{-| Module : DeepControl.Monad.Trans Description : Enable deep level Monad-Transform programming. 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 : --- 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. -} module DeepControl.Monad.Trans ( -- * MonadIO MonadIO(..), -- * MonadTrans trans, MonadTrans(..), MonadTrans2(..), MonadTrans3(..), MonadTrans4(..), MonadTrans5(..), -- * Level-2 example -- $Example_Level2 ) where import DeepControl.Monad import Control.Monad.IO.Class import Control.Monad.Trans.Class (MonadTrans (..)) ---------------------------------------------------------------------- -- Level-1 -- | Alias for @'Control.Monad.Trans.Class.lift'@. trans :: (Monad m, MonadTrans t) => m a -> t m a trans = lift ---------------------------------------------------------------------- -- Level-2 class MonadTrans2 t where trans2 :: (Monad m1, Monad2 m2) => m1 (m2 a) -> t m1 m2 a ---------------------------------------------------------------------- -- Level-3 class MonadTrans3 t where trans3 :: (Monad m1, Monad2 m2, Monad3 m3) => m1 (m2 (m3 a)) -> t m1 m2 m3 a ---------------------------------------------------------------------- -- Level-4 class MonadTrans4 t where trans4 :: (Monad m1, Monad2 m2, Monad3 m3, Monad4 m4) => m1 (m2 (m3 (m4 a))) -> t m1 m2 m3 m4 a ---------------------------------------------------------------------- -- Level-5 class MonadTrans5 t where trans5 :: (Monad m1, Monad2 m2, Monad3 m3, Monad4 m4, Monad5 m5) => m1 (m2 (m3 (m4 (m5 a)))) -> t m1 m2 m3 m4 m5 a ---------------------------------------------------------------------- -- Examples {- $Example_Level2 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] -}