3 ms·
An example of this is the two possible applicative instance of list. One is based on the monad instance and does a cross product if presented with two lists. Th
by pinjo 8y ago
An example of this is the two possible applicative instance of list. One is based on the monad instance and does a cross product if presented with two lists. The other zips its arguments. It is the more interesting one imho:
import Control.Applicative
newtype ZList a = ZList { runZList :: [a] }
instance Functor ZList where
fmap f = ZList . fmap f . runZList
instance Applicative ZList where
pure a = ZList [a]
(<*>) f x = ZList $ zipper (runZList f) (runZList x)
where zipper (f:fs) (x:xs) = f x : zipper fs xs
zipper [] _ = []
zipper _ [] = []
Difference of behaviour:
*Main> ZipList [(*3),(*5),(*6)] <*> ZipList [1,2,3,4]
ZipList {getZipList = [3,10,18]}
*Main> [(*3),(*5),(*6)] <*> [1,2,3,4]
[3,6,9,12,5,10,15,20,6,12,18,24]
*Main>
- nybble41 8y agoYes, though that definition results in: pure id <*> ZipList [x, y, z] == ZipList [x] and thus breaks one of the Applicative laws: pure id <*> v == v The standard ZipList definition is `pure a = ZipList (repeat a)` (an infinite list). The issue with defining a Monad instance for ZList is that mapping the function on the right of (>>=) over the ZList on the left gets you a ZList of `ZList b`, with no meaningful way to zip these ZLists together.