deepcontrol-0.3.3.0: Provide more deeper level style of programming than the usual Control.xxx modules express

Copyright(c) Andy Gill 2001, (c) Oregon Graduate Institute of Science and Technology, 2001, (C) 2015 KONISHI Yohsuke
LicenseBSD-style (see the file LICENSE)
Maintainerocean0yohsuke@gmail.com
Stabilityexperimental
Portability---
Safe HaskellSafe
LanguageHaskell2010

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.

Synopsis

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:

Methods

liftIO :: IO a -> m a

Lift a computation from the IO monad.

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.

type M t1 = TransDown t1 Source

cover

other

class MonadTrans_ t1 where Source

Required only for MonadTransFold2 and MonadTransFold3

Methods

trans :: Monad m2 => m2 (TransDown t1 a) -> t1 m2 a Source

untrans :: Monad m2 => t1 m2 a -> m2 (TransDown t1 a) Source

Level-2

class MonadTrans2 t where Source

Methods

lift2 :: (Monad m1, Monad2 m2) => m1 (m2 a) -> t m1 m2 a Source

class (MonadTrans (Trans2Down t2), MonadTrans2 t2) => MonadTrans2Down t2 Source

Associated Types

type Trans2Down t2 :: (* -> *) -> * -> * 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

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

(|**|) :: (Monad m1, Monad2 m2, MonadTransCover2 t2) => M_ t2 a -> t2 m1 m2 a infixl 3 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

Methods

lift3 :: (Monad m1, Monad2 m2, Monad3 m3) => m1 (m2 (m3 a)) -> t m1 m2 m3 a Source

class (MonadTrans2 (Trans3Down t3), MonadTrans3 t3) => MonadTrans3Down t3 Source

Associated Types

type Trans3Down t3 :: (* -> *) -> (* -> *) -> * -> * 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

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

(|***|) :: (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

Methods

lift4 :: (Monad m1, Monad2 m2, Monad3 m3, Monad4 m4) => m1 (m2 (m3 (m4 a))) -> t m1 m2 m3 m4 a Source

Level-5

class MonadTrans5 t where Source

Methods

lift5 :: (Monad m1, Monad2 m2, Monad3 m3, Monad4 m4, Monad5 m5) => m1 (m2 (m3 (m4 (m5 a)))) -> t m1 m2 m3 m4 m5 a 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 function

Level-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]