New monads/MonadBase

From HaskellWiki
< New monads
Revision as of 17:10, 24 August 2006 by ChrisKuklewicz (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
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])]