haskell fmap和bind之间的关系

q0qdq0h2  于 2023-03-03  发布在  其他
关注(0)|答案(3)|浏览(157)

在查阅了Control.Monad文档后,我对这段文字感到困惑:
上述定律意味着:
fmap f xs = xs >>= return . f
他们是怎么暗示的?

hyrbngr7

hyrbngr71#

Control.Applicative表示
根据这些定律,f的Functor示例将满足

fmap f x = pure f <*> x

ApplicativeMonad之间的关系是
x一个一个一个一个x一个一个二个x
ap表示

return f `ap` x1 `ap` ... `ap` xn

相当于

liftMn f x1 x2 ... xn

因此

fmap f x = pure f <*> x
         = return f `ap` x
         = liftM f x
         = do { v <- x; return (f v) }
         = x >>= return . f
x6h2sr28

x6h2sr282#

如果F是一个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

那么liftM id xs是什么呢?

liftM id xs
xs >>= return . id
-- id does nothing, so...
xs >>= return
-- By the second monad law...
xs

liftM id = id。因此,或者换句话说。

fmap f xs  =  xs >>= return . f

通过Applicative定律的epheriment's answer也是得出这一结论的有效方式。

i5desfxk

i5desfxk3#

让我对为什么这个等式成立作一个更加独立的描述:
那么,为什么是x >>= (return . f) = fmap f x呢?
这是从三个单子定律和参数性(免费)得出的,这意味着:
考虑函数return :: forall a. F a。因为这个函数必须在所有类型a上工作,所以它不能改变或创建a类型的新元素,而只能复制或忘记a类型的值。因此,在应用return之前或之后,我们是否应用任何函数f :: a -> c来将所有a改变为c并不重要。
在左边我们将f应用于return的参数,在右边我们将f应用于结果:

return (f v) = fmap f (return v)                       (free theorem for return)

类似地,考虑函数>>= :: forall a b. F a -> (a -> F b) -> F b。因为该函数必须在所有类型a上工作,所以它不能改变或创建类型a的新元素,而只能复制或忘记类型a的值。因此,在应用>>=之前还是之后应用任何函数f :: a -> c以将所有a改变为c是无关紧要的。
在左边我们将f应用于>>=的参数,在右边我们将f应用于结果:

x >>= (fmap f . g)  =  fmap f (x >>= g)               (free theorem for bind)

如果我们现在简单地示例化g = return,我们得到:

x >>= (fmap f . return)  =  fmap f (x >>= return)

对于这个方程,我们可以在左边应用自由返回定理(fmap f . return = return . f),在右边应用左单位单子法则(x >>= return = x):

x >>= (return . f)  =  fmap f x

好的。

相关问题