# Functor, Applicative and Monad instances for Reader

How do you define a Reader (-> r) instance of a **Functor**, **Applicative** or even a **Monad**? A Reader is a function that takes some resource **r** and returns another value. This has been something that has always confused me. After an initial peruse it all makes sense for a while but when next faced with the same problem I can’t remember how these instances are implemented.

I’d like to analyse how the Reader instances are derived for each of **Functor**, **Applicative** and **Monad** and test it against some examples to gain some intuition. Also note that (-> r) and (r ->) can be used interchangeably. Thanks to Brian McKenna for that useful titbit.

### Functor

A functor typeclass is defined as:

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

**fmap** or **<$>** basically runs a function (**a -> b**), on a value within some context **f a** and returns the context with the function applied to its value as an **f b**.

```
(a -> b) -- f', a function that requires an 'a' to create a 'b'
f a -- Functor with an 'a'
f (f'(a)) -- apply f' to the 'a'
f b -- the final result of a 'b'
```

Let’s take a look at the **Functor** instance for Maybe:

```
instance Functor Maybe where
-- fmap :: (a -> b) -> f a -> f b
fmap f (Just a) = Just (f a)
fmap _ Nothing = Nothing
```

With **Maybe**, the function **f**, is applied to a value within a **Just** or not applied if the value is a **Nothing**.

When we hear that (-> r) is also a Functor it can boggle our minds a little. How do we define an instance for that?

```
instance Functor (-> r) where
fmap f = -- what goes here?
```

We need a function that takes some resource **r** and returns some other value. Let’s have a crack at deriving the implementation for Functor:

```
instance Functor (r -> ) where
-- fmap :: (a -> b) -> f a -> f b
fmap fab f a = f b -- refer to (a -> b) as fab
fmap fab (\r -> a) = (\r -> b) -- given that the Functor is (r ->), replace 'f' with (r ->)
fmap fab fra = (\r -> b) -- refer to (r -> a) as fra so we can use it
fmap fab fra = (\r -> ??? (fra r)) -- we have an 'r' and we have something that needs an 'r' and returns an 'a'.
fmap fab fra = (\r -> fab (fra r)) -- We have an 'a' and something that needs an 'a' to return a 'b'
fmap fab fra = fab . fra -- we can simplify this to composing fab and fra
```

We are applying the function **fab** to the result of **fra**. It looks like **fmap** takes two functions are composes them.

Compose (.) is defined as:

`(.) :: (b -> c) -> (a -> b) -> a -> c`

or in our case:

`(.) :: (a -> b) -> (r -> a) -> r -> b`

And we can implement the Functor for (r ->) with compose alone:

```
instance Functor (r -> ) where
fmap = (.)
```

This gives us the intuition that fmap over functions is just composition.

Let’s use it on an example:

`fmap (*3) (+100) 1`

What is the result of the above?

Let’s use function composition to get the answer:

```
fmap (*3) (+100) 1
= (\r -> (r + 100) * 3) -- expanding Functor
= ((1 + 100) * 3) -- substituting 1 for 'r'
= 303
```

### Applicative

The Applicative typeclass is defined as:

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

The **pure** function lifts some value **a** into the **Applicative**, **f**. Also note that **f** is also a **Functor**. The **<$>** function sequences a function from (**a -> b**) within an **Applicative** context, with the value of **a** supplied in another **Applicative** context to produce the result **b** in a third **Applicative** context.

Note the similarities between **<$>** and <*>:

```
fmap, (<$>) :: (a -> b) -> f a -> f b
(<*>) :: f (a -> b) -> f a -> f b
```

The only difference is that with <*> the function is within a context **f**.

```
f (a -> b) -- f', a function within a context 'f', requires an 'a' to create a 'b'
f a -- Applicative Functor with an 'a'
f (f'(a)) -- apply f' to the 'a' within 'f'
f b -- the final result of a 'b'
```

Let’s take a look at the **Applicative** instance for **Maybe**:

```
instance Applicative Maybe where
-- pure :: a -> f a
pure = Just
-- (<*>) :: f (a -> b) -> f a -> f b
(<*>) (Just f) other = fmap f other
(<*>) Nothing _ = Nothing
```

For **Maybe**, **pure** simply creates an instance of **Just** with the supplied value. With <*> the function **f** is within a **Maybe** context. If the context is a **Just**, the function is applied to the other **Maybe** context using **fmap** from the **Functor** typeclass. If the context is a **Nothing**, no function application takes place and a **Nothing** is returned.

