So last week, we discussed the Functor typeclass. We found it allows us to run transformations on data regardless of how the data is wrapped. No matter if our data were in a List, a `Maybe`

, an `Either`

, or even a custom type, we could simply call `fmap`

. However, what happens when we try to **combine wrapped data?** For instance, if we try to have GHCI interpret these calculations, we’ll get type errors:

```
>> (Just 4) * (Just 5)
>> Nothing * (Just 2)
```

## Functors Falling Short

Can functors help us here? We can use fmap to wrap multiplication by the particular wrapped `Maybe`

value:

```
>> let f = (*) <$> (Just 4)
>> :t f
f :: Num a => Maybe (a -> a)
>> (*) <$> Nothing
Nothing
```

This gives us a partial function wrapped in a `Maybe`

. But we **still cannot unwrap** this and apply it to `(Just 5)`

in a generic fashion. So we have to resort to code specific to the `Maybe`

type:

```
funcMaybe :: Maybe (a -> b) -> Maybe a -> Maybe b
funcMaybe Nothing _ = Nothing
funcMaybe (Just f) val = f <$> val
```

This obviously won’t work with other functors types.

## Applicatives to the Rescue

This is exactly what the Applicative typeclass is for. It has two main functions:

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

The pure function takes some value and wraps it in a minimal context. The `<*>`

function, called sequential application, takes two parameters. First, it takes a function wrapped in the context. Next, a wrapped value. Its output is the result of applying the function to the value, rewrapped in the context. An instance is called an applicative functor because it allows us to **apply** a wrapped **function**. Since sequential application takes a wrapped function, we typically begin our use of applicatives by wrapping something with either pure or fmap. This will become more clear with some examples.

Let’s first consider multiplying Maybe values. If we are multiply by a constant value we can use the functor approach. But we can also use the **applicative approach** by wrapping the constant function in `pure`

and then using sequential application:

```
>> (4 *) <$> (Just 5)
Just 20
>> (4 *) <$> Nothing
Nothing
>> pure (4 *) <*> (Just 5)
Just 20
>> pure (4 *) <*> Nothing
Nothing
```

Now if we want to multiply 2 maybe values, we start by wrapping the bare multiplication function in `pure`

. Then we sequentially apply both `Maybe`

values:

```
>> pure (*) <*> (Just 4) <*> (Just 5)
Just 20
>> pure (*) <*> Nothing <*> (Just 5)
Nothing
>> pure (*) <*> (Just 4) <*> Nothing
Nothing
```

## Implementing Applicatives

From these examples, we can tell the `Applicative`

instance for `Maybe`

is implemented **exactly how we would expect**. The `pure`

function simply wraps a value with `Just`

. Then to chain things together, if either the function or the value is `Nothing`

, we output `Nothing`

. Otherwise apply the function to the value and re-wrap with `Just`

.

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

The `Applicative`

instance for Lists is a little more interesting. It doesn’t exactly give the behavior we might first expect.

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

The `pure`

function is what we expect. We take a value and wrap it as a singleton in a list. When we chain operations, we now take a LIST of functions. We might expect to apply each function to the value in the corresponding position. However, what actually happens is we apply every function in the first list to every value in the second list. When we have only one function, this results in familiar mapping behavior. But when we have multiple functions, we see the difference:

```
>> pure (4 *) <*> [1,2,3]
[4,8,12]
>> [(1+), (5*), (10*)] <*> [1,2,3]
[2,3,4,5,10,15,10,20,30]
```

This makes it easy to do certain operations, like finding every pairwise product of two lists:

```
>> pure (*) <*> [1,2,3] <*> [10,20,30]
[10,20,30,20,40,60,30,60,90]
```

You might be wondering how we might do parallel application of functions. For instance, we might want to use the second list example above, but have the result be `[2,10,30]`

. There is a construct for this, called `ZipList`

! It is a newtype around list, whose `Applicative`

instance is designed to use this behavior.

```
>> ZipList [(1+), (5*), (10*)] <*> [5,10,15]
ZipList {getZipList = [6,50,150]}
```

## Summary

- Applicative functors take the idea of normal functors one step further.
- They allow function application to occur within the wrapper context.
- In some circumstances, this allows us to reuse generic code.
- In other cases, this gives us clean idioms to express simple concepts and solve common problems.