Aadit M Shah
Aadit M Shah

Reputation: 74234

Is it possible to write a function of the type `Monad m => t Identity a -> t m a` for every monad transformer `t`?

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

Answers (1)

Aadit M Shah
Aadit M Shah

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

Related Questions