Optimus Prime may have been the greatest Transformer, but that’s not what I’m talking ‘bout here. I mean monadic transformers. And having spent some time reading about them and thinking about my next move in the Haskell programming… this is it.
What are monadic transformers? Well, most (let’s be fair: all) Haskell programs will make use of the
IO monad to deal with the outside world. However there’s a number of other instances where monads can be useful — capturing errors, logging progress, maintaining internal state.
There exist separate monads in Standard Library for this stuff:
State, for example. But joining them together can be awkward even though many programs will have use for several of them at once.
One technique would be to build your own über-monad with all the bells and whistles you want. This would be both (a) daft, as the work is already done and (b) too error-prone.
The other technique is with monad transformers. They essentially provide an automated way to do monad nesting — such as
IO (Either [String] [Bool]) — without all the tedious threading of monads. Kind of like a meta-monad, if you will, since you can sequence monads together in the way that monads allow you to sequence functions.
The other nice thing is that it cuts down on those horrible parentheses. Monad actions from different monads can be called back to back without causing a fuss. Example:
f = do a <- get -- from State monad
liftIO $ print a -- from IO monad
tell $ "found a " ++ show a -- from Writer monad
case a `mod` 2 of
0 -> throwError "even number" -- from Error monad
1 -> put $ a+2
I didn’t really understand them until I read the recent paper by Martin Grabmüller, Monad Transformers Step by Step. It’s still in draft at the moment but it’s very readable and dead useful.