module M where import Control.Monad (ap, liftM) import Control.Monad.Trans.Class (MonadTrans, lift) newtype ComposeT t1 t2 m a = MkComposeT (t1 (t2 m) a) instance (MonadTrans t1, MonadTrans t2, Monad m) => Monad (ComposeT t1 t2 m) where MkComposeT m >>= f = MkComposeT $ do x <- m let MkComposeT result = f x result instance (MonadTrans t1, MonadTrans t2, Monad m) => Applicative (ComposeT t1 t2 m) where (<*>) = ap pure x = MkComposeT (pure x) instance (MonadTrans t1, MonadTrans t2, Monad m) => Functor (ComposeT t1 t2 m) where fmap = liftM