Why isn't lift's return value constrained to be a monad?
haskell, monad-transformers, monads, typeclass
Solution
My guess is that a `MonadTrans` transforms a `Monad` into something else, instead of transforming a `Monad` into a `Monad`. It's more generalized, since you might write something that transforms a `Monad` and you can define `lift`, but you can't define `>>=` and `return`. Since most (if not all) `MonadTrans` instances end up being `Monad`s, it doesn't really present a problem as the compiler still handles it just fine.
Problem
Why isn't `MonadTrans` defined as ``` class MonadTrans t where lift :: (Monad m, Monad (t m)) => m a -> t m a -- ^^^^^^^^^^^ ``` instead of current ``` class MonadTrans t where lift :: Monad m => m a -> t m a ``` This is Haskell 98 (unlike the suggestion in Why aren't monad transformers constrained to yield monads?) and ensures that the result will always be a monad. Is there a reason why monad transformers are allowed to produce something that isn't a monad?