I've found out that there are at least 2 realizations of pure
for this Applicative instance, that follow all the laws (Identity, Homomorphism, Interchange, Composition). Is one of them still wrong?
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)
or
pure a = ZipList' as
where as = Cons a as
For the first pure
, the identity law does not hold. Indeed, this law says that:
pure id <*> v = v
This thus means that:
ZipList' (Cons id Nil) <*> v = v
for all v
s. But that does not hold. Say that v = ZipList' (Cons 1 (Cons 2 Nil))
, so basically a list [1,2]
. Then one expects that:
ZipList' (Cons id Nil) <*> ZipList' (Cons 1 (Cons 2 Nil)) = ZipList' (Cons 1 (Cons 2 Nil))
If we however evaluate your implementation for Applicative
, we see that:
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)
But this is not what we expect for the identity law, since here we obtain a ZipList'
that basically is [1]
, whereas it should be [1,2]
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With