# Applicative Functors

``````class Functor_ t => Applicative_ (t :: * -> *) where
pure :: a -> t a
apply :: t (a -> b) -> t a -> t b``````

Several laws (in addition to those for `Functor`) which we won't stare at too closely for now.

1. `pure id `apply` v = v`
2. `pure (.) `apply` u `apply` v `apply` w = u `apply` (v `apply` w)`
3. `pure f `apply` pure x = pure (f x)`
4. `u `apply` pure y = pure (\$ y) `apply` u`

## Maybe

Recall `pureMaybe` and `applyMaybe`:

``````instance Applicative_ Maybe where
-- pure :: a -> Maybe a
pure = Just

-- apply :: Maybe (a -> b) -> Maybe a -> Maybe b
apply (Just f) ma = Just \$ fmap f ma
apply _           = Nothing``````

## Two Interpretations for Lists

Can think of lists as two different "computational contexts".

One way is to consider a list as a set values denoting a non-determinstic choice. Under this interpretation, want to apply all functions to all arguments.

``````instance Applicative_ [] where
-- pure :: a -> [a]
pure a = [a]

-- apply :: [(a -> b)] -> [a] -> [b]
-- apply fs xs = concatMap (\f -> map (\x -> f x) xs) fs
-- apply fs xs = concatMap (\f -> concatMap (\x -> [f x]) xs) fs
apply fs xs = [ f x | f <- fs, x <- xs ]``````

A second way is to consider a list as an ordered sequence of values. Under this interpretation, want to pairwise apply functions to arguments. Because we can only define one instance per type, we need to define a wrapper for (at least) one or the other; the Haskell libraries choose the instance above for "bare" lists and the following wrapper types for the second interpretation, called zip lists.

``````newtype ZipList a = ZipList { getZipList :: [a] }

instance Functor_ ZipList where
fmap f (ZipList xs) = ZipList (fmap f xs)

instance Applicative_ ZipList where

-- apply :: ZipList (a -> b) -> ZipList a -> ZipList b
ZipList fs `apply` ZipList xs = ZipList \$ zipWith (\$) fs xs

-- pure :: a -> ZipList a
pure f = ZipList \$ repeat f``````

## Functions

``````instance Applicative_ ((->) t) where
-- pure :: a -> ((->) t) a
-- pure :: a -> (t -> a)
-- pure a = \t -> a
pure   = const

-- apply :: ((->) t) (a -> b) -> ((->) t) a -> ((->) t) b
-- apply :: (t -> a -> b) -> (t -> a) -> (t -> b)
apply f g = \t -> f t (g t)``````

An `fmap` example with functions:

``````>  pure (^2) `apply` (3*) \$ 3   -- same as:  (^2) `fmap` (3*) \$ 3
-- apply (const (^2)) (3*) \$ 3
-- (\t1 -> const (^2) t1 ((3*) t1)) \$ 3
-- const (^2) 3 ((3*) 3)
-- (\_ -> (^2)) 3 ((3*) 3)
-- (^2) ((3*) 3)
-- (^2) 9
81``````

An `apply` example with functions:

``````>  liftA2 (+) (^2) (3*) 3
-- pure (+) `apply` (^2) `apply` (3*) \$ 3
-- const (+) `apply` (^2) `apply` (3*) \$ 3
-- apply (apply (const (+)) (^2)) (3*) \$ 3
-- (\t1 -> (apply (const (+)) (^2)) t1 ((3*) t1)) \$ 3
-- (\t1 -> (\t2 -> (const (+)) t2 ((^2) t2)) t1 ((3*) t1)) \$ 3
-- (\t2 -> (const (+)) t2 ((^2) t2)) 3 ((3*) 3)
-- (const (+)) 3 ((^2) 3) ((3*) 3)
-- (\_ -> (+)) 3 ((^2) 3) ((3*) 3)
-- (+) ((^2) 3) ((3*) 3)
-- (+) 9 ((3*) 3)
-- (+) 9 9
18``````

## From `Applicative_` to `Applicative`

The `Applicative` class defined in `Control.Applicative` — and exposed by `Prelude` — uses the name `(<*>)` rather than `apply`. (We alluded to this choice in the "Monad Roadmap").

``````class Functor f => Applicative f where
-- fmap  ::   (a -> b) -> f a -> f b    -- from Functor
(<*>) :: f (a -> b) -> f a -> f b    -- Applicative_.apply
pure  :: a -> f a                    -- Applicative_.pure``````

The `Control.Applicative` library defines `liftA2`, `liftA3`, etc. functions analogous to the `lift2Maybe`, `lift3Maybe`, etc. functions we defined before.

There are also versions of `(<*>)` that "keep" the left or right arguments and "ignore" the other:

``````(<*) :: Applicative f => f a -> f b -> f a
(*>) :: Applicative f => f a -> f b -> f b``````

Think about how to define these "for free" in terms of `(<*>)`. We'll see cases in which these operators are quite handy (stay tuned for "parser pipelines").