Why runXXX is not part of MonadTrans definition?
haskell, monad-transformers
Solution
There is no universal interface for running monad transformers. For example, try running `LogicT` or `ContT` or `FreeT` using your interface.
Even if you could generalize your interface to handle all of these example, you would still be missing the key ingredient: laws. Type class methods should obey equations that allow you to reason about code that uses the type class interface without consulting the source of specific instances. For example, the `lift` method from `MonadTrans` must obey these to laws:
lift (return x) = return x
lift (m >>= f) = lift m >>= \x -> lift (f x)
There are nice theoretical reasons why `lift` should obey these laws, which become more apparent if you write the laws in this point-free style:
(lift .) return = return -- fmap id = id
(lift .) (f >=> g) = (lift .) f >=> (lift .) g -- fmap (f . g) = fmap f . fmap g
In other words, `(lift .)` is a functor between two kleisli categories and `lift` is therefore a monad morphism.
A lot of thought goes into defining type classes like `Functor`, `Monad`, and `MonadTrans`, and the Typeclassopedia is a great place to start learning more about this topic.
Problem
The `MonadTrans` document says: Each monad transformer also comes with an operation runXXX to unwrap the transformer, exposing a computation of the inner monad. So I wonder why `MonadTrans` is not defined as ``` class MonadTrans t where type p :: * type r :: * -> * lift:: Monad m => m a -> t m a run :: t m a -> p -> m (r a) ``` to eliminate the above clause? Is that the above definition not generic enough? If so, which monad transformer does not fit for this definition? UPDATE Adjusted a little bit to enable different result type.