Reputation:
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?
Upvotes: 5
Views: 1423
Reputation: 190
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.
Upvotes: 1
Reputation: 34398
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.
Upvotes: 8
Reputation: 204926
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
Upvotes: 8