
On Sun, Apr 18, 2010 at 5:02 PM, wren ng thornton
Heinrich Apfelmus wrote:
Anders Kaseorg wrote:
This concept can also be generalized to monad transformers:
class MonadTrans t => MonadTransMorph t where morph :: Monad m => (forall b. (t m a -> m b) -> m b) -> t m a
[...] However, not all control operators can be lifted this way. Essentially, while you may "downgrade" an arbitrary selection of t m a values you may only promote one m a in return and all have to share the same return type a . In particular, it's not possible to implement
lift :: (Monad m, MonadTrans t) => m a -> t m a
Why not? * morph says m(t m a) is a subset of (t m a) * Monad m says we can fmap :: (a->b) -> (m a->m b) * Monad (t m) says we can return :: a -> t m a
lift ma = morph (\k -> k (fmap return ma))
Maybe something like this? lift m = morph (\k -> m >>= k . return) -- n.b., return and >>= are from different monads
Again, having m(t m a)->(t m a) is strictly more expressive than only having (m a)->(t m a) because the former may avail itself of operations/operators of t.
join . lift :: m (t m a) -> t m a
morph is more powerful than lift, but it isn't because of the type.
--
Dave Menendez