Is `x >> pure y` equivalent to `liftM (const y) x`Unlike a Functor, a Monad can change shape?Why should Applicative be a superclass of Monad?Is there a monad that doesn't have a corresponding monad transformer (except IO)?Composition of compositions in HaskellHaskell: Flaw in the description of applicative functor laws in the hackage Control.Applicative article?: it says Applicative determines FunctorTo what extent are Applicative/Monad instances uniquely determined?Is this property of a functor stronger than a monad?Are applicative functors composed with the applicative style really independent?bind can be composed of fmap and join, so do we have to use monadic functions a -> m b?Do the monadic liftM and the functorial fmap have to be equivalent?
Was there a Viking Exchange as well as a Columbian one?
What was the "glowing package" Pym was expecting?
TikZ how to make supply and demand arrows for nodes?
Why didn't this hurt this character as badly?
How deep to place a deadman anchor for a slackline?
How to set the font color of quantity objects (Version 11.3 vs version 12)?
Can someone publish a story that happened to you?
What does "rf" mean in "rfkill"?
Confused by notation of atomic number Z and mass number A on periodic table of elements
Past Perfect Tense
What is a Recurrent Neural Network?
Lock in SQL Server and Oracle
What does YCWCYODFTRFDTY mean?
If Earth is tilted, why is Polaris always above the same spot?
Options leqno, reqno for documentclass or exist another option?
Were there two appearances of Stan Lee?
Packing rectangles: Does rotation ever help?
Pawn Sacrifice Justification
How can I record the screen and the rear camera on an iPhone simultaneously?
Electric guitar: why such heavy pots?
Do I have to worry about players making “bad” choices on level up?
Upright [...] in italics quotation
Pulling the rope with one hand is as heavy as with two hands?
Has any spacecraft ever had the ability to directly communicate with civilian air traffic control?
Is `x >> pure y` equivalent to `liftM (const y) x`
Unlike a Functor, a Monad can change shape?Why should Applicative be a superclass of Monad?Is there a monad that doesn't have a corresponding monad transformer (except IO)?Composition of compositions in HaskellHaskell: Flaw in the description of applicative functor laws in the hackage Control.Applicative article?: it says Applicative determines FunctorTo what extent are Applicative/Monad instances uniquely determined?Is this property of a functor stronger than a monad?Are applicative functors composed with the applicative style really independent?bind can be composed of fmap and join, so do we have to use monadic functions a -> m b?Do the monadic liftM and the functorial fmap have to be equivalent?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
The two expressions
y >> pure x
liftM (const x) y
have the same type signature in Haskell.
I was curious whether they were equivalent, but I could neither produce a proof of the fact nor a counter example against it.
If we rewrite the two expressions so that we can eliminate the x
and y
then the question becomes whether the two following functions are equivalent
flip (>>) . pure
liftM . const
Note that both these functions have type Monad m => a -> m b -> m a
.
I used the laws that Haskell gives for monad, applicatives, and functors to transform both statements into various equivalent forms, but I was not able to produce a sequence of equivalences between the two.
For instance I found that y >> pure x
can be rewritten as follows
y >>= const (pure x)
y *> pure x
(id <$ y) <*> pure x
fmap (const id) y <*> pure x
and liftM (const x) y
can be rewritten as follows
fmap (const x) y
pure (const x) <*> y
None of these spring out to me as necessarily equivalent, but I cannot think of any cases where they would not be equivalent.
haskell monads functor applicative
add a comment |
The two expressions
y >> pure x
liftM (const x) y
have the same type signature in Haskell.
I was curious whether they were equivalent, but I could neither produce a proof of the fact nor a counter example against it.
If we rewrite the two expressions so that we can eliminate the x
and y
then the question becomes whether the two following functions are equivalent
flip (>>) . pure
liftM . const
Note that both these functions have type Monad m => a -> m b -> m a
.
I used the laws that Haskell gives for monad, applicatives, and functors to transform both statements into various equivalent forms, but I was not able to produce a sequence of equivalences between the two.
For instance I found that y >> pure x
can be rewritten as follows
y >>= const (pure x)
y *> pure x
(id <$ y) <*> pure x
fmap (const id) y <*> pure x
and liftM (const x) y
can be rewritten as follows
fmap (const x) y
pure (const x) <*> y
None of these spring out to me as necessarily equivalent, but I cannot think of any cases where they would not be equivalent.
haskell monads functor applicative
add a comment |
The two expressions
y >> pure x
liftM (const x) y
have the same type signature in Haskell.
I was curious whether they were equivalent, but I could neither produce a proof of the fact nor a counter example against it.
If we rewrite the two expressions so that we can eliminate the x
and y
then the question becomes whether the two following functions are equivalent
flip (>>) . pure
liftM . const
Note that both these functions have type Monad m => a -> m b -> m a
.
I used the laws that Haskell gives for monad, applicatives, and functors to transform both statements into various equivalent forms, but I was not able to produce a sequence of equivalences between the two.
For instance I found that y >> pure x
can be rewritten as follows
y >>= const (pure x)
y *> pure x
(id <$ y) <*> pure x
fmap (const id) y <*> pure x
and liftM (const x) y
can be rewritten as follows
fmap (const x) y
pure (const x) <*> y
None of these spring out to me as necessarily equivalent, but I cannot think of any cases where they would not be equivalent.
haskell monads functor applicative
The two expressions
y >> pure x
liftM (const x) y
have the same type signature in Haskell.
I was curious whether they were equivalent, but I could neither produce a proof of the fact nor a counter example against it.
If we rewrite the two expressions so that we can eliminate the x
and y
then the question becomes whether the two following functions are equivalent
flip (>>) . pure
liftM . const
Note that both these functions have type Monad m => a -> m b -> m a
.
I used the laws that Haskell gives for monad, applicatives, and functors to transform both statements into various equivalent forms, but I was not able to produce a sequence of equivalences between the two.
For instance I found that y >> pure x
can be rewritten as follows
y >>= const (pure x)
y *> pure x
(id <$ y) <*> pure x
fmap (const id) y <*> pure x
and liftM (const x) y
can be rewritten as follows
fmap (const x) y
pure (const x) <*> y
None of these spring out to me as necessarily equivalent, but I cannot think of any cases where they would not be equivalent.
haskell monads functor applicative
haskell monads functor applicative
edited Mar 27 at 20:30
duplode
24.1k45092
24.1k45092
asked Mar 27 at 18:31
10000000001000000000
489214
489214
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
The other answer gets there eventually, but it takes a long-winded route. All that is actually needed are the definitions of liftM
, const
, and a single monad law: m1 >> m2
and m1 >>= _ -> m2
must be semantically identical. (Indeed, this is the default implementation of (>>)
, and it is rare to override it.) Then:
liftM (const x) y
= definition of liftM*
y >>= z -> pure (const x z)
= definition of const
y >>= z -> pure x
= monad law
y >> pure x
* Okay, okay, so the actual definition of liftM
uses return
instead of pure
. Whatever.
Interesting. For some reason I thought that the standard definition wasliftM = fmap
, with the more restrictive type. With the real definition above, the wanted equation is much simpler to obtain :)
– chi
Mar 27 at 20:00
1
@chi Even without it things aren't too bad:fmap f m = m >>= return . f
is also a monad law (one of the oft-forgotten ones).
– Daniel Wagner
Mar 27 at 20:47
5
That law itself follows from parametricity and the monad lawm >>= pure = m
.
– dfeuer
Mar 27 at 21:27
add a comment |
Yes they are the same
Let's start with flip (>>) . pure
, which is the pointfree version of x >> pure y
you provide:
flip (>>) . pure
It is the case that flip (>>)
is just (=<<) . const
so we can rewrite this as:
((=<<) . const) . pure
Since function composition ((.)
) is associative we can write this as:
(=<<) . (const . pure)
Now we would like to rewrite const . pure
. We can notice that const
is just pure
on (a ->)
, that means since pure . pure
is fmap pure . pure
, const . pure
is (.) pure . const
, ((.)
is fmap
for the functor (a ->)
).
(=<<) . ((.) pure . const)
Now we associate again:
((=<<) . (.) pure) . const
((=<<) . (.) pure)
is the definition for liftM
1 so we can substitute:
liftM . const
And that is the goal. The two are the same.
1: The definition of liftM
is liftM f m1 = do x1 <- m1; return (f x1)
, we can desugar the do
into liftM f m1 = m1 >>= return . f
. We can flip the (>>=)
for liftM f m1 = return . f =<< m1
and elide the m1
to get liftM f = (return . f =<<)
a little pointfree magic and we get liftM = (=<<) . (.) return
1
Can you please add how you get fromconst . pure
tofmap pure . const
? Btw it might have been easier to start with(.)
right away instead of writingfmap
(and later explaining (figuring out?) whatFunctor
instance it belongs to).
– Bergi
Mar 27 at 22:30
1
@Bergi Actually you are right, doing it earlier makes things simpler.
– Sriotchilism O'Zaic
Mar 27 at 22:54
add a comment |
One more possible route, exploiting the applicative laws:
For instance I found that
y >> pure x
can be rewritten as follows [...]fmap (const id) y <*> pure x
That amounts to...
fmap (const id) y <*> pure x
pure ($ x) <*> fmap (const id) y -- interchange law of applicatives
fmap ($ x) (fmap (const id) y) -- fmap in terms of <*>
fmap (($ x) . const id) y -- composition law of functors
fmap (const x) y
... which, as you noted, is the same as liftM (const x) y
.
That this route requires only applicative laws and not monad ones reflects how (*>)
(another name for (>>)
) is an Applicative
method.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55384267%2fis-x-pure-y-equivalent-to-liftm-const-y-x%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
The other answer gets there eventually, but it takes a long-winded route. All that is actually needed are the definitions of liftM
, const
, and a single monad law: m1 >> m2
and m1 >>= _ -> m2
must be semantically identical. (Indeed, this is the default implementation of (>>)
, and it is rare to override it.) Then:
liftM (const x) y
= definition of liftM*
y >>= z -> pure (const x z)
= definition of const
y >>= z -> pure x
= monad law
y >> pure x
* Okay, okay, so the actual definition of liftM
uses return
instead of pure
. Whatever.
Interesting. For some reason I thought that the standard definition wasliftM = fmap
, with the more restrictive type. With the real definition above, the wanted equation is much simpler to obtain :)
– chi
Mar 27 at 20:00
1
@chi Even without it things aren't too bad:fmap f m = m >>= return . f
is also a monad law (one of the oft-forgotten ones).
– Daniel Wagner
Mar 27 at 20:47
5
That law itself follows from parametricity and the monad lawm >>= pure = m
.
– dfeuer
Mar 27 at 21:27
add a comment |
The other answer gets there eventually, but it takes a long-winded route. All that is actually needed are the definitions of liftM
, const
, and a single monad law: m1 >> m2
and m1 >>= _ -> m2
must be semantically identical. (Indeed, this is the default implementation of (>>)
, and it is rare to override it.) Then:
liftM (const x) y
= definition of liftM*
y >>= z -> pure (const x z)
= definition of const
y >>= z -> pure x
= monad law
y >> pure x
* Okay, okay, so the actual definition of liftM
uses return
instead of pure
. Whatever.
Interesting. For some reason I thought that the standard definition wasliftM = fmap
, with the more restrictive type. With the real definition above, the wanted equation is much simpler to obtain :)
– chi
Mar 27 at 20:00
1
@chi Even without it things aren't too bad:fmap f m = m >>= return . f
is also a monad law (one of the oft-forgotten ones).
– Daniel Wagner
Mar 27 at 20:47
5
That law itself follows from parametricity and the monad lawm >>= pure = m
.
– dfeuer
Mar 27 at 21:27
add a comment |
The other answer gets there eventually, but it takes a long-winded route. All that is actually needed are the definitions of liftM
, const
, and a single monad law: m1 >> m2
and m1 >>= _ -> m2
must be semantically identical. (Indeed, this is the default implementation of (>>)
, and it is rare to override it.) Then:
liftM (const x) y
= definition of liftM*
y >>= z -> pure (const x z)
= definition of const
y >>= z -> pure x
= monad law
y >> pure x
* Okay, okay, so the actual definition of liftM
uses return
instead of pure
. Whatever.
The other answer gets there eventually, but it takes a long-winded route. All that is actually needed are the definitions of liftM
, const
, and a single monad law: m1 >> m2
and m1 >>= _ -> m2
must be semantically identical. (Indeed, this is the default implementation of (>>)
, and it is rare to override it.) Then:
liftM (const x) y
= definition of liftM*
y >>= z -> pure (const x z)
= definition of const
y >>= z -> pure x
= monad law
y >> pure x
* Okay, okay, so the actual definition of liftM
uses return
instead of pure
. Whatever.
edited Mar 27 at 18:59
answered Mar 27 at 18:54
Daniel WagnerDaniel Wagner
105k7163289
105k7163289
Interesting. For some reason I thought that the standard definition wasliftM = fmap
, with the more restrictive type. With the real definition above, the wanted equation is much simpler to obtain :)
– chi
Mar 27 at 20:00
1
@chi Even without it things aren't too bad:fmap f m = m >>= return . f
is also a monad law (one of the oft-forgotten ones).
– Daniel Wagner
Mar 27 at 20:47
5
That law itself follows from parametricity and the monad lawm >>= pure = m
.
– dfeuer
Mar 27 at 21:27
add a comment |
Interesting. For some reason I thought that the standard definition wasliftM = fmap
, with the more restrictive type. With the real definition above, the wanted equation is much simpler to obtain :)
– chi
Mar 27 at 20:00
1
@chi Even without it things aren't too bad:fmap f m = m >>= return . f
is also a monad law (one of the oft-forgotten ones).
– Daniel Wagner
Mar 27 at 20:47
5
That law itself follows from parametricity and the monad lawm >>= pure = m
.
– dfeuer
Mar 27 at 21:27
Interesting. For some reason I thought that the standard definition was
liftM = fmap
, with the more restrictive type. With the real definition above, the wanted equation is much simpler to obtain :)– chi
Mar 27 at 20:00
Interesting. For some reason I thought that the standard definition was
liftM = fmap
, with the more restrictive type. With the real definition above, the wanted equation is much simpler to obtain :)– chi
Mar 27 at 20:00
1
1
@chi Even without it things aren't too bad:
fmap f m = m >>= return . f
is also a monad law (one of the oft-forgotten ones).– Daniel Wagner
Mar 27 at 20:47
@chi Even without it things aren't too bad:
fmap f m = m >>= return . f
is also a monad law (one of the oft-forgotten ones).– Daniel Wagner
Mar 27 at 20:47
5
5
That law itself follows from parametricity and the monad law
m >>= pure = m
.– dfeuer
Mar 27 at 21:27
That law itself follows from parametricity and the monad law
m >>= pure = m
.– dfeuer
Mar 27 at 21:27
add a comment |
Yes they are the same
Let's start with flip (>>) . pure
, which is the pointfree version of x >> pure y
you provide:
flip (>>) . pure
It is the case that flip (>>)
is just (=<<) . const
so we can rewrite this as:
((=<<) . const) . pure
Since function composition ((.)
) is associative we can write this as:
(=<<) . (const . pure)
Now we would like to rewrite const . pure
. We can notice that const
is just pure
on (a ->)
, that means since pure . pure
is fmap pure . pure
, const . pure
is (.) pure . const
, ((.)
is fmap
for the functor (a ->)
).
(=<<) . ((.) pure . const)
Now we associate again:
((=<<) . (.) pure) . const
((=<<) . (.) pure)
is the definition for liftM
1 so we can substitute:
liftM . const
And that is the goal. The two are the same.
1: The definition of liftM
is liftM f m1 = do x1 <- m1; return (f x1)
, we can desugar the do
into liftM f m1 = m1 >>= return . f
. We can flip the (>>=)
for liftM f m1 = return . f =<< m1
and elide the m1
to get liftM f = (return . f =<<)
a little pointfree magic and we get liftM = (=<<) . (.) return
1
Can you please add how you get fromconst . pure
tofmap pure . const
? Btw it might have been easier to start with(.)
right away instead of writingfmap
(and later explaining (figuring out?) whatFunctor
instance it belongs to).
– Bergi
Mar 27 at 22:30
1
@Bergi Actually you are right, doing it earlier makes things simpler.
– Sriotchilism O'Zaic
Mar 27 at 22:54
add a comment |
Yes they are the same
Let's start with flip (>>) . pure
, which is the pointfree version of x >> pure y
you provide:
flip (>>) . pure
It is the case that flip (>>)
is just (=<<) . const
so we can rewrite this as:
((=<<) . const) . pure
Since function composition ((.)
) is associative we can write this as:
(=<<) . (const . pure)
Now we would like to rewrite const . pure
. We can notice that const
is just pure
on (a ->)
, that means since pure . pure
is fmap pure . pure
, const . pure
is (.) pure . const
, ((.)
is fmap
for the functor (a ->)
).
(=<<) . ((.) pure . const)
Now we associate again:
((=<<) . (.) pure) . const
((=<<) . (.) pure)
is the definition for liftM
1 so we can substitute:
liftM . const
And that is the goal. The two are the same.
1: The definition of liftM
is liftM f m1 = do x1 <- m1; return (f x1)
, we can desugar the do
into liftM f m1 = m1 >>= return . f
. We can flip the (>>=)
for liftM f m1 = return . f =<< m1
and elide the m1
to get liftM f = (return . f =<<)
a little pointfree magic and we get liftM = (=<<) . (.) return
1
Can you please add how you get fromconst . pure
tofmap pure . const
? Btw it might have been easier to start with(.)
right away instead of writingfmap
(and later explaining (figuring out?) whatFunctor
instance it belongs to).
– Bergi
Mar 27 at 22:30
1
@Bergi Actually you are right, doing it earlier makes things simpler.
– Sriotchilism O'Zaic
Mar 27 at 22:54
add a comment |
Yes they are the same
Let's start with flip (>>) . pure
, which is the pointfree version of x >> pure y
you provide:
flip (>>) . pure
It is the case that flip (>>)
is just (=<<) . const
so we can rewrite this as:
((=<<) . const) . pure
Since function composition ((.)
) is associative we can write this as:
(=<<) . (const . pure)
Now we would like to rewrite const . pure
. We can notice that const
is just pure
on (a ->)
, that means since pure . pure
is fmap pure . pure
, const . pure
is (.) pure . const
, ((.)
is fmap
for the functor (a ->)
).
(=<<) . ((.) pure . const)
Now we associate again:
((=<<) . (.) pure) . const
((=<<) . (.) pure)
is the definition for liftM
1 so we can substitute:
liftM . const
And that is the goal. The two are the same.
1: The definition of liftM
is liftM f m1 = do x1 <- m1; return (f x1)
, we can desugar the do
into liftM f m1 = m1 >>= return . f
. We can flip the (>>=)
for liftM f m1 = return . f =<< m1
and elide the m1
to get liftM f = (return . f =<<)
a little pointfree magic and we get liftM = (=<<) . (.) return
Yes they are the same
Let's start with flip (>>) . pure
, which is the pointfree version of x >> pure y
you provide:
flip (>>) . pure
It is the case that flip (>>)
is just (=<<) . const
so we can rewrite this as:
((=<<) . const) . pure
Since function composition ((.)
) is associative we can write this as:
(=<<) . (const . pure)
Now we would like to rewrite const . pure
. We can notice that const
is just pure
on (a ->)
, that means since pure . pure
is fmap pure . pure
, const . pure
is (.) pure . const
, ((.)
is fmap
for the functor (a ->)
).
(=<<) . ((.) pure . const)
Now we associate again:
((=<<) . (.) pure) . const
((=<<) . (.) pure)
is the definition for liftM
1 so we can substitute:
liftM . const
And that is the goal. The two are the same.
1: The definition of liftM
is liftM f m1 = do x1 <- m1; return (f x1)
, we can desugar the do
into liftM f m1 = m1 >>= return . f
. We can flip the (>>=)
for liftM f m1 = return . f =<< m1
and elide the m1
to get liftM f = (return . f =<<)
a little pointfree magic and we get liftM = (=<<) . (.) return
edited Mar 27 at 22:54
answered Mar 27 at 18:31
Sriotchilism O'ZaicSriotchilism O'Zaic
868620
868620
1
Can you please add how you get fromconst . pure
tofmap pure . const
? Btw it might have been easier to start with(.)
right away instead of writingfmap
(and later explaining (figuring out?) whatFunctor
instance it belongs to).
– Bergi
Mar 27 at 22:30
1
@Bergi Actually you are right, doing it earlier makes things simpler.
– Sriotchilism O'Zaic
Mar 27 at 22:54
add a comment |
1
Can you please add how you get fromconst . pure
tofmap pure . const
? Btw it might have been easier to start with(.)
right away instead of writingfmap
(and later explaining (figuring out?) whatFunctor
instance it belongs to).
– Bergi
Mar 27 at 22:30
1
@Bergi Actually you are right, doing it earlier makes things simpler.
– Sriotchilism O'Zaic
Mar 27 at 22:54
1
1
Can you please add how you get from
const . pure
to fmap pure . const
? Btw it might have been easier to start with (.)
right away instead of writing fmap
(and later explaining (figuring out?) what Functor
instance it belongs to).– Bergi
Mar 27 at 22:30
Can you please add how you get from
const . pure
to fmap pure . const
? Btw it might have been easier to start with (.)
right away instead of writing fmap
(and later explaining (figuring out?) what Functor
instance it belongs to).– Bergi
Mar 27 at 22:30
1
1
@Bergi Actually you are right, doing it earlier makes things simpler.
– Sriotchilism O'Zaic
Mar 27 at 22:54
@Bergi Actually you are right, doing it earlier makes things simpler.
– Sriotchilism O'Zaic
Mar 27 at 22:54
add a comment |
One more possible route, exploiting the applicative laws:
For instance I found that
y >> pure x
can be rewritten as follows [...]fmap (const id) y <*> pure x
That amounts to...
fmap (const id) y <*> pure x
pure ($ x) <*> fmap (const id) y -- interchange law of applicatives
fmap ($ x) (fmap (const id) y) -- fmap in terms of <*>
fmap (($ x) . const id) y -- composition law of functors
fmap (const x) y
... which, as you noted, is the same as liftM (const x) y
.
That this route requires only applicative laws and not monad ones reflects how (*>)
(another name for (>>)
) is an Applicative
method.
add a comment |
One more possible route, exploiting the applicative laws:
For instance I found that
y >> pure x
can be rewritten as follows [...]fmap (const id) y <*> pure x
That amounts to...
fmap (const id) y <*> pure x
pure ($ x) <*> fmap (const id) y -- interchange law of applicatives
fmap ($ x) (fmap (const id) y) -- fmap in terms of <*>
fmap (($ x) . const id) y -- composition law of functors
fmap (const x) y
... which, as you noted, is the same as liftM (const x) y
.
That this route requires only applicative laws and not monad ones reflects how (*>)
(another name for (>>)
) is an Applicative
method.
add a comment |
One more possible route, exploiting the applicative laws:
For instance I found that
y >> pure x
can be rewritten as follows [...]fmap (const id) y <*> pure x
That amounts to...
fmap (const id) y <*> pure x
pure ($ x) <*> fmap (const id) y -- interchange law of applicatives
fmap ($ x) (fmap (const id) y) -- fmap in terms of <*>
fmap (($ x) . const id) y -- composition law of functors
fmap (const x) y
... which, as you noted, is the same as liftM (const x) y
.
That this route requires only applicative laws and not monad ones reflects how (*>)
(another name for (>>)
) is an Applicative
method.
One more possible route, exploiting the applicative laws:
For instance I found that
y >> pure x
can be rewritten as follows [...]fmap (const id) y <*> pure x
That amounts to...
fmap (const id) y <*> pure x
pure ($ x) <*> fmap (const id) y -- interchange law of applicatives
fmap ($ x) (fmap (const id) y) -- fmap in terms of <*>
fmap (($ x) . const id) y -- composition law of functors
fmap (const x) y
... which, as you noted, is the same as liftM (const x) y
.
That this route requires only applicative laws and not monad ones reflects how (*>)
(another name for (>>)
) is an Applicative
method.
edited Mar 27 at 22:37
answered Mar 27 at 20:27
duplodeduplode
24.1k45092
24.1k45092
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55384267%2fis-x-pure-y-equivalent-to-liftm-const-y-x%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown