Lecture 10.0 — 2017-12-20
Hands on Applicative
This lecture is written in literate Haskell; you can download the raw source.
We wrote up a straightforward instance for Maybe
and a more interesting instance for Either e
:
instance Applicative (Either e) where
pure x = Right x -- because Left x would be ill typed!
(Right f) <*> (Right v) = Right $ f v
err@(Left e) <*> _ = err
_ <*> err@(Left e) = err
Then we went over the Applicative
definitions for lists. There were two possibilities: cartesian product…
instance Applicative [] where
pure x = [x]
[] <*> _ = []
_ <*> [] = []
(f:fs) <*> xs = map f xs ++ fs <*> xs
…and zipping:
newtype ZipList a = ZipList { getZipList :: [a] }
deriving (Eq, Show, Functor)
instance Applicative ZipList where
pure = ZipList . repeat
ZipList fs <*> ZipList xs = ZipList (zipWith ($) fs xs)
Obey the laws
Like Functor
, the Applicative
type class is governed by laws.
Identity: pure id <*> v = v
Composition: pure (.) <*> u <*> v <*> w = u <*> (v <*> w)
Homomorphism: pure f <*> pure x = pure (f x)
Interchange: u <*> pure y = pure ($ y) <*> u
Note that identity
is a generalization of id <$> v = v
from Functor, since
f <$> x = pure f <*> x`.