|
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>
|
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.