When we combine monad transformers, we embed one type into another. For example, for our current recipe, the type is shown here:
ReaderT Cursor (WriterT Cursor IO) ()
It can be read as follows:
- The innermost monad is IO.
- WriterT embeds IO into it. The writer state is the Cursor.
- ReaderT embeds WriterT (and IO) monads. The ReaderT has the environment Cursor.
- Essentially, we start from the innermost monad and keep wrapping it with another monad.
To run the preceding monad, we have unwrapped the outer most monad first. Here, is our example:
- Outermost monad is ReaderT. We will unwrap it with runReaderT.
- Then next monad is WriterT. We will unwrap it with runWriterT.
- The IO monad actions are embedded innermost. When we unwrap ...