
Hello, (This should actually be a reply to the "Move MonadIO to base" thread[1] but I didn't want to break up the extremely interesting discussion on the MonadTransMorph class) Would it be useful if we got rid of MonadIO: class (Monad m) => MonadIO m where liftIO :: IO a -> m a and replace it with the generalization: class (Monad m, Monad n) => MonadBase m n | m -> n where inBase :: n a -> m a which would allow lifting not just IO but any base monad into a stack of monad transformers. It could be implemented as follows: -------------------------------------------------------------------------------------- {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE UndecidableInstances #-} module MonadBase where import Data.Monoid ( Monoid ) import Control.Monad.ST ( ST ) import Control.Monad.Trans.Class ( MonadTrans, lift ) import Control.Monad.Trans.Cont ( ContT ) import Control.Monad.Trans.Error ( ErrorT, Error ) import Control.Monad.Trans.Identity ( IdentityT ) import Control.Monad.Trans.List ( ListT ) import Control.Monad.Trans.Maybe ( MaybeT ) import Control.Monad.Trans.RWS ( RWST ) import Control.Monad.Trans.Reader ( ReaderT ) import Control.Monad.Trans.State ( StateT ) import Control.Monad.Trans.Writer ( WriterT ) class (Monad m, Monad n) => MonadBase m n | m -> n where inBase :: n a -> m a instance MonadBase IO IO where inBase = id instance MonadBase Maybe Maybe where inBase = id instance MonadBase [] [] where inBase = id instance MonadBase (ST s) (ST s) where inBase = id -- etc. -- This would be nice but will cause lots of trouble: -- instance Monad m => MonadBase m m where inBase = id liftInBase :: (MonadTrans t, MonadBase m n) => n a -> t m a liftInBase = lift . inBase instance (MonadBase m n) => MonadBase (ContT r m) n where inBase = liftInBase instance (MonadBase m n) => MonadBase (IdentityT m) n where inBase = liftInBase instance (MonadBase m n) => MonadBase (ListT m) n where inBase = liftInBase instance (MonadBase m n) => MonadBase (MaybeT m) n where inBase = liftInBase instance (MonadBase m n) => MonadBase (ReaderT r m) n where inBase = liftInBase instance (MonadBase m n) => MonadBase (StateT s m) n where inBase = liftInBase instance (MonadBase m n, Error e) => MonadBase (ErrorT e m) n where inBase = liftInBase instance (MonadBase m n, Monoid w) => MonadBase (RWST r w s m) n where inBase = liftInBase instance (MonadBase m n, Monoid w) => MonadBase (WriterT w m) n where inBase = liftInBase {-# DEPRECATED liftIO "Use inBase instead." #-} liftIO :: MonadBase m IO => IO a -> m a liftIO = inBase -------------------------------------------------------------------------------------- I noticed that MonadLib also provides this class[2]. regards Bas [1] http://thread.gmane.org/gmane.comp.lang.haskell.libraries/12877 [2] http://hackage.haskell.org/packages/archive/monadLib/3.6.1/doc/html/MonadLib...