m |
m |
| 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 == |
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.
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.