[Haskell-cafe] Re: Nested Monads Questions

Dan Doel dan.doel at gmail.com
Fri Aug 11 17:49:04 EDT 2006


On 8/11/06, Stefan Aeschbacher <haskell at aeschbacher.ch> wrote:
> I'm trying to understand Monad Transformers. The code below works as
> expected but I have the following questions:
I'll take a shot.

>  - why can I use liftIO but not lift in the doSomething function?
I fooled around a bit, and the answer I came up with is that lift is
only able to lift through the first transformer, while liftIO is able
to lift through them both. You'd need to use something like (lift .
lift).

The difference is in what the parameters to the classes MonadTrans and
MonadIO represent. MonadIO m means that m is a monad into which
IO-actions can be lifted. MonadTrans t means that (t m) is a monad
into which m-actions can be lifted. However, since the type class
doesn't know about m, it's impossible to exprss that composition of
two transformers is itself a transformer, whereas you can easily
declare that the result of transforming a MonadIO with a certain
transformer results in a MonadIO.

It's not immediately clear to me how to express that composition of
transformers results in a transformer even with multi-parameter type
classes, but I'm not a type-hacking guru. I wouldn't be surprised if
it's possible.

>  - why is there no liftSTM function?
Because there is no MonadSTM typeclass specifying which monads can
have STM actions properly lifted into them. You could write your own.
here's a first pass:

    class Monad m => MonadSTM m where
        liftSTM :: STM a -> m a

    instance MonadSTM STM where
        liftSTM = id

    instance (MonadSTM m) => MonadSTM (ReaderT m) where
        liftSTM = lift . liftSTM

    instance (MonadSTM m) => MonadSTM (WriterT m) where
        liftSTM = lift . liftSTM

    Et cetera...

However, I have no idea if there were reasons why such a class was not
included other than simple oversight. It's possible that lifting like
the above may not work like you'd expect, and perhaps it's difficult
to make it do so. But, if you're willing to be a guinea pig, go ahead
and try those out. :)

Enjoy.
-- Dan


More information about the Haskell-Cafe mailing list