After looking up the Control.Monad
documentation, I'm confused about
this passage:
The above laws imply:
fmap f xs = xs >>= return . f
How do they imply that?
After looking up the Control.Monad
documentation, I'm confused about
this passage:
The above laws imply:
fmap f xs = xs >>= return . f
How do they imply that?
Control.Applicative
says
As a consequence of these laws, the
Functor
instance for f will satisfyfmap f x = pure f <*> x
The relationship between Applicative
and Monad
says
pure = return
(<*>) = ap
ap
says
return f `ap` x1 `ap` ... `ap` xn
is equivalent to
liftMn f x1 x2 ... xn
Therefore
fmap f x = pure f <*> x
= return f `ap` x
= liftM f x
= do { v <- x; return (f v) }
= x >>= return . f
Functor
instances are unique, in the sense that if F
is a Functor
and you have a function foobar :: (a -> b) -> F a -> F b
such that foobar id = id
(that is, it follows the first functor law) then foobar = fmap
. Now, consider this function:
liftM :: Monad f => (a -> b) -> f a -> f b
liftM f xs = xs >>= return . f
What is liftM id xs
, then?
liftM id xs
xs >>= return . id
-- id does nothing, so...
xs >>= return
-- By the second monad law...
xs
liftM id xs = xs
; that is, liftM id = id
. Therefore, liftM = fmap
; or, in other words...
fmap f xs = xs >>= return . f
epheriment's answer, which routes through the Applicative
laws, is also a valid way of reaching this conclusion.
Let me contribute a more self-contained description of why this equality holds:
So, why is x >>= (return . f) = fmap f x
?
This follows from the three monad laws and parametricity (for free). This means:
Consider the function return :: forall a. F a
. Because this function must work over all types a
it cannot not change or create new elements of type a
but only duplicate or forget values of type a
. Therefore, it does not matter whether we apply any function f :: a -> c
to change all a
s into c
s before or after applying return
.
On the left we apply f
on the argument of return
, on the right we apply f
on the result:
return (f v) = fmap f (return v) (free theorem for return)
Similarly, consider the function >>= :: forall a b. F a -> (a -> F b) -> F b
. Because this function must work over all types a
it cannot not change or create new elements of type a
but only duplicate or forget values of type a
. Therefore, it does not matter whether we apply any function f :: a -> c
to change all a
s into c
s before or after applying >>=
.
On the left we apply f
on the argument of >>=
, on the right we apply f
on the result:
x >>= (fmap f . g) = fmap f (x >>= g) (free theorem for bind)
If we now simply instantiate g=return, we get:
x >>= (fmap f . return) = fmap f (x >>= return)
To this equation, we can apply on the left hand side the free theorem of return (fmap f . return = return . f
), and on the right hand side the left-unit monad law (x >>= return = x
):
x >>= (return . f) = fmap f x
Done.
pure: ∀ a, F a
as equivalent to pure :: forall a. a -> F a
(and in fact aren't you missing an a →
?), and some will probably be confused wondering how the list-specific map
and :
got involved. –
Brindle © 2022 - 2024 — McMap. All rights reserved.
Applicative
level. That is: why isfmap f x = pure f <*> x
a consequence of theApplicative
laws? After all, they don't even mentionfmap
! And then to answer that, you need @duplode's observation about parametricity... – Labors