# Maybe as an Applicative Functor

`Maybe`

type is made an instance of the `Applicative`

type class as follows:

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

It took me a several attempts before I could parse this definition. I was particularly puzzled by the line `(Just f) <*> something = fmap f something`

. To help me understand this better, I decided to build this definition back up from the very basics.

First, let’s look at the `Functor`

type class definition:

```
class Functor f where
fmap :: (a -> b) -> f a -> f b
```

This means that for a given functor type `f`

(i.e. type that is an instance of the `Functor`

type class), `fmap`

takes a function from `a -> b`

and a functor (box) that contains `a`

and returns a functor (box) that contains `b`

. An intuitive way to think about this is that `fmap`

opens the box containing `a`

and applies the function `a -> b`

to it, which results in `b`

.

Now let’s see how `Maybe`

is an instance of the `Functor`

type class:

```
instance Functor Maybe where
fmap func Nothing = Nothing
fmap func (Just x) = Just (func x)
```

- Line 2: Applying a function to
`Nothing`

results in`Nothing`

. - Line 3: From the definition of the
`Functor`

type, we know that the type of`func`

is`a -> b`

and`Just x`

corresponds to`f a`

. Applying the function to`x`

inside the box results in a value of type`b`

in the functor box.

Now, let’s look at the definition of the `Applicative`

type class:

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

For a type `f`

that is an instance of the `Applicative`

type class, here is what each line means:

`f`

must also be a functor (i.e. be an instance of the`Functor`

type class).- The
`pure`

function takes an arbitrary type`a`

and brings it into the functor. i.e.`pure`

puts`a`

in a box of type`f`

. `<*>`

takes a functor (box) of type`f`

that contains a function of type`a -> b`

, and a functor (box) of type`f`

that contains type`a`

. It results in a functor (box) of type`f`

that contains`b`

.

With the preamble out of the way, let’s make `Maybe`

an instance of the `Applicative`

type class. To do that, I need to implement the `pure`

and `<*>`

methods for the `Maybe`

type. Below is a line-by-line implementation:

```
instance Applicative Maybe where
pure x = Just x
```

For the `Maybe`

type, `pure`

simply wraps an arbitrary type in `Just`

, thus making it a `Maybe`

value. E.g. writing `pure 4 :: Maybe Int`

in GHCi results in `Just 4`

.

```
(<*>) Nothing _ = Nothing
```

Here, `Nothing`

maps to `f (a -> b)`

from the `Applicative`

class definition. We cannot extract a function out of `Nothing`

, so the result will be `Nothing`

regardless of the second argument.

```
(<*>) (Just func) Nothing = Nothing
```

In the line above, `(Just func)`

maps to `f (a -> b)`

, and `Nothing`

maps to `f a`

from the class definition. `<*>`

extracts `func`

out of `Just func`

, and applies it to `Nothing`

. Applying a function to `Nothing`

results in `Nothing`

(or, using the box analogy, applying a function to an empty box results in an empty box)

```
(<*>) (Just func) (Just x) = Just (func x)
```

`(Just func)`

maps to `f (a -> b)`

, and `Just x`

maps to `f a`

from the `Applicative`

class definition. `<*>`

extracts the function from `Just func`

, and applies it to `x`

inside the `Just x`

box. The result is `Just (func x)`

.

Now, let’s put the definition of `<*>`

for `Maybe`

type next to the definition of the `fmap`

function:

```
(<*>) (Just func) Nothing = Nothing
(<*>) (Just func) (Just x) = Just (func x)
fmap func Nothing = Nothing
fmap func (Just x) = Just (func x)
```

This makes it obvious that in the definition of `<*>`

, once we extract `func`

out of `Just func`

, we simply map that function over the second argument of `<*>`

(which will be of `Maybe`

type as well). This means that the `<*>`

implementation for `Maybe`

can be re-written as:

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

This is exactly how the `<*>`

function is implemented at the beginning of this blog post.

Finally, Functors, Applicatives, And Monads In Pictures by Aditya Bhargava is one of the best posts I’ve read on functors & applicatives. I highly recommend it.