# Grasping Haskell: functors, applicatives and monads (part 2)

This is the second part in a series, the previous part covered Functors.

I like to introduce Functor Applicatives by introducing a problem.

Let’s say we have a function which takes two arguments and we want to apply it to two boxed values:

Easy right? We use a Functor! There’s only one problem: *fmap *only applies one value to a function.

How about applying *fmap *twice? We can use partial functions in Haskell!

first = fmap (+) (Just 3)

second = fmap first (Just 4)

Sadly, this won’t compile. In fact, it’s pretty obvious why: *fmap *returns the result (which is a partial function in this case) in a box. When we apply *fmap* the second time, it doesn’t get a (partial) function as first argument, instead it receives a boxed function.

Applicatives to the rescue!

### Applicative Functors

The *Applicative *typeclass is located in the *Control.Applicative *module and defines two methods: *pure *and *<*>*.

class(Functor f) => Applicative fwherepure :: a -> f a

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

Again, we can derive a lot from this class definition:

- If we want to make a type an
*Applicative,*it has to be a*Functor*first. *pure*takes a value and returns an*Applicative*with that value inside it.- If you look closely, you’ll see that
*<*>*resembles*fmap*pretty well. In fact, the only difference lies in the first argument! While*fmap*takes a function,*<*>*takes a**function that is****inside an Applicative.**

That last sentence rings a bell, right? It should, because it solves the problem we encountered in the introduction.

#### Maybe as an Applicative

So how does this work in practice? Let’s have a look at Maybe’s Applicative implementation:

instanceApplicative Maybewherepure = Just

Nothing <*> _ = Nothing

(Just func) <*> something = fmap func something

Let’s break it down.

*pure *is simply *Just. *When implementing *pure, *you should aim to put the value in **the minimal context** that still yields that value. We’ll encounter a clearer example a bit further in this article.

Notice that *<*> *is an infix operator.

Extracting a function from *Nothing* is impossible, so we simply return *Nothing *again. However, if we match (Just func), we can apply *fmap *on the extracted *func *and *something.* This is possible because *something* also has to be a Functor!

Let’s apply our newly gained knowledge to our previous problem:

pure (+) <*> Just 3 <*> Just 4

equals *Just 7.*

But we’re not done yet! The *Control.Applicative *module exports another convenient function: *<$>, *which is defined as:

f <$> x = fmap f x

Recall that an Applicative is also a Functor, so we can use *fmap. *This allows us to rewrite our previous solution in a more elegant way:

(+) <$> Just 3 <*> Just 4

Beautiful, isn’t it?

#### List is an Applicative too!

As you could’ve guessed, lists also instantiate the Applicative typeclass. Let’s dive right into the implementation:

instanceApplicative []wherepure x = [x]

fs <*> xs = [f x | f <- fs, x <- xs]

Recall that *pure *puts the value in the minimal context that still yields the same value. In this case, the least amount of context is achieved by putting it in a singleton list.

The implementation of *<*> *is worth a closer look. It’s nothing more than a list comprehension! It basically boils down to this: **every function is applied to every value, **and the results are returned in a new list**. **An example will make this more clear:

(*) <$> [2, 3] <*> [4, 5]

equals [8, 10, 12, 15].

I can hear you saying it already: that’s not what I always want! What if I want to apply each function in my first list to the respective value in the second list? The *ZipList *typeclass was made for this exact purpose, but for the sake of keeping things brief, I will not explain it here.

You should now have a firm grasp of the Functor and Applicative typeclass, and how they are related. If you have any questions or suggestions, do not hesitate to contact me!

The next and final article in this mini-series will handle Monads. Trust me, it’s not rocket science! Stay tuned.