# Applicative Functors

```
{-# LANGUAGE TypeSynonymInstances, FlexibleContexts, NoMonomorphismRestriction, OverlappingInstances, FlexibleInstances #-}
module ApplicativeFunctors where
```

```
import Prelude hiding (sequence)
import Control.Monad
import Data.Functor.Compose
import Test.HUnit
```

# An alternative to monads

We have seen how to use monads to express different kind of computational behaviors: errors, states, etc. and how to use these for specific tasks: parsing, evaluators, exception handling, etc.

We have also seen how to combine computational behaviors by means of monad transformers. In this way, we can build more interesting examples: evaluators with exceptions, etc.

Monads are not the only components useful to structure computations. Today we will go back to *functors* and see how a special class of functors: *applicative functors* represents an alternative to monads.

Let's take once again expression evaluation as an example:

```
-- | A variable
data Var = A | B | C | D | E | F | G | H | I | J
deriving (Show)
```

```
-- | Basic information: a literal or undefined
data Inf = Lit Bool Var | Undef
deriving (Show)
```

```
data Expr = Or3 Inf Inf Inf
| Not Expr
| And Expr Expr
deriving (Show)
```

This is a language for Boolean formulas containing atoms that are 3-clause of basic information `Inf`

. The basic component `Inf`

is either a literal or an undefined value. An expression containing an undefined value is partial and it cannot be evaluated to a boolean.

`ok = Not (And (Or3 (Lit True A) (Lit False B) (Lit True C)) (Not (Or3 (Lit True D) (Lit False E) (Lit True F)))) `

`err= Not (And (Or3 (Lit True A) (Lit False B) (Lit True C)) (Not (Or3 Undef (Lit False E) (Lit True F)))) `

Suppose once again that we want to evaluate those expressions. We can do it easily in an unsafe way

```
evalInfUnsafe :: Inf -> Bool
evalInfUnsafe (Lit a b) = a
```

```
evalUnsafe :: Expr -> Bool
evalUnsafe (Not x) = not (evalUnsafe x)
evalUnsafe (And x y) = evalUnsafe x && evalUnsafe y
evalUnsafe (Or3 x y z) = evalInfUnsafe x || evalInfUnsafe y || evalInfUnsafe z
```

and as expected this produces an exception in the case we evaluate an expression containing an undefined information `Undef`

.

```
*Main> evalUnsafe ok
*Main> evalUnsafe err
```

We now know how to take care of undefined behaviors. We can write an exception handler.

```
data Exc a = Raise String
| Result a
deriving (Show)
```

Using `Exc`

we can have an evaluator as follow:

```
evalInf :: Inf -> Exc Bool
evalInf (Lit a b) = Result a
evalInf _ = Raise "undefined value"
```

```
eval :: Expr -> Exc Bool
eval (Not x) = case eval x of
Raise s -> Raise s
Result xb -> Result (not xb)
eval (And x y) = case eval x of
Raise s -> Raise s
Result xb -> case eval y of
Raise s -> Raise s
Result yb -> Result (xb && yb)
eval (Or3 x y z) = case evalInf x of
Raise s -> Raise s
Result xb -> case evalInf y of
Raise s -> Raise s
Result yb -> case evalInf z of
Raise s -> Raise s
Result zb -> Result (xb || yb || zb)
```

So far so good.

```
*Main> eval ok
*Main> eval err
```

Our code is not really modular. We know that one method to better structure the computation is to use Monads. But how about using Functor instead?

We need to show that `Exc`

can be turned in an instance of `Functor`

, but this is easy!

```
instance Functor Exc where
-- fmap :: Functor f => (a -> b) -> f a -> f b
fmap f a = case a of
Raise s -> Raise s
Result x -> Result (f x)
```

So, can we use fmap to lift the boolean operations to the `Exc`

level?

```
eval1:: Expr -> Exc Bool
eval1 (Not x) = fmap not (eval1 x)
eval1 (And x y) = fmap2 (&&) (eval1 x ) (eval1 y)
eval1 (Or3 x y z) = fmap3 (\a -> \b -> \c -> a || b || c)
(evalInf x) (evalInf y) (evalInf z)
```

```
*Main> eval1 ok
*Main> eval1 err
```

How can we obtain `fmap2`

and `fmap3`

?

`-- fmap: (a -> b) -> Exc a -> Exc b`

```
fmap2 :: (a -> b -> c) -> Exc a -> Exc b -> Exc c
fmap2 f a b = case a of
Raise s -> Raise s
Result a -> fmap (f a) b
```

```
fmap3 :: (a -> b -> c -> d) -> Exc a -> Exc b -> Exc c -> Exc d
fmap3 f a b c = case a of
Raise s -> Raise s
Result a -> fmap2 (f a) b c
```

Suppose that we have an n-ary input function, how can we define the corresponding `fmapn`

?

```
-- fmap4 :: (a1 -> a2 -> a3 -> a4 -> r) -> Exc a1 -> Exc a2 -> Exc a3 -> Exc a4 -> Exc r
-- fmap5 :: ...
```

```
class Functor f => Applicative' f where
(<**>) :: f (a -> b) -> f a -> f b
```

```
instance Applicative' Exc where
f <**> a = case f of
Raise s -> Raise s
Result f' -> fmap f' a
```

```
fmap2':: (a -> b -> c) -> Exc a -> Exc b -> Exc c
fmap2' f a b = (fmap f) a <**> b
```

```
fmap3':: (a -> b -> c -> d) -> Exc a -> Exc b -> Exc c -> Exc d
fmap3' f a b c = (fmap f) a <**> b <**> c
```

Now, why we need to bring with us `fmap`

?

```
(<$>) :: Functor f => (a -> b) -> f a -> f b
(<$>) = fmap
```

we can now rewrite our example as:

```
fmap3'':: (a -> b -> c -> d) -> Exc a -> Exc b -> Exc c -> Exc d
fmap3'' f a b c = f <$> a <**> b <**> c
```

Now suppose that our third argument is not an exception but an Integer on which we cannot fail. We would like to have something like

`-- fmap3''' :: :: (a -> Int -> c -> d) -> Exc a -> Int -> Exc c -> Exc d`

How can we obtain it?

We can extend the Applicative' class:

```
class Functor f => Applicative f where
(<*>) :: f (a -> b) -> f a -> f b
pure :: a -> f a
```

and we can show that Exc is also an Applicative class

```
instance Applicative Exc where
f <*> a = f <**> a
pure a = Result a
```

```
fmap3''':: (a -> Int -> c -> d) -> Exc a -> Int -> Exc c -> Exc d
fmap3''' f a b c = f <$> a <*> pure b <*> c
```

Finally we can rewrite our evaluator with exception as:

```
eval2:: Expr -> Exc Bool
eval2 (Not x) = not <$> (eval2 x)
eval2 (And x y) = (&&) <$> (eval2 x ) <*> (eval2 y)
eval2 (Or3 x y z) = (||) <$> ((||) <$> (evalInf x) <*> (evalInf y)) <*> (evalInf z)
```

```
*Main> eval2 ok
*Main> eval2 err
```

Applicative Functors helps us to structure exceptions. Are they also useful more in general?

# Every Monad is Applicative

Let's have a look back to Monads. Isn't the pattern of `fmap`

, `fmap2`

, `fmap3`

, etc familiar?

`-- liftM :: Monad m => (a1 -> r) -> m a1 -> m r`

`-- liftM2 :: Monad m => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r`

`-- liftM3 :: Monad m => (a1 -> a2 -> a3 -> r) -> m a1 -> m a2 -> m a3 -> m r`

Let's try to build them in a modular way:

```
liftM' :: Monad m => (a1 -> r) -> m a1 -> m r
liftM' f a = do a' <- a
return (f a')
```

```
liftM2' :: Monad m => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2' f a b = do a' <- a
b' <- b
return (f a' b')
```

```
liftM3' :: Monad m => (a1 -> a2 -> a3 -> r) -> m a1 -> m a2 -> m a3 -> m r
liftM3' f a b c = do a' <- a
b' <- b
c' <- c
return (f a' b' c')
```

