on master help sign in
Add Effect.Monad and Effect.Trans

These allow Eff programs to be used in monad transformer stacks, either by wrapping them in MonadEff (which is a monad wrapping programs with unchanging effects) or by using the TRANS effect to allow lifting of programs in some inner monad.

commita21064e77efe3993c32ca9a20d0636599a57624f authorEdwin Brady <ecb10@st-andrews.ac.uk> dateSun 14 Jun 2015, 13:54 (11 years ago) parentf224681
3 files changed+41−14
libs/effects/Effect/Monad.idr+19−12 libs/effects/Effect/Trans.idr+20 libs/effects/effects.ipkg+2−2
libs/effects/Effect/Monad.idr+19−12
@@ -2,20 +2,27 @@ module Effect.Monad
22
33import Effects
44
5−-- Eff is a monad too, so we can happily use it in a monad transformer.
5+data MonadEffT : List EFFECT -> (Type -> Type) -> Type -> Type where
6+ MkMonadEffT : EffM m a xs (\v => xs) -> MonadEffT xs m a
67
7−using (xs : List EFFECT, m : Type -> Type)
8− instance Functor (\a => EffM m a xs (\v => xs)) where
9− map f prog = do t <- prog
10− value (f t)
8+instance Functor (MonadEffT xs f) where
9+ map f (MkMonadEffT x) = MkMonadEffT (do x' <- x
10+ pure (f x'))
1111
12− instance Applicative (\a => EffM m a xs (\v => xs)) where
13− pure = value
14− (<*>) f a = do f' <- f
15− a' <- a
16− value (f' a')
12+instance Applicative (MonadEffT xs f) where
13+ pure x = MkMonadEffT (pure x)
14+ (<*>) (MkMonadEffT f) (MkMonadEffT x)
15+ = MkMonadEffT (do f' <- f
16+ x' <- x
17+ pure (f' x'))
1718
18− instance Monad (\a => Eff m a xs (\v => xs)) where
19− (>>=) = Effects.(>>=)
19+instance Monad (MonadEffT xs f) where
20+ (>>=) (MkMonadEffT x) f = MkMonadEffT (do x' <- x
21+ let MkMonadEffT fx = f x'
22+ fx)
2023
24+implicit monadEffT : EffM m a xs (\v => xs) -> MonadEffT xs m a
25+monadEffT = MkMonadEffT
2126
27+MonadEff : List EFFECT -> Type -> Type
28+MonadEff xs = MonadEffT xs id
libs/effects/Effect/Trans.idrnew file+20
@@ -0,0 +1,20 @@
1+module Effect.Trans
2+
3+import Effects
4+
5+%access public
6+
7+data Trans : (Type -> Type) -> Effect where
8+ Lift : m a -> sig (Trans m) a
9+
10+-- using (m : Type -> Type)
11+instance Monad m => Handler (Trans m) m where
12+ handle st (Lift op) k = do x <- op
13+ k x ()
14+
15+TRANS : (Type -> Type) -> EFFECT
16+TRANS m = MkEff () (Trans m)
17+
18+lift : m a -> Eff a [TRANS m]
19+lift op = call $ Lift op
20+
libs/effects/effects.ipkg+2−2
@@ -1,9 +1,9 @@
11package effects
22
33opts = "--nobasepkgs -i ../prelude -i ../base"
4−modules = Effects, Effect.Default,
4+modules = Effects, Effect.Default, Effect.Monad,
55
66 Effect.Exception, Effect.File, Effect.State,
77 Effect.Random, Effect.StdIO, Effect.Select,
8− Effect.Memory, Effect.System
8+ Effect.Memory, Effect.System, Effect.Trans
99