fmap和bind的关系

问题描述 投票:0回答:3

在查看

Control.Monad
文档后,我对 这段话:

以上定律暗示:

fmap f xs  =  xs >>= return . f

他们是怎么暗示的?

haskell monads functor
3个回答
8
投票

Control.Applicative

作为这些定律的结果,f 的

Functor
实例将满足

fmap f x = pure f <*> x

Applicative
Monad
的关系说

pure = return
(<*>) = ap

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

7
投票

Functor
实例是唯一的,因为如果
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 xs = xs
;也就是说,
liftM id = id
。因此,
liftM = fmap
;或者,换句话说......

fmap f xs  =  xs >>= return . f

epheriment的答案,它通过

Applicative
定律,也是得出这个结论的有效方法。


0
投票

让我更完整地描述为什么这个等式成立:


那么,为什么是

bind (pure · f)  =  map f

这遵循三个单子法则和参数化(免费)。这意味着:

考虑功能

pure: ∀ a, F a
。因为这个函数必须对所有类型
a
起作用,所以它不能不更改或创建
a
类型的新元素,而只能复制或忘记
a
类型的值。因此,我们是否在应用
f: a→c
之前或之后应用任何函数
a
将所有
c
s更改为
pure
s并不重要。

左边我们在使用

f
之前应用
pure
,在右边我们应用
f
之后:

pure (f v) = map f (pure v)                       (free theorem for pure)

类似地,考虑函数

bind: ∀ a b, (a → F b) → (F a → F b)
。因为这个函数必须对所有类型
a
起作用,所以它不能不更改或创建
a
类型的新元素,而只能复制或忘记
a
类型的值。因此,我们是否在应用
f: a→c
之前或之后应用任何函数
a
将所有
c
s更改为
bind
s并不重要。

左边我们在使用

f
之前应用
bind
,在右边我们应用
f
之后:

bind (map f · g)  =  map f · bind g               (free theorem for bind)

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

bind (map f · pure)  =  map f · bind pure

对于这个方程,我们可以在左侧应用纯自由定理 (

map f · pure = pure · f
),在右侧应用左单位单子定律 (
bind pure = id
):

bind (pure · f)  =  map f

完成

© www.soinside.com 2019 - 2024. All rights reserved.