Understanding Monad Transformers

You’ve read about a bunch of monads and that each one of them has a particular role to fulfill, then you start using them and soon realize that one monad at a time is just a one-off trick.

Enter monad transformers. Many different effects combined, that must be the way to go. You read the analogy with the onion and its layers: it’s fascinating, there are trivial examples around that all make a lot of sense. But putting the onion at work on a real case of yours is another story. How can you make then knowledge stick?

So you turn to the standard Haskell libraries, like mtl, but not even this helps understand what’s going on: every layer of the onion is a MonadRead, a MonadState, a MonadWrite and a MonadCont at the same time; you can use almost any canonical function at every level. So you get sloppy, neglect to lift until GHC strikes back with some extremely long and obscure error message.

This is a series of posts that illustrate from the ground up (no libraries imported) the beautiful details of monad transformers in Haskell applied to a non-trivial use case: an expression interpreter. They require a minimal familiarity with Haskell syntax, but nothing more than that. All the code here runs in GHC and it is to be found on GitHub, fully equipped with tests.

Be brave, start with the first post