【发布时间】:2020-09-14 03:09:25
【问题描述】:
给定一个操作(??) 这样
(a ?? b) ?? c = a ?? (b ?? c)
(也就是说(??)是关联的)
一定是这样的
liftA2 (??) (liftA2 (??) a b) c = liftA2 (??) a (liftA2 (??) b c)
(也就是说liftA2 (??)是关联的)
如果我们愿意,我们可以将其重写为:
fmap (??) (fmap (??) a <*> b) <*> c = fmap (??) a <*> (fmap (??) b <*> c)
我花了一点时间盯着适用的法律,但我无法拿出证据证明情况确实如此。所以我开始反驳它。我尝试过的所有开箱即用的应用程序(Maybe、[]、Either 等)都遵循法律,所以我想我会创建自己的。
我最好的想法是制作一个附有额外信息的空应用程序。
data Vacuous a = Vac Alg
Alg 将是一些代数,我稍后会根据自己的方便定义,以使属性失败但应用定律成功。
现在我们这样定义我们的实例:
instance Functor Vacuous where
fmap f = id
instance Applicative Vacuous where
pure x = Vac i
liftA2 f (Vac a) (Vac b) = Vac (comb a b)
(Vac a) <*> (Vac b) = Vac (comb a b)
其中i 是待确定的Alg 的某个元素,comb 是待确定的Alg 上的二进制组合器。我们真的没有其他方法可以定义它。
如果我们想要满足 身份 法则,这将强制 i 成为 comb 的身份。然后我们免费获得Homomorphism和Interchange。但现在 Composition 强制 comb 与 Alg 关联
((pure (.) <*> Vac u) <*> Vac v) <*> Vac w = Vac u <*> (Vac v <*> Vac w)
((Vac i <*> Vac u) <*> Vac v) <*> Vac w = Vac u <*> (Vac v <*> Vac w)
(Vac u <*> Vac v) <*> Vac w = Vac u <*> (Vac v <*> Vac w)
(Vac (comb u v)) <*> Vac w = Vac u <*> (Vac (comb v w))
Vac (comb (comb u v) w) = Vac (comb u (comb v w))
comb (comb u v) w = comb u (comb v w)
强迫我们满足属性。
有反例吗?如果不是,我们如何证明这个性质?
【问题讨论】:
-
请注意,
base的instance (Applicative f, Semigroup a) => Semigroup (Ap f a)依赖于该属性是否为真。
标签: haskell applicative semigroup