0 | module Control.Eff.Internal
2 | import public Control.MonadRec
3 | import public Control.Monad.Free
4 | import public Data.Union
5 | import public Data.Subset
13 | Eff : (fs : List (Type -> Type)) -> (t : Type) -> Type
14 | Eff fs = Free (Union fs)
18 | send : Has f fs => f t -> Eff fs t
24 | toFree : Eff fs t -> Handler fs m -> Free m t
25 | toFree eff h = mapK (handleAll h) eff
30 | runEff : MonadRec m => Eff fs t -> Handler fs m -> m t
31 | runEff eff h = foldMap (handleAll h) eff
36 | extract : Eff [] a -> a
37 | extract fr = case toView fr of
39 | Bind u _ => absurd u
43 | {auto prf : Has f fs}
44 | -> (a -> Eff (fs - f) b)
45 | -> (forall v . f v -> (v -> Eff (fs - f) b) -> Eff (fs - f) b)
48 | handleRelay fval fcont fr = case toView fr of
49 | Pure val => fval val
50 | Bind x g => case decomp {prf} x of
51 | Left y => assert_total $
lift y >>= handleRelay fval fcont . g
52 | Right y => assert_total $
fcont y (handleRelay fval fcont . g)
56 | {auto prf : Has f fs}
57 | -> (forall v . f v -> (resume: v -> Eff (fs - f) b) -> Eff (fs - f) b)
60 | handle fcont fr = handleRelay pure fcont fr
64 | {auto prf : Has f fs}
66 | -> (s -> a -> Eff (fs - f) b)
67 | -> (forall v . s -> f v -> (s -> v -> Eff (fs - f) b) -> Eff (fs - f) b)
70 | handleRelayS vs fval fcont fr = case toView fr of
71 | Pure val => fval vs val
72 | Bind x g => case decomp {prf} x of
73 | Left y => assert_total $
lift y >>= handleRelayS vs fval fcont . g
74 | Right y => assert_total $
fcont vs y (\vs2 => handleRelayS vs2 fval fcont . g)
79 | lift : Subset fs fs' => Eff fs a -> Eff fs' a
80 | lift @{s} fr = case toView fr of
81 | Pure val => pure val
83 | let mx := weaken @{s} x
85 | lift (assert_smaller fr (g freex))