首页 > 解决方案 > 如何为 Applicative 实例制作适当的“纯”?

问题描述

我发现pure这个 Applicative 实例至少有 2 个实现,它们遵循所有定律(同一性、同态、交换、组合)。其中之一仍然是错误的吗?

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

标签: haskellapplicative

解决方案


首先pure等律不成立。事实上,该法律规定:

pure id <*> v = v

因此,这意味着:

ZipList' (Cons id Nil) <*> v = v

对于所有vs。但这不成立。说了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]


推荐阅读