Making Monad Transformer from Monad

Given an arbitrary monad, is there a way to create a monad transformer based on this monad? I searched this question and didn't see anywhere where it was addressed (although I may have missed it), so I just tried to do it myself and I came up, I think:

import Control.Monad.Trans.Class (MonadTrans, lift)

newtype ToMonadTrans m2 m1 a = ToMonadTrans (m2 (m1 a))

instance (Functor m2, Functor m1) => Functor (ToMonadTrans m2 m1) where
  fmap f (ToMonadTrans x) = ToMonadTrans (fmap (fmap f) x)

instance (Applicative m2, Applicative m1) => Applicative (ToMonadTrans m2 m1) where
  pure = ToMonadTrans . pure . pure
  ToMonadTrans f <*> ToMonadTrans x = ToMonadTrans (((<*>) . (fmap (<*>))) f x)

instance (Monad m2, Monad m1) => Monad (ToMonadTrans m2 m1) where
  ToMonadTrans x >>= ToMonadTrans f = ToMonadTrans (???)

instance Monad m2 => MonadTrans (ToMonadTrans m2) where
  lift x = ToMonadTrans (pure x)

      

The idea here is what is the ToMonadTrans Maybe

same as MaybeT

. The good thing about this approach (if it works) is that you can make any monad in MonadTrans

, allowing you to add any monad without having to write an appropriate specialized transformer.

As you can see I have implemented MonadTrans

as well Functor

and Applicative

, the only place I am stuck is Monad

.

My questions:

  • Can this be done?
  • Was this done in a hack package?
+3


source to share





All Articles