[Haskell-cafe] Monad transformers

Evan Laforge qdunkan at gmail.com
Sat Jul 3 19:30:15 EDT 2010


> As I say, every time I've tried to do this, I end up writing a function to
> "run this stuff", and it typically takes a few hours to reach the point
> where it type-checks.

It took me a while the first time, but then I just learned the pattern
and I do it that way every time.  Here's my pattern:

type SomethingStack m = Monad1T Args (Monad2T Args (Monad3T Args m))
newtype SomethingT m a = SomethingT (SomethingStack m a)
  deriving (Functor, Monad, MonadIO, MonadError MyError, KitchenSink)
run_something_t (SomethingT m) = m

run :: (Monad m) => SomethingT m a -> m (a, MonadCrap, MonadCrap, ...)
run = Monad3T.run args . Monad2T.run args . Monad1T.run args . run_something_t

Or if you don't need the polymorphism, just stick a
'Identity.runIdentity' before Monad3T.run and make a

type Something = SomethingT Identity

The tricky bit is that you run them inside-out so the composition
looks like the stack backwards.  And sometimes mtl's 'run' functions
have an inconvenient arg order (e.g. StateT), so you have to flip
them.


More information about the Haskell-Cafe mailing list