deepcontrol-0.5.4.0: Provide deep level programming style for Applicative and Monad

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.

Synopsis

Documentation

MonadTrans

class (Monad m, MonadTrans t) => MonadTrans_ m t | m -> t, t -> m where Source #

Required only for transfold

Minimal complete definition

trans, untrans

Methods

trans :: Monad n => n (m a) -> t n a Source #

untrans :: Monad n => t n a -> n (m a) Source #

Instances

MonadTrans_ [] ListT Source # 

Methods

trans :: Monad n => n [a] -> ListT n a Source #

untrans :: Monad n => ListT n a -> n [a] Source #

MonadTrans_ Maybe MaybeT Source # 

Methods

trans :: Monad n => n (Maybe a) -> MaybeT n a Source #

untrans :: Monad n => MaybeT n a -> n (Maybe a) Source #

MonadTrans_ Identity (IdentityT *) Source # 

Methods

trans :: Monad n => n (Identity a) -> IdentityT * n a Source #

untrans :: Monad n => IdentityT * n a -> n (Identity a) Source #

MonadTrans_ (Except e) (ExceptT e) Source # 

Methods

trans :: Monad n => n (Except e a) -> ExceptT e n a Source #

untrans :: Monad n => ExceptT e n a -> n (Except e a) Source #

Monoid w => MonadTrans_ (Writer w) (WriterT w) Source # 

Methods

trans :: Monad n => n (Writer w a) -> WriterT w n a Source #

untrans :: Monad n => WriterT w n a -> n (Writer w a) Source #

Level-2

trans-roll

transfold2 :: (Monad m1, MonadTrans_ m2 t2) => m1 (m2 a) -> t2 m1 a Source #

>>> transfold2 $ [Just 1]
MaybeT [Just 1]
>>> transfold2 $ Just [1]
ListT (Just [1])

untransfold2 :: (Monad m1, MonadTrans_ m2 t2) => t2 m1 a -> m1 (m2 a) Source #

>>> untransfold2 $ MaybeT [Just 1]
[Just 1]
>>> untransfold2 $ ListT (Just [1])
Just [1]

Level-3

trans-roll

transfold3 :: (Monad m1, Monad (t2 m1), MonadTrans_ m2 t2, MonadTrans_ m3 t3) => m1 (m2 (m3 a)) -> t3 (t2 m1) a Source #

>>> transfold3 $ ExceptT (Identity (Right [Just 1]))
MaybeT (ListT (ExceptT (Identity (Right [Just 1]))))

untransfold3 :: (Monad m1, Monad (t2 m1), MonadTrans_ m2 t2, MonadTrans_ m3 t3) => t3 (t2 m1) a -> m1 (m2 (m3 a)) Source #

>>> untransfold3 $ MaybeT (ListT (ExceptT (Identity (Right [Just 1]))))
ExceptT (Identity (Right [Just 1]))

Level-4

trans-roll

transfold4 :: (Monad m1, Monad (t2 m1), Monad (t3 (t2 m1)), MonadTrans_ m2 t2, MonadTrans_ m3 t3, MonadTrans_ m4 t4) => m1 (m2 (m3 (m4 a))) -> t4 (t3 (t2 m1)) a Source #

untransfold4 :: (Monad m1, Monad (t2 m1), Monad (t3 (t2 m1)), MonadTrans_ m2 t2, MonadTrans_ m3 t3, MonadTrans_ m4 t4) => t4 (t3 (t2 m1)) a -> m1 (m2 (m3 (m4 a))) Source #

Level-5

trans-roll

transfold5 :: (Monad m1, Monad (t2 m1), Monad (t3 (t2 m1)), Monad (t4 (t3 (t2 m1))), MonadTrans_ m2 t2, MonadTrans_ m3 t3, MonadTrans_ m4 t4, MonadTrans_ m5 t5) => m1 (m2 (m3 (m4 (m5 a)))) -> t5 (t4 (t3 (t2 m1))) a Source #

untransfold5 :: (Monad m1, Monad (t2 m1), Monad (t3 (t2 m1)), Monad (t4 (t3 (t2 m1))), MonadTrans_ m2 t2, MonadTrans_ m3 t3, MonadTrans_ m4 t4, MonadTrans_ m5 t5) => t5 (t4 (t3 (t2 m1))) a -> 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 ReaderT-IdentityT2-IO-Maybe monad, a level-2 monad-transformation.

import DeepControl.Applicative
import DeepControl.Traversable (sink)
import DeepControl.Monad ((>-))
import DeepControl.Monad.Morph ((|*|), (|>|))
import DeepControl.Monad.Trans (transfold2, untransfold2)
import DeepControl.Monad.Trans.Identity (Identity(..), IdentityT(..), IdentityT2(..))
import Control.Monad.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 -> 
             ReaderT TimeLimit (IdentityT2 IO Maybe) Int  -- ReaderT-IdentityT2-IO-Maybe monad
ackermann x y = do
    timelimit <- ask
    (|*|) . IdentityT2 $ ackermannTimeLimit timelimit x y -- lift IO-Maybe function to ReaderT-IdentityT2-IO-Maybe function

calc_ackermann :: TimeLimit -> Int -> Int -> IO (Maybe Int)
calc_ackermann timelimit x y = ackermann x y >- \r -> runReaderT r timelimit
                                             >- runIdentityT2

-- λ> sink $ 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 . runIdentityT2) |>| ackermann x y -- You can get usual ReaderT-MaybeT-IO function from ReaderT-IdentityT2-IO-Maybe function

ackermann'' :: Int -> Int -> 
               ReaderT TimeLimit (IdentityT2 IO Maybe) Int       -- ReaderT-IdentityT2-IO-Maybe monad
ackermann'' x y = (IdentityT2 . untransfold2) |>| ackermann' x y -- You can get ReaderT-IdentityT2-IO-Maybe function from usual ReaderT-MaybeT-IO function