# 'Understanding the Reader monad

I'm reading *PureScript by Example* and got to the part introducing the Reader monad. The example goes like this:

```
createUser :: Reader Permissions (Maybe User)
createUser = do
permissions <- ask
if hasPermission "admin" permissions
then map Just newUser
else pure Nothing
```

The confusing part for me is the `ask`

function. The signature is:

```
ask :: forall r. Reader r r
```

It appears as if it creates a Reader out of thin air 😐

When I was reading about the `State`

monad, it had the same concept with its `get`

function. And the text explained:

*the state is implemented as a function argument hidden by the State monad’s data constructor, so there is no explicit reference to pass around.*

I'm guessing this is the key, and the same thing is happening here with the Reader, but I don't understand how it works...

When the above example is run via `runReader`

, how does the provided value suddenly appear as a result of `ask`

? The Haskell docs for `ask`

say: *Retrieves the monad environment.* But my confusion is *from where*? The way I see it, a value gets passed to `runReader`

, gets stored *somewhere*, and to get it - you call `ask`

... but that makes no sense.

While the example is PureScript, I'm guessing any Haskell-literate person would also be able to answer, hence the Haskell tag.

## Solution 1:^{[1]}

I don't have a PureScript environment around currently, so I'll try to answer from a Haskell perspective, and hope it helps.

A *Reader* is really only a 'wrapper' around a function, so when you get a `Reader r r`

, you really only get a reader from `r`

to `r`

; in other words, a function `r -> r`

.

You *can* summon functions out of thin air, because, if you're a Platonist, I suppose they always exist...

When you use `do`

notation, you're 'inside the monad', so the context `r`

is implicit. In other words, you call a function that returns the `r`

value, and when you use the `<-`

arrow, you simply get that context.

## Solution 2:^{[2]}

You can convince yourself that it works by performing a few substitutions. First look at the signature of `createUser`

. Let's "unroll" the definition of `Reader`

:

```
createUser :: Reader Permissions (Maybe User)
{- definition of Reader -}
createUser :: ReaderT Permissions Identity (Maybe User)
```

The `ReaderT`

type only has one data constructor: `ReaderT (r -> m a)`

, which means `createUser`

is a term that evaluates to a value of type `ReaderT (Permissions -> Identity (Maybe User))`

. As you can see, it is just a function tagged with `ReaderT`

. It does not have to create anything out of thin air, but will receive the value of type `Permissions`

when that function is called.

Now let's look at the line you are having trouble with. You know that the `do`

notation is just syntactic sugar, and the expression:

```
do permissions <- ask
if hasPermission "admin" permissions
then map Just newUser
else pure Nothing
```

desugars to

```
ask >>= \permissions ->
if hasPermission "admin" permissions
then map Just newUser
else pure Nothing
```

To understand what this does, you will have to lookup the definition of `ask`

, `>>=`

and `pure`

for `ReaderT`

. Let's perform another round of substitutions:

```
ask >>= \permissions -> ...
{- definition of ask for ReaderT -}
ReaderT pure >>= \permissions -> ...
{- definition of >>= for ReaderT -}
ReaderT \r ->
pure r >>= \a -> case (\permissions -> ...) a of ReaderT f -> f r
{- function application -}
ReaderT \r ->
pure r >>= \a ->
case (if hasPermission "admin" a
then map Just newUser
else pure Nothing) of ReaderT f -> f r
{- definition of pure for Identity -}
ReaderT \r ->
Identity r >>= \a ->
case (if hasPermission "admin" a
then map Just newUser
else pure Nothing) of ReaderT f -> f r
{- definition of >>= for Identity -}
ReaderT \r ->
(\a ->
case (if hasPermission "admin" a
then map Just newUser
else pure Nothing) of ReaderT f -> f r) r
{- function application -}
ReaderT \r ->
case (if hasPermission "admin" r
then map Just newUser
else pure Nothing) of ReaderT f -> f r
```

As you can see, `createUser`

is clearly just a function wrapped by `ReaderT`

that threads a value (the "environment") through your expressions. `runReader`

unwraps the function and calls it with the provided argument:

```
runReader :: forall r a. Reader r a -> r -> a
runReader (ReaderT f) r = f r
```

## Solution 3:^{[3]}

The partial function type `(->) r`

is a functor i.e. `r->a`

is a container for any type `a`

(a `List a`

of size two is equivalent to a function `Bool->a`

) . Moreover, it is also a monad

```
instance Monad ((->) r) where
f >>= k = \ r -> k (f r) r
```

It satisfies the `MonadReader`

type class and is called the simple reader monad and might be given the type synonym `Reader r`

.

`ask`

returns this monad `(->) r) r`

applied to the same type `r`

, which we then can bind.

Understand the partial function type `(->) r`

better.

## Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution | Source |
---|---|

Solution 1 | Mark Seemann |

Solution 2 | Regis Kuckaertz |

Solution 3 |