| Copyright | (c) Andy Gill 2001, (c) Oregon Graduate Institute of Science and Technology, 2001, (C) 2015 KONISHI Yohsuke |
|---|---|
| License | BSD-style (see the file LICENSE) |
| Maintainer | ocean0yohsuke@gmail.com |
| Stability | experimental |
| Portability | --- |
| Safe Haskell | Safe |
| Language | Haskell2010 |
DeepControl.Monad.Trans
Contents
Description
This module enables you to program in Monad-Transformer style for more deeper level than the usual Control.Monad.Trans module expresses.
You would realize exactly what more deeper level means by reading the example codes, which are attached on the page bottom.
Note: many instances for Level-4 and Level-5 haven't been written yet.
- class Monad m => MonadIO m where
- class MonadTrans t where
- class (Monad (TransDown t1), MonadTrans t1) => MonadTransDown t1 where
- type TransDown t1 :: * -> *
- type M t1 = TransDown t1
- class MonadTransDown t1 => MonadTransCover t1 where
- class MonadTrans_ t1 where
- class MonadTrans2 t where
- class (MonadTrans (Trans2Down t2), MonadTrans2 t2) => MonadTrans2Down t2 where
- type Trans2Down t2 :: (* -> *) -> * -> *
- type M_ t2 = TransDown (Trans2Down t2)
- type T_ t2 = Trans2Down t2
- class (MonadTrans (T_ t), MonadTrans2 t) => MonadTransFold2 t where
- transfold2 :: (Monad m1, Monad (t2 m1), MonadTrans_ t2) => t m1 (TransDown t2) a -> T_ t (t2 m1) a
- untransfold2 :: (Monad m1, Monad (t2 m1), MonadTrans_ t2) => T_ t (t2 m1) a -> t m1 (TransDown t2) a
- class MonadTransCover (Trans2Down t2) => MonadTransCover2 t2 where
- (|-*|) :: (Monad m1, Monad2 m2) => Trans2Down t2 m1 a -> t2 m1 m2 a
- (|*-|) :: (Monad m1, Monad2 m2) => Trans2Down t2 m2 a -> t2 m1 m2 a
- (|**|) :: (Monad m1, Monad2 m2, MonadTransCover2 t2) => M_ t2 a -> t2 m1 m2 a
- trans2 :: (Monad m1, Monad (t2 m1), MonadTrans_ t2, MonadTrans_ t3) => m1 (TransDown t2 (TransDown t3 a)) -> t3 (t2 m1) a
- untrans2 :: (Monad m1, Monad (t2 m1), MonadTrans_ t2, MonadTrans_ t3) => t3 (t2 m1) a -> m1 (TransDown t2 (TransDown t3 a))
- class MonadTrans3 t where
- class (MonadTrans2 (Trans3Down t3), MonadTrans3 t3) => MonadTrans3Down t3 where
- type Trans3Down t3 :: (* -> *) -> (* -> *) -> * -> *
- type M__ t3 = M_ (Trans3Down t3)
- type T__ t3 = T_ (Trans3Down t3)
- class (MonadTrans (T__ t), MonadTrans3 t) => MonadTransFold3 t where
- transfold3 :: (Monad m1, Monad (t2 m1), Monad (t3 (t2 m1)), MonadTrans t3, MonadTrans t2, MonadTrans_ t2, MonadTrans_ t3) => t m1 (TransDown t2) (TransDown t3) a -> T__ t (t3 (t2 m1)) a
- untransfold3 :: (Monad m1, Monad (t2 m1), Monad (t3 (t2 m1)), MonadTrans t3, MonadTrans t2, MonadTrans_ t2, MonadTrans_ t3) => T__ t (t3 (t2 m1)) a -> t m1 (TransDown t2) (TransDown t3) a
- class MonadTransCover2 (Trans3Down t3) => MonadTransCover3 t3 where
- (|--*|) :: (Monad m1, Monad2 m2, Monad3 m3) => Trans3Down t3 m1 m2 a -> t3 m1 m2 m3 a
- (|-*-|) :: (Monad m1, Monad2 m2, Monad3 m3) => Trans3Down t3 m1 m3 a -> t3 m1 m2 m3 a
- (|*--|) :: (Monad m1, Monad2 m2, Monad3 m3) => Trans3Down t3 m2 m3 a -> t3 m1 m2 m3 a
- (|***|) :: (Monad m1, Monad2 m2, Monad3 m3, MonadTransCover3 t3) => M__ t3 a -> t3 m1 m2 m3 a
- (|-**|) :: (Monad m1, Monad2 m2, Monad3 m3, MonadTransCover3 t3) => T__ t3 m1 a -> t3 m1 m2 m3 a
- (|*-*|) :: (Monad m1, Monad2 m2, Monad3 m3, MonadTransCover3 t3) => T__ t3 m2 a -> t3 m1 m2 m3 a
- (|**-|) :: (Monad m1, Monad2 m2, Monad3 m3, MonadTransCover3 t3) => T__ t3 m3 a -> t3 m1 m2 m3 a
- trans3 :: (Monad m1, Monad (t3 (t2 m1)), Monad (t2 m1), MonadTrans_ t2, MonadTrans_ t3, MonadTrans_ t4) => m1 (TransDown t2 (TransDown t3 (TransDown t4 a))) -> t4 (t3 (t2 m1)) a
- untrans3 :: (Monad m1, Monad (t3 (t2 m1)), Monad (t2 m1), MonadTrans_ t2, MonadTrans_ t3, MonadTrans_ t4) => t4 (t3 (t2 m1)) a -> m1 (TransDown t2 (TransDown t3 (TransDown t4 a)))
- class MonadTrans4 t where
- class MonadTrans5 t where
MonadIO
class Monad m => MonadIO m where
Monads in which IO computations may be embedded.
Any monad built by applying a sequence of monad transformers to the
IO monad will be an instance of this class.
Instances should satisfy the following laws, which state that liftIO
is a transformer of monads:
Instances
| MonadIO IO | |
| MonadIO m => MonadIO (ListT m) | |
| MonadIO m => MonadIO (MaybeT m) | |
| MonadIO m => MonadIO (IdentityT m) | |
| MonadIO m => MonadIO (ContT r m) | |
| MonadIO m => MonadIO (ReaderT r m) | |
| MonadIO m => MonadIO (StateT s m) | |
| MonadIO m => MonadIO (StateT s m) | |
| MonadIO m => MonadIO (ExceptT e m) | |
| (Error e, MonadIO m) => MonadIO (ErrorT e m) | |
| (Monoid w, MonadIO m) => MonadIO (WriterT w m) | |
| (Monoid w, MonadIO m) => MonadIO (WriterT w m) | |
| (MonadIO m1, Monad m1, Monad2 m2) => MonadIO (ReaderT2 r m1 m2) | |
| (MonadIO m1, Monad m1, Monad2 m2) => MonadIO (StateT2 s m1 m2) | |
| (Monoid w, MonadIO m) => MonadIO (RWST r w s m) | |
| (Monoid w, MonadIO m) => MonadIO (RWST r w s m) | |
| (MonadIO m1, Monad m1, Monad2 m2, Monad3 m3) => MonadIO (ReaderT3 r m1 m2 m3) | |
| (MonadIO m1, Monad m1, Monad2 m2, Monad3 m3) => MonadIO (StateT3 s m1 m2 m3) | |
| (Monoid w, MonadIO m1, Monad m1, Monad2 m2) => MonadIO (RWST2 r w s m1 m2) | |
| (Monoid w, MonadIO m1, Monad m1, Monad2 m2, Monad3 m3) => MonadIO (RWST3 r w s m1 m2 m3) |
MonadTrans
Level-1
class MonadTrans t where
The class of monad transformers. Instances should satisfy the
following laws, which state that lift is a monad transformation:
Methods
lift :: Monad m => m a -> t m a
Lift a computation from the argument monad to the constructed monad.
Instances
| MonadTrans ListT | |
| MonadTrans MaybeT | |
| MonadTrans IdentityT | |
| MonadTrans (ContT r) | |
| MonadTrans (ReaderT r) | |
| MonadTrans (StateT s) | |
| MonadTrans (StateT s) | |
| MonadTrans (ExceptT e) | |
| Error e => MonadTrans (ErrorT e) | |
| Monoid w => MonadTrans (WriterT w) | |
| Monoid w => MonadTrans (WriterT w) | |
| Monoid w => MonadTrans (RWST r w s) | |
| Monoid w => MonadTrans (RWST r w s) |
class (Monad (TransDown t1), MonadTrans t1) => MonadTransDown t1 Source
Instances
cover
class MonadTransDown t1 => MonadTransCover t1 where Source
Instances
other
class MonadTrans_ t1 where Source
Required only for and MonadTransFold2MonadTransFold3
Methods
trans :: Monad m2 => m2 (TransDown t1 a) -> t1 m2 a Source
untrans :: Monad m2 => t1 m2 a -> m2 (TransDown t1 a) Source
Instances
Level-2
class MonadTrans2 t where Source
Instances
| MonadTrans2 (ReaderT2 r) Source | |
| MonadTrans2 (StateT2 s) Source | |
| Monoid w => MonadTrans2 (RWST2 r w s) Source |
class (MonadTrans (Trans2Down t2), MonadTrans2 t2) => MonadTrans2Down t2 Source
Associated Types
type Trans2Down t2 :: (* -> *) -> * -> * Source
Instances
| MonadTrans2Down (ReaderT2 r) Source | |
| MonadTrans2Down (StateT2 s) Source | |
| Monoid w => MonadTrans2Down (RWST2 r w s) Source |
type M_ t2 = TransDown (Trans2Down t2) Source
type T_ t2 = Trans2Down t2 Source
fold
class (MonadTrans (T_ t), MonadTrans2 t) => MonadTransFold2 t where Source
Following property holds.
untransfold2 . transfold2 == id
Methods
transfold2 :: (Monad m1, Monad (t2 m1), MonadTrans_ t2) => t m1 (TransDown t2) a -> T_ t (t2 m1) a Source
untransfold2 :: (Monad m1, Monad (t2 m1), MonadTrans_ t2) => T_ t (t2 m1) a -> t m1 (TransDown t2) a Source
Instances
| MonadTransFold2 (ReaderT2 r) Source | |
| MonadTransFold2 (StateT2 s) Source | |
| Monoid w => MonadTransFold2 (RWST2 r w s) Source |
cover
class MonadTransCover (Trans2Down t2) => MonadTransCover2 t2 where Source
Methods
(|-*|) :: (Monad m1, Monad2 m2) => Trans2Down t2 m1 a -> t2 m1 m2 a infixl 3 Source
(|*-|) :: (Monad m1, Monad2 m2) => Trans2Down t2 m2 a -> t2 m1 m2 a infixl 3 Source
Instances
| MonadTransCover2 (ReaderT2 r) Source | |
| MonadTransCover2 (StateT2 w) Source | |
| Monoid w => MonadTransCover2 (RWST2 r w s) Source |
other
trans2 :: (Monad m1, Monad (t2 m1), MonadTrans_ t2, MonadTrans_ t3) => m1 (TransDown t2 (TransDown t3 a)) -> t3 (t2 m1) a Source
untrans2 :: (Monad m1, Monad (t2 m1), MonadTrans_ t2, MonadTrans_ t3) => t3 (t2 m1) a -> m1 (TransDown t2 (TransDown t3 a)) Source
Level-3
class MonadTrans3 t where Source
Instances
| MonadTrans3 (ReaderT3 r) Source | |
| MonadTrans3 (StateT3 s) Source | |
| Monoid w => MonadTrans3 (RWST3 r w s) Source |
class (MonadTrans2 (Trans3Down t3), MonadTrans3 t3) => MonadTrans3Down t3 Source
Associated Types
type Trans3Down t3 :: (* -> *) -> (* -> *) -> * -> * Source
Instances
| MonadTrans3Down (ReaderT3 r) Source | |
| MonadTrans3Down (StateT3 s) Source | |
| Monoid w => MonadTrans3Down (RWST3 r w s) Source |
type M__ t3 = M_ (Trans3Down t3) Source
type T__ t3 = T_ (Trans3Down t3) Source
fold
class (MonadTrans (T__ t), MonadTrans3 t) => MonadTransFold3 t where Source
Following property holds.
untransfold3 . transfold3 == id
Methods
transfold3 :: (Monad m1, Monad (t2 m1), Monad (t3 (t2 m1)), MonadTrans t3, MonadTrans t2, MonadTrans_ t2, MonadTrans_ t3) => t m1 (TransDown t2) (TransDown t3) a -> T__ t (t3 (t2 m1)) a Source
untransfold3 :: (Monad m1, Monad (t2 m1), Monad (t3 (t2 m1)), MonadTrans t3, MonadTrans t2, MonadTrans_ t2, MonadTrans_ t3) => T__ t (t3 (t2 m1)) a -> t m1 (TransDown t2) (TransDown t3) a Source
Instances
| MonadTransFold3 (ReaderT3 r) Source | |
| MonadTransFold3 (StateT3 s) Source | |
| Monoid w => MonadTransFold3 (RWST3 r w s) Source |
cover
class MonadTransCover2 (Trans3Down t3) => MonadTransCover3 t3 where Source
Methods
(|--*|) :: (Monad m1, Monad2 m2, Monad3 m3) => Trans3Down t3 m1 m2 a -> t3 m1 m2 m3 a infixl 3 Source
(|-*-|) :: (Monad m1, Monad2 m2, Monad3 m3) => Trans3Down t3 m1 m3 a -> t3 m1 m2 m3 a infixl 3 Source
(|*--|) :: (Monad m1, Monad2 m2, Monad3 m3) => Trans3Down t3 m2 m3 a -> t3 m1 m2 m3 a infixl 3 Source
Instances
| MonadTransCover3 (ReaderT3 r) Source | |
| MonadTransCover3 (StateT3 s) Source | |
| Monoid w => MonadTransCover3 (RWST3 r w s) Source |
(|***|) :: (Monad m1, Monad2 m2, Monad3 m3, MonadTransCover3 t3) => M__ t3 a -> t3 m1 m2 m3 a infixl 3 Source
(|-**|) :: (Monad m1, Monad2 m2, Monad3 m3, MonadTransCover3 t3) => T__ t3 m1 a -> t3 m1 m2 m3 a infixl 3 Source
(|*-*|) :: (Monad m1, Monad2 m2, Monad3 m3, MonadTransCover3 t3) => T__ t3 m2 a -> t3 m1 m2 m3 a infixl 3 Source
(|**-|) :: (Monad m1, Monad2 m2, Monad3 m3, MonadTransCover3 t3) => T__ t3 m3 a -> t3 m1 m2 m3 a infixl 3 Source
other
trans3 :: (Monad m1, Monad (t3 (t2 m1)), Monad (t2 m1), MonadTrans_ t2, MonadTrans_ t3, MonadTrans_ t4) => m1 (TransDown t2 (TransDown t3 (TransDown t4 a))) -> t4 (t3 (t2 m1)) a Source
untrans3 :: (Monad m1, Monad (t3 (t2 m1)), Monad (t2 m1), MonadTrans_ t2, MonadTrans_ t3, MonadTrans_ t4) => t4 (t3 (t2 m1)) a -> m1 (TransDown t2 (TransDown t3 (TransDown t4 a))) Source
Level-4
class MonadTrans4 t where Source
Level-5
class MonadTrans5 t where Source
Level-2 example
Here is a monad transformer example how to implement Ackermann function, improved to stop within a certain limit of time, with ReaderT2-IO-Maybe monad, a level-2 monad-transformation.
import DeepControl.Applicative
import DeepControl.Commutative (commute)
import DeepControl.Monad ((>-))
import DeepControl.Monad.Trans (lift2, transfold2, untransfold2)
import DeepControl.Monad.Trans.Reader
import Control.Monad.Trans.Maybe
import System.Timeout (timeout)
type TimeLimit = Int
ackermannTimeLimit :: TimeLimit -> Int -> Int
-> IO (Maybe Int) -- IO-Maybe Monad
ackermannTimeLimit timelimit x y = timeout timelimit (ackermannIO x y)
where
ackermannIO :: Int -> Int -> IO Int
ackermannIO 0 n = (*:) $ n + 1
ackermannIO m n | m > 0 && n == 0 = ackermannIO (m-1) 1
| m > 0 && n > 0 = ackermannIO m (n-1) >>= ackermannIO (m-1)
ackermann :: Int -> Int ->
ReaderT2 TimeLimit IO Maybe Int -- ReaderT2-IO-Maybe monad
ackermann x y = do
timelimit <- ask
lift2 $ ackermannTimeLimit timelimit x y -- lift IO-Maybe function to ReaderT2-IO-Maybe function
calc_ackermann :: TimeLimit -> Int -> Int -> IO (Maybe Int)
calc_ackermann timelimit x y = ackermann x y >- \r -> runReaderT2 r timelimit
-- λ> commute $ calc_ackermann 1000 |$> [0..4] |* 4
-- [Just 5,Just 6,Just 11,Just 125,Nothing]
ackermann' :: Int -> Int ->
ReaderT TimeLimit (MaybeT IO) Int -- ReaderT-MaybeT-IO monad
ackermann' x y = transfold2 $ ackermann x y -- You can get usual ReaderT-MaybeT-IO function from ReaderT2-IO-Maybe function
ackermann'' :: Int -> Int ->
ReaderT2 TimeLimit IO Maybe Int -- ReaderT2-IO-Maybe monad
ackermann'' x y = untransfold2 $ ackermann' x y -- You can get ReaderT2-IO-Maybe function from usual ReaderT-MaybeT-IO functionLevel-2 example2
Here is a monad transformer example showing how to use cover functions.
import DeepControl.Applicative ((|$>))
import DeepControl.Monad (Monad2)
import DeepControl.Monad.Trans (lift, (|*|), (|-*|), (|*-|))
import DeepControl.Monad.Trans.State
import DeepControl.Monad.Trans.Writer
tick :: State Int ()
tick = modify (+1)
tock :: StateT Int IO ()
tock = do
(|*|) tick :: (Monad m) => StateT Int m ()
lift $ putStrLn "Tock!" :: (MonadTrans t) => t IO ()
-- λ> runStateT tock 0
-- Tock!
-- ((),1)
save :: StateT Int (Writer [Int]) ()
save = do
n <- get
lift $ tell [n]
program :: StateT2 Int IO (Writer [Int]) ()
program = replicateM_ 4 $ do
(|-*|) tock
:: (Monad2 m) => StateT2 Int IO m ()
(|*-|) save
:: (Monad m) => StateT2 Int m (Writer [Int]) ()
-- λ> execWriter |$> runStateT2 program 0
-- Tock!
-- Tock!
-- Tock!
-- Tock!
-- [1,2,3,4]