Skip to main content

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]