# Understanding the Reader monad

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.

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
```