deepcontrol-0.3.0.0: Enable 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: all the MonadTransx 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 m1, Monad m1, Monad2 m2) => MonadIO (WriterT2 w 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, Monad3 m3) => MonadIO (WriterT3 w 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

trans :: (Monad m, MonadTrans t) => m a -> t m a Source

Alias for lift.

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.

class MonadTrans2 t where Source

Methods

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

class MonadTrans3 t where Source

Methods

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

class MonadTrans4 t where Source

Methods

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

class MonadTrans5 t where Source

Methods

trans5 :: (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 (trans2)
import DeepControl.Monad.Trans.Reader

import System.Timeout (timeout)

type TimeLimit = Int

ackermann :: TimeLimit -> Int -> Int ->
             IO (Maybe Int)                        -- IO-Maybe Monad
ackermann 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)

ackermannR :: Int -> Int ->
              ReaderT2 TimeLimit IO Maybe Int      -- ReaderT2-IO-Maybe monad
ackermannR x y = do
    timelimit <- ask
    trans2 $ ackermann timelimit x y               -- transform(lift) IO-Maybe function to ReaderT2-IO-Maybe function

calc_ackermann :: TimeLimit -> Int -> Int -> IO (Maybe Int)
calc_ackermann timelimit x y = ackermannR x y >- \r -> runReaderT2 r timelimit

-- λ> commute $ calc_ackermann 1000 |$> [0..4] |* 4
-- [Just 5,Just 6,Just 11,Just 125,Nothing]