Relationship between fmap and bind

2019-05-02 13:32发布

问题:

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?

回答1:

Control.Applicative says

As a consequence of these laws, the Functor instance for f will satisfy

fmap 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


回答2:

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.