我发现这个 Applicative 实例至少有 2 个 pure
实现,它们遵循所有的规律(身份、同态、交换、组合)。其中之一仍然是错误的吗?
data List a =
Nil
| Cons a (List a)
deriving (Eq, Show)
newtype ZipList' a =
ZipList' (List a)
deriving (Eq, Show)
instance Applicative ZipList' where
ZipList' fss <*> ZipList' xss = ZipList' $ applicate fss xss
where applicate (Cons f fs) (Cons x xs) = Cons (f x) (applicate fs xs)
applicate Nil _ = Nil
applicate _ Nil = Nil
pure x = ZipList' (Cons x Nil)
或者
pure a = ZipList' as
where as = Cons a as
最佳答案
对于第一个 pure
,恒等律不成立。事实上,这条法律是这样说的:
pure id <*> v = v
因此,这意味着:
ZipList' (Cons id Nil) <*> v = v
对于所有
v
。但这并不成立。说 v = ZipList' (Cons 1 (Cons 2 Nil))
,所以基本上是一个列表 [1,2]
。那么人们期望:ZipList' (Cons id Nil) <*> ZipList' (Cons 1 (Cons 2 Nil)) = ZipList' (Cons 1 (Cons 2 Nil))
但是,如果我们评估您的
Applicative
实现,我们会看到:ZipList' (Cons id Nil) <*> ZipList' (Cons 1 (Cons 2 Nil))
= ZipList' (applicate (Cons id Nil) (Cons 1 (Cons 2 Nil)))
= ZipList' (Cons (id 1) (applicate Nil (Cons 2 Nil)))
= ZipList' (Cons 1 Nil)
但这不是我们对恒等律所期望的,因为在这里我们获得了一个基本上是
ZipList'
的 [1]
,而它应该是 [1,2]
。关于haskell - 如何为 Applicative 实例制作合适的 "pure"?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59956838/