How do we define an **Applicative** instance for (r ->) ?

```
instance Applicative (r -> ) where
-- pure :: a -> f a
pure a = \r -> a
-- (<*>) :: f (a -> b) -> f a -> f b
(<*>) f g = \r -> f r (g r) -- f is (\r -> (a -> b)), g is (\r -> a)
```

Apply the input **r** to **g** to return an **a** and also apply **r** to **f**, to return the function from (**a -> b**). Then apply the function (**a -> b**) to **a** to return a **b**.

Let’s use it on an example:

```
(+) <$> (+3) <*> (*100) 5
= (+) <$> (\r -> r + 3) <*> (\r -> r * 100) 5 -- expanding Applicative
= (+) <$> (5 + 3) (5 * 100) -- substituting 5 for 'r'
= 8 + 500 -- combining with (+)
= 508
```

You may also notice that this gives you the same answer as **liftA2**:

```
liftA2 :: (a -> b -> c) -> f a -> f b -> f c
liftA2 (+) (+3) (*100) 5
= 508
```

The intuition here is that, we can supply the input to each **Applicative** context, and then combine them with a function either through **<$>** or **liftA2**.

And here’s one more example which may seem a little hairy:

```
(\x y z -> [x,y,z]) <$> (+3) <*> (*2) <*> (/2) $ 5
= (\x y z -> [x,y,z]) <$> (\r -> r +3) <*> (\r -> *2) <*> (\r -> /2) $ 5 -- expand Applicative
= (\x y z -> [x,y,z]) <$> (5 + 3) <*> (5 * 2) <*> (5 / 2) -- replace 'r' with 5
= (\x y z -> [x,y,z]) <$> (8.0) <*> (10.0) <*> (2.5)
= [8.0, 10.0, 2.5] -- combine with (\x y z -> [x,y,z])
```

The same result can be achieved with **liftA3**:

```
liftA3 (\x y z -> [x,y,z]) (+3) (*2) (/2) $ 5
= [8.0,10.0,2.5]
```

### Monad

The **Monad** typeclass is defined as:

```
class Applicative m => Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
```

The **return** function lifts a value **a** into the **Monad** **m**. Bind or (**>>=**) sequentially composes two actions, passing any value produced by the first as an argument to the second.

Let’s take a look at the **Monad** instance for **Maybe** :

```
instance Monad Maybe where
-- (>>=) :: m a -> (a -> m b) -> m b
(Just a) >>= k = k a
Nothing >>= _ = Nothing
```

If the first **Maybe** context is a **Just**, then apply the function **k** to produce a new **Maybe** context. If the first **Maybe** context is a **Nothing**, then return **Nothing**.

How do we define an **Monad** instance for (r ->) ?

```
instance Monad (r ->) where
-- return :: a -> m a
return = pure
-- (>>=) :: m a -> (a -> m b) -> m b
f >>= g = \r -> g (f r) r -- f is (\r -> a), g is (\a -> \r -> b)
```

The **return** function is derived from **pure**, since all **Monads** are also **Applicatives**. The bind function (**>>=**) first applies the input **r** to **f** to give an **a**. It then applies the **a** to **g** to return a function from (**r -> b**). The input **r** is then applied to this function to return the final **b**.

The intuition here is that we supply the input resource **r** to **f** and use that result as the first input to **g** followed by **r** as the second input.

Let’s use it in an example:

```
(+3) >>= (*) $ 5
= (\r -> r + 3) >>= (\a -> \r -> a * r) 5 -- expanding the Monad for 'r'
= (5 + 3) >>= (\a -> a * 5) -- replace 'r' with 5
= (8) >>= (\a -> a * 5)
= (8 * 5) -- replace 'a' with 8
= 40
```

or simply:

```
(+3) >>= (*) $ 5
= ((5+3) * 5)
= (8 * 5)
= 40
```

We can also use the do syntax to solve the above:

```
let z1 = do
x <- (+3)
(x *)
z1 5
= 40
```

#### Join

The **join** function flattens nested **Monads** and is defined as:

```
join :: (Monad m) => m (m a) -> m a
join x = x >>= id
```

Given the following:

`join (+) 10`

armed with the what we know about **Monads**, what is its result?

```
join (+) 10
-- m (m a) -> m a
= (\r -> (\r -> r + r)) 10 -- expanding the Monad for 'r'
= (10 + 10) -- replacing 'r' with 10
= 20
```

We can also use the do syntax to solve the above:

```
let z2 = do
x <- (+)
x
z2 10
= 20
```