
I'm having trouble using an existential type, becasue of what seem to be limitations in how I can express the type. I want values in my existential type to denote, for some monad, a monadic operation and a way to run the monad. Except, I want it mix the operation with operations in another monad, so it use a monad transformer. Specifically: data Foo = forall t. (MonadTrans t) => Foo ((Monad m, Monad (t m)) => t m a -> m a) -- run ((Monad m, Monad (t m)) => t m Int) -- op prog :: Foo -> IO Int prog (Foo run op) = run $ do lift $ putStrLn "Running prog" op ghci gives the error Could not deduce (Monad (t IO)) from the context (MonadTrans t) arising from use of `op' at try.hs:22 Hmm.... I see that my constraints did not mean what I expected. As the "Probable fix" suggests, I can add Monad (t IO) to the existential context to make this code type check, but I want it to work for all monads, not just IO. Something like data Foo = forall t. (MonadTrans t, (forall m. Monad m => Monad (t m))) => Foo ... But I haven't found anything like that. I would also welcome other approaches to this problem. Andrew