3

Given an arbitrary monad, is there a way to create a monad transformer based on that monad? I googled 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 got close, 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 that ToMonadTrans Maybe is the same as MaybeT. The good thing about this approach (if it works) is that you can make any monad into a MonadTrans, allowing one to layer any monad without having to write a corresponding specialised transformer.

As you can see, I implemented MonadTrans as well as Functor and Applicative, the only place I got stuck is Monad.

My questions are:

  1. Can this be done?
  2. Has this been done in a package on hackage?
Clinton
  • 22,361
  • 15
  • 67
  • 163
  • 4
    `ToMonadTrans` is isomorphic to `Compose`. In general cases, the composition of two monads is not a monad. Monad Transformers are just able to somehow do these compositions. – freestyle Jun 15 '17 at 16:06
  • 3
    https://stackoverflow.com/questions/29453915/composing-monads-v-applicative-functors http://blog.tmorris.net/posts/monads-do-not-compose/ – Reactormonk Jun 15 '17 at 16:09
  • 1
    Could you use [FreeT](https://hackage.haskell.org/package/transformers-free-1.0.1/docs/Control-Monad-Trans-Free.html#g:3)? – Mark Seemann Jun 15 '17 at 17:54
  • You cannot do this in general. There is no algorithmic way of taking a definition of a monad (e.g., type and code in Haskell) and producing the type and code of the corresponding transformer. There are at least 4 different classes of monads whose transformers are constructed in completely different ways (composed-inside, composed-outside, adjunction monad, product monad), and there are a few other monads that do not belong to any of these 4 classes. – winitzki May 19 '21 at 10:16

0 Answers0