How can we make these kind of construction more parametric? What we want to do is to have a way for

```
aP :: Monad m => m (a -> b) -> m a -> m b
f `aP` x = do f' <- f
x' <- x
return (f' x')
```

With this new operation we can build all the liftMn we need.

```
liftM'' :: Monad m => (a1 -> r) -> m a1 -> m r
liftM'' f x = return f `aP` x
```

```
liftM2'' :: Monad m => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2'' f x y = return f `aP` x `aP` y
```

```
liftM3'' :: Monad m => (a1 -> a2 -> a3 -> r) -> m a1 -> m a2 -> m a3 -> m r
liftM3'' f x y z = return f `aP` x `aP` y `aP` z
```

```
liftM4'' :: Monad m => (a1 -> a2 -> a3 -> a4 -> r) -> m a1 -> m a2 -> m a3 -> m a4 -> m r
liftM4'' f x y z w = return f `aP` x `aP` y `aP` z `aP` w
```

Indeed this shows that every `Monad`

is `Applicative`

!

Let's have a look to some concrete instances.

```
instance Applicative Maybe where
pure a = return a
f <*> x = f `aP` x
```

```
instance Applicative IO where
pure = return
f <*> x = f `aP` x
```

More in general we have:

`newtype WrappedMonad m a = Wrap {unWrap :: m a}`

```
instance Monad m => Functor (WrappedMonad m) where
fmap = fmap
```

```
instance Monad m => Applicative (WrappedMonad m) where
pure a = Wrap (return a)
Wrap f <*> Wrap x = Wrap (liftM2 ($) f x)
```

But not every Applicative is a Monad. Indeed, we can think that `pure`

can corresponds to `return`

but how about `>>=`

?

```
instance Applicative m => Monad m where
return a = pure a
x >>= f = ??
```

The difference between the two notions can be explained in term of the flow of information

```
cond :: Monad m => m Bool -> m a -> m a -> m a
cond m f g = do bool <- m
if bool then f else g
```

```
cond' :: Applicative m => m Bool -> m a -> m a -> m a
cond' m f g = pure (\b t e->if b then t else e) <*> m <*> f <*> g
```

The evaluation of this expressions can bring to results that are interestingly different. This because in `cond`

the value `bool`

returned by the computation `m`

influence the choice of the result. Conversely, in `cond'`

we just sequence the results.

```
*Main> cond (Just True) (Just False) Nothing
*Main> cond' (Just True) (Just False) Nothing
```

So, we have that every `Monad`

is `Applicative`

but not that every `Applicative`

is a `Monad`

. This suggests that even if they share many similarities, `Monad`

and `Applicative`

are two interesting distinct concepts. Both of them can be used to structure computation. The choice on when using one or the other depends on the concrete application we need to develop.

As a guideline we can think that `Monad`

are particularly useful when we want the value returned by one computation to influence the choice of another. This is the main characteristic of `>>=`

. Conversely, `Applicative`

are useful when the structure of a computation is fixed and we just need to sequence the results. This is what `<*>`

is useful for.

# Applicative Functors Compose Easily

We have seen how to compose Monads thanks to Monad Transformers. How about composing Applicative Functors? Clearly, we can define in a similar way Applicative Transformers (and we have also a library for doing this). Alternatively we can try to compose them directly.

Let's try to build the product of two Applicative Functors.

`data Prod f g a = Prod (f a) (g a)`

```
instance (Functor f, Functor g) => Functor (Prod f g) where
-- fmap: (a -> b) -> Prod f g a -> Prod f g b
fmap h (Prod x y) = Prod (fmap h x) (fmap h y)
```

```
instance (Applicative f, Applicative g) => Applicative (Prod f g) where
pure x = Prod (pure x) (pure x)
Prod f g <*> ~(Prod x y) = Prod (f <*> x) (g <*> y)
```

Easy, isn't it? but the product is not the real composition. How can we achieve composition then?

First, we need to see how two functors can be composed!

```
class Composition cp where
decompose :: (cp f g) x -> f (g x)
compose :: f (g x) -> (cp f g) x
```

