New monads/MonadBase
< New monads
Jump to navigation
Jump to search
Revision as of 15:57, 7 October 2006 by BrettGiles (talk | contribs) (NewMonads/MonadBase moved to New monads/MonadBase)
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
From NewMonads
MonadBase
It seems that the liftIO function from MonadIO can be generalized to access whatever the base of a transformer stack happens to be. So there is no need for a liftSTM, liftST, etc.
-- By Chris Kuklewicz
module MonadBase(MonadBase,liftBase,MonadIO',liftIO') where
import Data.Monoid(Monoid)
import Control.Monad.Trans(lift,MonadTrans)
-- All the base monads with GHC
import Control.Monad.ST.Strict as S(ST)
import Control.Monad.ST.Lazy as L(ST)
import Control.Concurrent.STM(STM)
import Control.Monad.Identity(Identity)
import Text.ParserCombinators.Parsec(GenParser)
-- And all the MonadIO instances:
import Control.Monad.List(ListT)
import Control.Monad.Cont(ContT)
import Control.Monad.Error(ErrorT,Error)
import Control.Monad.Reader(ReaderT)
import Control.Monad.State(StateT)
import Control.Monad.Writer(WriterT)
import Control.Monad.RWS(RWST)
class (Monad m,Monad b) => MonadBase b m where
liftBase :: b a -> m a
-- One can recover MonadIO and liftIO from MonadBase
class (MonadBase IO m) => MonadIO' m where
liftIO' :: IO a -> m a
liftIO' = liftBase
-- Base monads
instance MonadBase IO IO where liftBase = id
instance MonadBase STM STM where liftBase = id
instance MonadBase (GenParser tok st) (GenParser tok st) where liftBase = id
instance MonadBase (S.ST s) (S.ST s) where liftBase = id
instance MonadBase (L.ST s) (L.ST s) where liftBase = id
instance MonadBase Maybe Maybe where liftBase = id
instance MonadBase [] [] where liftBase = id
instance (Error e) => MonadBase (Either e) (Either e) where liftBase = id
instance MonadBase ((->) a) ((->) a) where liftBase = id
instance MonadBase Identity Identity where liftBase = id
-- Trans monads
instance MonadBase b m => MonadBase b (ListT m) where
liftBase = lift . liftBase
instance MonadBase b m => MonadBase b (ContT r m) where
liftBase = lift . liftBase
instance (Error e, MonadBase b m) => MonadBase b (ErrorT e m) where
liftBase = lift . liftBase
instance MonadBase b m => MonadBase b (ReaderT r m) where
liftBase = lift . liftBase
instance MonadBase b m => MonadBase b (StateT s m) where
liftBase = lift . liftBase
instance (Monoid w, MonadBase b m) => MonadBase b (WriterT w m) where
liftBase = lift . liftBase
instance (Monoid w, MonadBase b m) => MonadBase b (RWST r w s m) where
liftBase = lift . liftBase
And an artificial example:
module Main where
import MonadBase
import Control.Monad.Reader
import Control.Monad.Writer
type Foo a = (WriterT [Int] (ReaderT String [])) a
foo :: Foo String
foo = do
x <- liftBase [1,2,3]
s <- ask
tell [succ x]
return (s ++ show x)
test = runReaderT (runWriterT foo) "hello"
*Main> test [("hello1",[2]),("hello2",[3]),("hello3",[4])]