Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How do define a monad transformer that is the composition of two arbitrary monad transformers?

I want to write something similar to the following:

newtype FooT c d m a = FooT { unFooT :: (c (d m)) a }

instance (MonadTrans c, MonadTrans d) => MonadTrans (FooT c d) where
  lift = FooT . lift . lift

However, this snippet will not compile:

Could not deduce (Monad (d m)) arising from a use of ‘lift’

I understand why this won’t compile; we don’t know that the application of an arbitrary transformer d m is itself a monad. However, I’m not sure of the best way to proceed.
Is there a clean way to make something like this work? Presumably it would go through if I could add a constraint along the lines of Monad (d m) to the left-hand-side of the instance declaration, but I don’t know how to do so since m is not bound.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

With the QuantifiedConstraints GHC extension, this is

{-# LANGUAGE QuantifiedConstraints #-}

instance (MonadTrans c, MonadTrans d, forall m. Monad m => Monad (d m)) =>
         MonadTrans (FooT c d) where
  lift = FooT . lift . lift

m in the constraint is not the same m as in lift. The quantified constraint simply means what it says ("for any m :: Type -> Type, if Monad m require Monad (d m)"), and in lift that universal statement is being instantiated with the particular m being passed as argument to lift. Thus lift‘s m does not escape its scope.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading