Personal tools

New monads

From HaskellWiki

(Difference between revisions)
Jump to: navigation, search
m
m (MonadBase)
Line 3: Line 3:
 
== MonadBase ==
 
== 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.
+
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. View [[MonadBase]].
 
+
<haskell>
+
-- 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
+
</haskell>
+
 
+
And an artificial example:
+
 
+
<haskell>
+
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"
+
</haskell>
+
 
+
<pre>
+
*Main> test
+
[("hello1",[2]),("hello2",[3]),("hello3",[4])]
+
</pre>
+
 
+
  
 
== MonadLib ==
 
== MonadLib ==

Revision as of 17:10, 24 August 2006

Contents


1 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. View MonadBase.

2 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.