deepcontrol-0.3.0.0: DeepControl/Monad/Morph.hs
{-|
Module : DeepControl.Monad.Morph
Description :
Copyright : 2013 Gabriel Gonzalez,
(C) 2015 KONISHI Yohsuke
License : BSD-style (see the LICENSE file in the distribution)
Maintainer : ocean0yohsuke@gmail.com
Stability : experimental
Portability : ---
This module extended mmorph package's Control.Monad.Morph module.
-}
{-# LANGUAGE RankNTypes #-}
module DeepControl.Monad.Morph (
module Control.Monad.Morph,
-- * Level-1
(|>|), (|<|),
-- * Level-2
(|>>|), (|<<|),
-- * Level-3
(|>>>|), (|<<<|),
-- * Level-2 example
-- $Example_Level2
) where
import DeepControl.Applicative
import DeepControl.Monad.Trans
import Control.Monad.Morph
-------------------------------------------------------------------------------
-- Level-1 functions
infixl 4 |>|
-- | Alias for @'hoist'@.
(|>|) :: (Monad m, MFunctor t) => (forall a . m a -> n a) -> t m b -> t n b
(|>|) = hoist
infixr 4 |<|
-- | Equivalent to (|>|) with the arguments flipped.
(|<|) :: (Monad m, MFunctor t) => t m b -> (forall a . m a -> n a) -> t n b
(|<|) l r = hoist r l
-------------------------------------------------------------------------------
-- Level-2 functions
infixl 4 |>>|
(|>>|) :: (Monad m, Monad (t2 m), MFunctor t1, MFunctor t2) =>
(forall a . m a -> n a) -> t1 (t2 m) b -> t1 (t2 n) b
(|>>|) f g = (f |>|) |>| g
infixr 4 |<<|
(|<<|) :: (Monad m, Monad (t2 m), MFunctor t1, MFunctor t2) =>
t1 (t2 m) b -> (forall a . m a -> n a) -> t1 (t2 n) b
(|<<|) f g = (g |>|) |>| f
-------------------------------------------------------------------------------
-- Level-3 functions
infixl 4 |>>>|
(|>>>|) :: (Monad m, Monad (t3 m), Monad (t2 (t3 m)), MFunctor t1, MFunctor t2, MFunctor t3) =>
(forall a . m a -> n a) -> t1 (t2 (t3 m)) b -> t1 (t2 (t3 n)) b
(|>>>|) f g = (f |>|) |>>| g
infixr 4 |<<<|
(|<<<|) :: (Monad m, Monad (t3 m), Monad (t2 (t3 m)), MFunctor t1, MFunctor t2, MFunctor t3) =>
t1 (t2 (t3 m)) b -> (forall a . m a -> n a) -> t1 (t2 (t3 n)) b
(|<<<|) f g = (g |>|) |>>| f
-------------------------------------------------------------------------------
-- TODO
{-
infixr 2 |>>=
class (MFunctor t2, MonadTrans t2) => MMonad2 t2 where
(|>>=) :: (Monad n, Monad m, MMonad t1) => t1 (t2 m) b -> (forall a . m a -> t1 (t2 n) a) -> t1 (t2 n) b
instance MMonad2 I.IdentityT where
m |>>= f = (I.runIdentityT |>| m) |>= f
infixr 2 >||>
(>||>) :: (Monad m2, Monad m3, MMonad t1, MMonad2 t2) =>
(forall a. m1 a -> t1 (t2 m2) a) -> (forall b. m2 b -> t1 (t2 m3) b) -> m1 c -> t1 (t2 m3) c
(f >||> g) m = f m |>>= g
-}
----------------------------------------------------------------------
-- Examples
{- $Example_Level2
Here is a monad-morph example, a level-2 monad-morph.
>import DeepControl.Monad.Morph
>import DeepControl.Monad.Trans.State
>import DeepControl.Monad.Trans.Writer
>
>-- i.e. :: StateT Int Identity ()
>tick :: State Int ()
>tick = modify (+1)
>
>tock :: StateT Int IO ()
>tock = do
> generalize |>| tick :: (Monad m) => StateT Int m ()
> lift $ putStrLn "Tock!" :: (MonadTrans t) => t IO ()
>
>-- λ> runStateT tock 0
>-- Tock!
>-- ((),1)
>
>-- i.e. :: StateT Int (WriterT [Int] Identity) ()
>save :: StateT Int (Writer [Int]) ()
>save = do
> n <- get
> lift $ tell [n]
>
>program :: StateT Int (WriterT [Int] IO) ()
>program = replicateM_ 4 $ do
> lift |>| tock
> :: (MonadTrans t) => StateT Int (t IO) ()
> generalize |>>| save
> :: (Monad m) => StateT Int (WriterT [Int] m ) ()
>
>-- λ> execWriterT (runStateT program 0)
>-- Tock!
>-- Tock!
>-- Tock!
>-- Tock!
>-- [1,2,3,4]
-}