The Reader monad is used to pass one value as an argument to a number of function calls. This can be useful when you require some configuration or environment information accessible from a block of functions.

This monad is provided in Haskell’s standard libraries, but let’s have a go at creating it ourselves.

## A sample problem

Say we have a `Person`

data type with a `name`

, `age`

and `address`

, and we want to write a `showPerson`

function to display these details in a string.

Notice how we need to pass the `person`

argument around everywhere? It would be nice to be able to have all this run in the context of a particular `person`

, and that’s what the Reader monad lets us do.

Rather than having the `x`

, `y`

, and `z`

parts of the `showPerson`

function each evaluating to a string, how about we instead treat them as functions of type `Person -> String`

. We’d like to compose all these together and return a value which is a combination of the previous results, which sounds like something we can use a monad for.

## Implementing a monad for single argument functions

Rather than the specific `Person -> String`

functions from the example, we can look at the general case of a function `r -> a`

, or a function that reads some value of type `r`

and returns some other value. We are interested in the `r ->`

bit, but Haskell won’t let us do that. Instead we need to write it as `(->) r`

.

**Aside:**In Haskell we can move an operator from infix position such as

`1 + 2`

to prefix position as `(+) 1 2`

. This is just what we’ve done in moving `r -> a`

to `(->) r a`

.
All monads are functors, so let’s implement that first:

We can follow the same trail of types to implement the monad type class:

We can now rewrite our `showPerson`

example by binding together the functions that read the `Person`

information using `>>=`

:

Alternatively we can use Haskell’s do-notation. (The two forms are equivalent; Haskell will turn this into the same code as the above snippet, but do-notation tends to look neater.)

## Built-in reader

We can import Control.Monad.Reader to make our `showPerson`

examples compile without having to define the reader implementation ourselves.

This implementation also provides a `Reader`

type and `ReaderT`

monad transformer, along with `ask`

, `asks`

, and `local`

functions to access the passed in environment, and a `runReader`

function to pass an environment to a `Reader`

and get the result. I haven’t had a need for these yet, but thought I’d mention them as they crop up in examples all the time. (I’m guessing these functions are most useful when using reader with monad transformers, but I’m still trying to work those out. :))