Reputation: 74234
Suppose we have the following type class.
class MonadTrans t => MonadLower t where
lower :: Monad m => t Identity a -> t m a
As a trivial example, we can implement an instance of MonadLower
for MaybeT
as follows.
instance MonadLower MaybeT where
lower (MaybeT (Identity maybe)) = MaybeT (return maybe)
However, I can't figure out how to implement an instance of MonadLower
for ContT r
.
instance MonadLower (ContT r) where
lower (ContT f) = ContT $ \k -> ???
Is it even possible to create an instance of MonadLower t
for every MonadTrans t
?
If not, which monad transformers (beside ContT r
) can't have MonadLower
instances?
Edit: Edward Kmett has defined a similar type class called MonadHoist
.
class MonadHoist t where
hoist :: (Monad m, Monad n) => (forall a. m a -> n a) -> t m a -> t n a
It turns out that lower = hoist (return . runIdentity)
.
Upvotes: 1
Views: 79
Reputation: 74234
According to Mauro we can't define a MonadHoist
instance for ContT
[1].
What Edward is proposing is to have a class of functorial monad transformers (transformers which are endofunctors in the category Mon(C) of monads over a category C and monad morphisms)
Note that some transformers, like the continuation monad transformer, are not functorial.
Upvotes: 0