↰
# Road to monads: Applicative functors

## Introduction

## What is an applicative
functor?

## Definition

## Applicative functor laws

## Standard applicatives

### Maybe

### List

### ->

Back to archive

Applicative functors are halfway between functors and monads; all monads are applicative functors, but not all applicative functors are monads. Also, all applicative functors are functors, but not all functors are applicative functors.

Unfortunately, in Haskell this is not accurately represented, because monads and functors preceded the implementation of applicative functors, meaning that there is not a typeclass constraint of applicative functor on monads even though there should be. They are trying to address this with the [FAMP (Functor-Applicative-Monad proposal)][1], which will ship with GHC 7.10.

Make sure you [understand functors][2] before trying to understand applicatives.

An applicative functor is a functor which allows function application inside it.

This is done by providing a mechanism for values (and in Haskell
functions are treated identically to values) to be lifted into the
context of the applicative functor. There is also a higher-level
`fmap`

to apply functorized functions to functors.

Applicative functors have the following typeclass:

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

Applicative functors are not in the standard prelude (yet), so must
be imported from `Control.Applicative`

; this module also
introduces `<$>`

which is a synonym for
`fmap`

but in infix form. A lot of code using applicatives
uses `<$>`

instead of `fmap`

for
readability, so for consistency so will I.

Notice the typeclass constraint on an applicative functor: it must first be a functor, which demonstrates what I said before.

Applicatives implement `pure`

and `<*>`

(pronounced “ap” as in apply); `pure`

takes a value and puts
it into the context of the applicative functor:

```
: pure 1
λ1
: pure 1 :: Maybe Int
λJust 1
: pure 1 :: [Int]
λ1] [
```

`<*>`

is like a special `<$>`

which
works on functions inside functors:

```
-- List applicative functor
: [(+1), (+2)] <*> [4, 5]
λ5,6,6,7]
[
-- Maybe applicative functor
: Just (*2) <*> Just 4
λJust 8
```

Applicatives follow the functor laws, and build upon them:

```
-- Lifting a function into an applicative context and then applying it is the
-- same as fmap'ing that function
pure f <*> = fmap f
-- Hence, identity
pure id <*> x = x
-- Lifting into applicative context can be deferred - Homomorphism
pure f <*> pure x = pure (f x)
-- Order of evaluation is interchangable
-- LHS means apply x to y in the applicative context
-- RHS means evaluate y in the applicative context before applying x to it
<*> pure y = pure ($ y) <*> x
x
-- Composition
<*> (y <*> z) = pure (.) <*> x <*> y <*> z
x -- By example
let x = Just (+1)
= Just (*2)
y = Just 3
z -- LHS
Just (+1) <*> (Just (*2) <*> Just 3) =
Just (+1) <*> (Just 6) =
Just 7
-- RHS
pure (.) <*> Just (+1) <*> Just (*2) <*> Just 3 =
Just ((+1) . (*2)) <*> Just 3 =
Just 7
```

`Maybe`

is also an instance of `Applicative`

,
allowing optional functions to be applied to optional values.

The applicative instance for `Maybe`

looks like this:

```
instance Applicative Maybe where
pure = Just
Just f) <*> (Just x) = Just (f x)
(<*> _ = Nothing _
```

Here we pattern match to get a function and a value, applying that
function to that value, otherwise we get a `Nothing`

because
`Maybe`

values are either `Just`

there or
`Nothing`

is there.

```
: Just (+1) <*> Just 2
λJust 3
: Nothing <*> Just 2
λNothing
: Just (+1) <*> Nothing
λNothing
```

There are actually multiple logical ways about turning lists into
applicative functors: one way is to compute every value
non-deterministically, and another which is to apply the function at the
*n*th index in the first list to the value at the *n*th
index in the second list.

The first is the default instance of list applicative:

```
instance Applicative [] where
pure x = [x]
<*> xs = [f x | f <- fs, x <- xs] fs
```

```
-- Take the head of the first list, map it over the second list, recurse and
-- concatenate the results
: [(+1), (*2), (+4)] <*> [1, 3, 8, 7]
λ2,4,9,8,2,6,16,14,5,7,12,11] [
```

The second instance is called a `ZipList`

, and is really a
type synonym for an ordinary list using the `newtype`

keyword:

`newtype ZipList a = ZipList [a]`

Try to work out the functor instance of `ZipList`

:

```
instance Functor ZipList where
fmap f (ZipList xs) = ZipList (map f xs)
```

With this wrapper, the applicative instance looks like this:

```
instance Applicative ZipList where
-- To satisfy the identity law, we turn the second list into an infinite list
-- so we aren't left with functions without values to map to
pure x = ZipList (repeat x)
-- zipWith ($) is zipping the two lists with the function application operator
ZipList fs) <*> (ZipList xs) = ZipList (zipWith ($) fs xs) (
```

Here is an example showing how it works:

```
: ZipList [(*2), (+1), (*2), (*5)] <*> ZipList [1..10]
λZipList {getZipList = [2,3,6,20]}
: ZipList [(*2), (+1), (*2), (*5)] <*> pure 1
λZipList {getZipList = [2,2,2,5]}
```

Here is the instance for function composition as an applicative:

```
instance Applicative ((->) r) where
pure = const
<*> g x = f x (g x) f
```

Here `pure`

is the same as `const`

, which takes
two functions and throws the second one away (also known as the
**K** combinator):

`const f _ = f`

The effect of this is that it creates a function that returns the value inside it, ignoring its parameter:

```
: :t pure 3
λpure 3 :: (Applicative f, Num a) => f a
: :t pure 3 "abc"
λpure 3 "abc" :: Num a => a
```

`<*>`

here demonstrates the **S**
combinator, applying both functions to the input and applying the output
of the first function to the output of the second, which is made clearer
by `isAlphaNum`

from `Data.Char`

.

```
isAlphaNum :: Char -> Bool
isAlphaNum = (||) <$> isAlpha <*> isDigit
isAlphaNum 'a' =
||) <$> isAlpha <*> isDigit) 'a' =
((||) . isAlpha) <*> isDigit) 'a' =
(((||) . isAlpha) 'a' $ isDigit 'a' =
((||) . isAlpha) 'a' $ False =
((||) True) $ False =
((True ||) $ False =
(True || False =
True
```