Move MonadIO to base

wren ng thornton wren at
Fri Apr 23 21:09:03 EDT 2010

David Menendez wrote:
> On Fri, Apr 23, 2010 at 3:46 PM, Dan Doel <dan.doel at> wrote:
>> Monad m and MonadTrans t do not imply Monad (t m), which is
>> what that definition requires.
> This works for me:
> lift :: (MonadTrans t, Monad m, Monad (t m)) => m a -> t m a
> lift m = morph (\d -> m >>= d . return)

I think the point was that the current definition of lift does not have 
a Monad(t m) constraint and therefore the above definition doesn't 
suffice because it imposes additional requirements. (Granted they're 
desirable requirements, but all the same.)

We don't actually need all of Monad(t m). The only thing we need is some 
general function:

     returnT :: (MonadTrans t, Monad m) => a -> t m a

Though that's not possible, since t is held abstract and MonadTrans only 
offers to construct one if you can provide a function to destruct them. 
So alternatively, we could use morph to construct returnT if only we had 
the general function:

     -- where B is some type associated with the t.
     foo :: (MonadTrans t, Monad m) => t m a -> m B

Which, of course, we can't do either since we don't even know which type 
B is (when t is held abstract).

Thus, the only ways to define lift using morph are:
(1)   add a (Monad (t m)) constraint to morph
(1')  add an (Applicative (t m)) constraint to morph
(1'') define a class for pointed functors and add (Pointed(t m))
(2)   add the returnT function to the MonadTrans class
(3)   add an MPTC/associated type B and the function foo to the 
MonadTrans class
(4)   some similar hackery I've overlooked.

Live well,

More information about the Libraries mailing list