In the last installation of this series, we covered the Functor and now we take a turn to discuss the `Applicative`

type class.

### It’s all about functions

Being functional programmers, the thing we embrace most are functions. Despite scala being an `object-functional`

language, I fell in love with it, due to it’s possibilities to write code using the functional paradigm and not state mutating object nonsense. And I believe it is a good exercise, if you (like me) come from a java background to emphasize functions over objects first. It is a different way of approaching problems, and it needs getting used to, but it pays of in the end.

Having said all that, let us remember that functions come in different flavours, they can have one parameter or multiple parameters and return a value and if they don’t return a value, but `Unit`

we basically know that this function stinks. It is no wonder then that functions can be transformed to take on a new `Gestalt`

:

What this tells us, that we can turn any function expecting multiple parameters in a function with one parameter (tupled), or in function were we can apply the parameters “lazily” in the curried version. We can also revert these forms into the original “multiple parameter” style. And don’t worry about the different use of “X” and “-” in the table, I just got carried away.

### The problem with our Functor typeclass and `map`

`map`

takes a function `f: A => B`

and applies this function in a context `F`

. What about functions taking more than one parameter? For example if we have a function `f: A => B => C`

and do `Functor[Option].map(Some(3))(f)`

we would end up with a value of `Some(B => C)`

:

```
val add : Int => Int => Int = x => y => x + y
Functor[Option].map(Some(3))(add)
add: Int => (Int => Int) = <function1>
>>> res0: Option[Int => Int] = Some(<function1>)
```

*Problem 1*: we cannot continue to map over the resulting value, which is a function in the context of Option, whereas`map`

does not provide that type signature. Try on your own, to see what happens, if you try to continue to map over the resulting value (spoiler: compiler errors happen, but which ones?)*Problem 2*: we cannot supply 2 parameters to map as in the fictional`Functor[Option].map(Some(3), Some(4)).map(add)`

#### Workaround

One workaround to our problem with map, could be to transform any function to their tupled representation, and map over a tuple, as in:

```
def add(x: Int, y: Int) = x + y
Functor[Option].map(Some((3,4)))((add _).tupled)
>>> res0: Option[Int] = Some(7)
```

*Problem 3*: Though this seems to work, it is clumsy, and what happens, if we do not have all values at hand, e.g. if we want to add`Some(3)`

and`None`

. How would we build a tuple from that?

### Applicative

Having understood these problems, we can introduce the `Applicative`

type class. It solves our problems, and as an aside has some very funny properties, which make it super powerful. Boiled down to its core interface the `Applicative`

looks like this:

```
trait Applicative[F[_]] {
// other functions ommitted for now
def ap[A, B](fa: => F[A])(f: => F[A => B]): F[B]
}
```

Let’s have a look at the problems which we have described above and see how an `Applicative`

might help. The signature of `ap`

seems to suggest that we can apply a value A in context `F`

to a function A=>B which resides in a context `F`

and get a result `B`

in the context of `F`

. WTF?

Or in plain english: If we have an optional parameter and apply it to an optional function we get an optional result. The same for the context `List`

: if we have a list of parameter values and a apply those to a list of functions we get a list of results. If the list of functions or parameters would be empty, we would get an empty list of results. Cool, eh? (we observe that an Applicative executes functions in a context, and preserves that context.)

### Interlude

Before we can consider the other problems, we introduce two more functions to the Applicative trait:

```
trait Applicative[F[_]] extends Functor[F] {
def pure[A](a: A): F[A]
def ap[A, B](fa: => F[A])(f: => F[A => B]): F[B]
override def map[A, B](fa: F[A])(f: A => B): F[B] =
ap(fa)(pure(f))
}
```

One is `pure`

(often aliased as `point`

) and one is the fact that every Applicative is also a Functor, and we can implement `map`

in terms of the functions of `ap`

and `pure`

. `pure`

is the function which allows us to put a single value `A`

into some context `F`

. In plain scala this would often be the `apply`

method of the companion object, and with `pure`

we have the means to abstract over the construction of values in a context. Every `Applicative`

is also a `Functor`

as we can simply *lift* the function f into the context `F`

using `pure`

and then use `ap`

to apply the value to the function inside the context.

Here are some sample instances:

```
val optionApplicativeInstance : Applicative[Option] = new Applicative[Option] {
override def pure[A](a: A): Option[A] = Some(a)
override def ap[A, B](fa: => Option[A])(f: => Option[(A) => B]): Option[B] = {
(fa, f) match {
case (Some(fa1), Some(f1)) => Some(f1(fa1))
case _ => None
}
}
}
val listApplicativeInstance : Applicative[List] = new Applicative[List] {
override def pure[A](a: A): List[A] = List(a)
override def ap[A, B](fa: => List[A])(f: => List[(A) => B]): List[B] = {
for { // cheating as I implement this using flatMap which is a function of monads.
fa1 <- fa
f1 <- f
} yield (f1(fa1))
}
}
```

### Problem solving continued

Let’s try to tackle problem 2 and find a way to supply 2 arguments to a function `f: (A,B) => C`

. In fact `Applicative`

contains lots of derived functions, and some of them are `ap2`

… `ap22`

, where the number denotes the number of arguments of our function.

```
def ap2[A,B,C](fa: => F[A],fb: => F[B])(f: F[(A,B) => C]) : F[C] =
(ap(fb)(ap(fa)(map(f)(_.curried))))
```

Step by Step:
* we `map`

over the function `f`

, thus looking into the context, and create the curried version of our function `A => B => C`

* after leaving `map`

, we have `F[A => B => C]`

* we `ap`

ply `fa`

, resulting in `F[B => C]`

and
* `ap`

ply `fb`

which results in
* `F[C]`

.

*q.e.d.* Yikes!

There is another group of functions associated with `Applicative`

which are the `applyN`

functions. The difference to `apN`

, is that they do not take function(s) in a context, but just a plain function and put it in the context via `pure`

for us.

```
def apply2[A,B,C](fa: => F[A],fb: => F[B])(f: (A,B) => C) : F[C] =
ap2(fa,fb)(pure(f))
```

### Notes

The naming conventions and precise structure within `Applicative`

can vary between differnt type class libraries. For example most of the functions in scalaz are implemented in `Apply`

with `Applicative`

adding the `point/pure`

function. In my own testbed [simplez][http://github.com/inoio/simplez] I unified this classes and the type classes in the play framework, again use `pure`

instead of `point`

and does not inherit directly from `Functor`

, but implements `map`

directly. But in the end, it all boils down to the same thing.

### Further learning

The books `Functional programming in Scala`

and `Scala in Depth`

both cover the essentials of `Applicative`

s very well.

### That’s it?

No, there will be a part 2 for Applicatives in this series covering the `ApplicativeBuilder`

and a (gosh!) practical example. Slowly but steady we continue to build our type class toolbox. As we will see, the previous classes will pop up here and there again, especially when we want to use `Applicatives`

to “collect information” while still keeping the control flow intact.

For further articles in this series: TypeClass101