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
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
定律,也是得出这个结论的有效方法。
让我更完整地描述为什么这个等式成立:
那么,为什么是
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
完成