如何为适用实例创建适当的“纯”?

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

我已经发现,此应用实例至少有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
haskell applicative
2个回答
8
投票

对于第一个pureidentity法则不适用[[not。确实,该法律规定:

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]

0
投票
每个<*>最多可以支持一个有效的pure。假设pure1pure2都合法。然后,对于任何x

pure2 x = -- Identity for pure1 pure1 id <*> pure2 x = -- Interchange for pure2 pure2 ($x) <*> pure1 id = -- Functor/Applicative for pure2 fmap ($x) (pure1 id) = -- Functor/Applicative for pure1 pure1 ($x) <*> pure1 id = -- Homomorphism for pure1 pure1 x

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