{-# OPTIONS_GHC -fno-warn-redundant-constraints #-} {-# LANGUAGE ExistentialQuantification, RankNTypes #-} -- An interesting interaction of universals and existentials, prompted by -- http://www.haskell.org/pipermail/haskell-cafe/2004-October/007160.html -- -- Note the non-nested pattern-match in runProg; tcfail126 checks the -- nested pattern match module Foo where import Control.Monad.Trans data Bar m = forall t. (MonadTrans t, Monad (t m)) => Bar (t m () -> m ()) (t m Int) data Foo = Foo (forall m. Monad m => Bar m) runProg :: Foo -> IO () runProg (Foo b) = case b of Bar run op -> run (prog op) -- You can't say runProg (Foo (Bar run op)); -- see tcfail126 prog :: (MonadTrans t, Monad (t IO)) => a -> t IO () prog x = error "urk"