-- | Basic functor composition

`newtype CompF f g a = CompF { runCompF :: f (g a) }`

```
instance Composition CompF where
compose = CompF
decompose = runCompF
```

```
instance (Functor f, Functor g) => Functor (CompF f g) where
fmap f = compose . fmap (fmap f) . decompose
```

Then the composition of Applicative Functors comes naturally.

```
instance (Applicative f, Applicative g) => Applicative (CompF f g) where
pure x = CompF (pure (pure x))
CompF f <*> CompF x = CompF (pure (<*>) <*> f <*> x)
```

# An Example of Applicative Functor threading

Besides composition, Applicative are particularly easy to thread. Let's go back to the motivating example and see how our evaluator can be enriched by both exceptions and step counting.

We have defined `Exc`

, now we need a step counter. This can be done easily.

```
data Count a = Count a Int
deriving (Show)
```

We need to show that `Count`

is an Applicative Functor.

```
instance Functor Count where
fmap f (Count a i) = Count (f a) i
```

```
instance Applicative Count where
pure a = Count a 0
Count f i <*> Count x j = Count (f x) (i+j)
```

And we can define the `tick`

counter

```
tick :: Count a -> Count a
tick (Count a n) = Count a (n+1)
```

We can thread `Exc`

and `Count`

in the evaluation.

```
evalInf' :: Inf -> Exc Bool
evalInf' (Lit a b) = Result a
evalInf' _ = Raise "undefined value"
```

```
eval3 :: Expr -> Exc (Count Bool)
eval3 (Not x) = case eval3 x of
Raise s -> Raise s
Result (Count xb n) -> Result (Count (not xb) (n+1))
eval3 (And x y) = case eval3 x of
Raise s -> Raise s
Result (Count xb n) -> case eval3 y of
Raise s -> Raise s
Result (Count yb m) -> Result (Count (xb && yb) (n+m+1))
eval3 (Or3 x y z) = case evalInf' x of
Raise s -> Raise s
Result xb -> case evalInf' y of
Raise s -> Raise s
Result yb -> case evalInf' z of
Raise s -> Raise s
Result zb -> Result (Count (xb || yb || zb) 1)
```

Again, this code is not very modular! Let's use what we have in our Applicative Functors arsenal. First, we need to generalize to a generic `Functor f`

some of the operations we have introduced above.

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

```
fmap3G :: Applicative f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d
fmap3G f a b c = f <$> a <*> b <*> c
```

With this we can finally write our evaluator with exception and step-counting as:

```
eval4:: Expr -> Exc (Count Bool)
eval4 (Not x) = (tick . (fmap not)) <$> (eval4 x)
eval4 (And x y) = fmap2G ( \s -> \ r -> tick (fmap2G (&&) s r)) (eval4 x) (eval4 y)
eval4 (Or3 x y z) = fmap3G or3 (evalInf' x) (evalInf' y) (evalInf' z)
```

```
or3 :: Bool -> Bool -> Bool -> Count Bool
or3 a b c = tick ( fmap2G (||) (fmap2G (||) (pure a) (pure b) ) (pure c) )
```

```
*Main> eval4 ok
*Main> eval4 err
```

# Applicative Functor Notation

In the code above we have used some non standard notation. Let's try to fix what is standard. In the module `Control.Applicative`

the definition of `Applicative`

corresponds to the one we gave above:

```
class Functor f => Applicative f where
(<*>) :: f (a -> b) -> f a -> f b
pure :: a -> f a
```

The symbol `<*>`

is the standard symbol for application of Applicative Functors.

While we used above the symbol `<**>`

as a synonym of `<*>`

, in the library it is instead used for a function similar to `<*>`

but with the order of the first two parameters reversed.

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

Finally, we used the symbol `aP`

for the lifted application on Monad. The standard symbol for that is instead ap

`ap :: m (a -> b) -> m a -> m b`

## News :

Welcome to CIS 552!

See the home page for basic
information about the course, the schedule for the lecture notes
and assignments, the resources for links to the required software
and online references, and the syllabus for detailed information about
the course policies.