# A Simple Reader Monad Example

What is a Reader Monad?

The Reader Monad works within the context of a shared environment. But what does that mean? Say you needed some shared object to execute a bunch of functions. An example could be that you need a database connection in every query function you execute. Or it could be some configuration options read from a file that are needed across a number of functions.

When trying to learn about the Reader Monad I’ve found most examples are convoluted or unnecessarily long. I hope to change that by providing a simple example that you can try out without too much head-spinning.

The Reader Monad is defined as:

`type Reader r = ReaderT r Identity`

One of the time-consuming things about learning the Reader Monad is that it is defined in terms of the ReaderT transformer (which is also a Monad). So now you have to learn multiple monads just to understand the Reader Monad. Annoying.

Let’s ignore the ReaderT transformer for now and assume that Reader is defined as:

`Reader r a`

where r is some “environment” and a is some value you create from that environment. And thanks to the type alias above you can just about do that.

Because Reader is a Monad we can do stuff like this:

```
import Control.Monad.Reader
let r1 = return 5 :: Reader String Int
```

We have created a simple Reader using the Monad’s **return** function.

If we check the type of r1:

```
:t r1
r1 :: Reader String Int
```

We see that we have created a Reader that takes in a String and returns an Int. The String is the “environment” of the Reader. So how can we get the Int value out of the reader? By running it of course! We can use the **runReader** function to do that:

```
(runReader r1) "this is your environment"
5
```

**runReader** is defined as:

`runReader :: Reader r a -> r -> a`

So **runReader** takes in a Reader and an environment (**r**) and returns a value (**a**).

*Now notice that we didn’t really do anything with the environment supplied to us.*

What if we had a bunch of Readers and we wanted to **bind** across them?

```
import Control.Monad.Reader
tom :: Reader String String
tom = do
env <- ask -- gives you the environment which in this case is a String
return (env ++ " This is Tom.")
jerry :: Reader String String
jerry = do
env <- ask
return (env ++ " This is Jerry.")
tomAndJerry :: Reader String String
tomAndJerry = do
t <- tom
j <- jerry
return (t ++ "\n" ++ j)
runJerryRun :: String
runJerryRun = (runReader tomAndJerry) "Who is this?"
```

The ask function is defined on MonadReader.

`class Monad m => MonadReader r m | m -> r where`

Let’s ignore MonadReader for now and focus on the definition of the ask function:

`ask :: m r`

Basically the above gives you a Reader Monad with the environment in it. So if you need access to the environment you ask for it. :)

In the **tom**, **jerry** and **tomAndJerry** functions, we are working within the context of the Reader Monad. That allows us to **bind** to the environment within the Reader. It also means that we need to **return** all values within a new Reader as well.

The **tomAndJerry** function binds to values from each Reader and then returns them combined in another Reader. We then run the whole lot in the **runJerryRun** function with the help of **runReader** and get the following output:

```
Who is this? This is Tom.
Who is this? This is Jerry.
```

I hope this simple example is useful in getting you started in using and thinking about the Reader Monad.