fmap和bind之间的关系

Tri*_*Lee 5 monads haskell functor

查阅Control.Monad文档后,我对这段话感到困惑:

上述法律意味着:

fmap f xs = xs >>= return . f

他们怎么暗示这个?

eph*_*ent 9

Control.Applicative

作为这些法律的结果,Functorf 的实例将满足

fmap f x = pure f <*> x
Run Code Online (Sandbox Code Playgroud)

Applicative和之间的关系Monad

pure = return
Run Code Online (Sandbox Code Playgroud)
(<*>) = ap
Run Code Online (Sandbox Code Playgroud)

ap

return f `ap` x1 `ap` ... `ap` xn
Run Code Online (Sandbox Code Playgroud)

相当于

liftMn f x1 x2 ... xn
Run Code Online (Sandbox Code Playgroud)

因此

fmap f x = pure f <*> x
         = return f `ap` x
         = liftM f x
         = do { v <- x; return (f v) }
         = x >>= return . f
Run Code Online (Sandbox Code Playgroud)

  • 好吧,这只是将问题推到了“适用”级别。那就是:为什么“ fmap fx =纯f &lt;*&gt; x”是“适用”定律的结果?毕竟,他们甚至都没有提到`fmap`!然后要回答这个问题,您需要@duplode对参数的观察... (2认同)

dup*_*ode 7

Functor实例是唯一的,在某种意义上,如果F是a Functor并且你有一个函数foobar :: (a -> b) -> F a -> F b,那么foobar id = id(也就是说,它遵循第一个仿函数法则)foobar = fmap.现在,考虑这个功能:

liftM :: Monad f => (a -> b) -> f a -> f b
liftM f xs = xs >>= return . f
Run Code Online (Sandbox Code Playgroud)

那是什么liftM id xs

liftM id xs
xs >>= return . id
-- id does nothing, so...
xs >>= return
-- By the second monad law...
xs
Run Code Online (Sandbox Code Playgroud)

liftM id xs = xs; 就是,liftM id = id.因此,liftM = fmap; 或者,换句话说......

fmap f xs  =  xs >>= return . f
Run Code Online (Sandbox Code Playgroud)

通过Applicative法律路线的epheriment的答案也是达成这个结论的有效方式.