The Reader monad is a monad transformer with the purpose of providing an environment. We use the monad transformer ReaderT :: r m a, which is defined in the Control.Monad.Reader module. In the mtl library, usually, each transformer has an associated type class. The transformer ReaderT is an instance of MonadReader type class:
class Monad m => MonadReader r (m :: * -> *) | m -> r where
ask :: m r
local :: (r -> r) -> m a -> m a
reader :: (r -> a) -> m a
A special monad called Identity exists in Data.Functor.Identity, which is the simplest monad. Its only purpose is to embed a pure value into a monad. The Reader monad is defined as ReaderT with Identity as an embedded monad:
type Reader r = ReaderT r Identity
MonadReader provides three functions. The ask :: MonadReader r m => m r function gets the current environment. The function asks :: MonadReader r m => (r -> a) -> m a can be used to use a function that takes the current environment and produces some value that can be used in the context of the monad.
The function local is special, as shown here:
local :: MonadReader r m => (r -> r) -> m a -> m a
It takes a function that produces another environment. The supplied computation is executed under the modified environment. However, the current environment is unaffected.