5. Applicative Functors
20/02/23
Generalising fmap
fmap0 :: a -> f a
fmap1 :: (a -> b) -> f a -> f b
fmap2 :: (a -> b -> c) -> f a -> f b -> f c
fmap3 :: (a -> b -> c -> d) -> f a -> f b -> f c -> f d
pure :: a-> f a -- Turn a value into a data strucutre.
((*)) :: f (a -> b) -> f a -> f b --() is a prefix operator. Need to give brackets when defining it as a type. Generalised form of function applicaiton
pure g (*) x (*) y (*) z -- applicative style
(*) -- does it to the left
fmap0 :: a -> f a
fmap0 = pure
fmap1 :: (a -> b) -> f a -> f b
fmap1 g x = pure g (*) x
fmap2 :: (a -> b -> c) -> f a -> f b -> f c
fmap2 g x y = (pure g (*) x ) (*) y
Applicative Functors
class Functor f => Applicative f where
pure :: a -> f a
((*)) :: f(a->b) -> f a -> f b
Example: Maybe
instance Applicative Maybe where
-- pure :: a -> Maybe a
pure x = Just x
-- ((*)) :: maybe (a->b) -> Maybe a -> Maybe b
Nothing (*) mx = Nothing
(Just g) (*) mx = fmap g mx
Example: Lists
instance Applicative [] where
-- pure :: a -> [a]
pure x = [x]
-- ((*)) :: [a->b] -> [a] -> [b]
gs (*) xs = [g x | g <- gs, x <- xs]