# Reader Monad

Suppose we have a function that requires knowing the environment

```
start :: Env -> ...
```

It will be pretty common to require this throughout the code.

```
startLogger :: Env -> ...
startDatabase :: Env -> ...
```

Considering that we only need read access to the environment, we can use the reader monad

```
data Reader r a = Reader (r -> a)
instance Monad (Reader r) where
return a = ReaderG $ \_ -> a
(>>=) :: (r -> a) -> (a -> r -> b) -> (r -> b)
ReaderG f >>= g = ReaderG $ \r -> let a = f r
f' = g a
in f' r
```

Observe that the variable `r`

passed into both functions `f`

, `f'`

is the same.

This shows that we reuse the same `r`

value, which could be the environment, a configuration and so on.

This is used as a READ-only value. We cannot update it, as again `(>>=)`

only gives us `a`

.

This allows us to do things like the following

```
-- Get environment
ask :: Reader r r
-- Modify local environment
local :: (r -> r) -> Reader r a -> Reader r a
main :: Reader r r
main = do
r <- ask -- ^ Access to the `r` value
return r
-- equivalent to
main2 :: Reader r r
main2 = ask >>= \r -> return r -- ^ return expanded here for similarity with main
```

What if we want both `READ/WRITE`

?

We can use the State Monad^{ᛦ} which combines the ideas of the `Reader`

and `Writer`

monads

References: hackage