New monads
Revision as of 20:01, 12 August 2006 by HenkJanVanTuyl (talk | contribs)
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.
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])]
MonadLib
This is by Iavor S. Diatchki and can be found at http://www.cse.ogi.edu/~diatchki/monadLib/
It is a new version of the mtl package with transformers: ReaderT WriterT StateT ExceptT SearchT ContT
It also defines BaseM which is like MonadBase above.