# Difference between revisions of "New monads"

From HaskellWiki

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

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

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