@@ -3,6 +3,7 @@ module Effectful.Handler
5 -- * Handling effects
5 -- * Handling effects
6 , interpret
7 , interpret
7 , reinterpret
8 , reinterpret
@@ -43,13 +44,18 @@ import Effectful.Internal.Monad
43-- handler.
44-- handler.
44newtype LocalEnv es = LocalEnv (Env es)
45newtype LocalEnv es = LocalEnv (Env es)
46−data Handler (e :: Effect) = forall handlerEs. Handler
47+-- | Type signature of the effect handler.
47− { _env :: Env handlerEs
48+type EffectHandler e es
48− , _handle :: forall a localEs. HasCallStack
49+ = forall a localEs. HasCallStack
49− => LocalEnv localEs
50+ => LocalEnv localEs
51+ -- ^ The environment for handling local 'Eff' operations with functions from
52+ -- the 'localUnlift' family when given a higher order effect.
50− -> e (Eff localEs) a
53+ -> e (Eff localEs) a
54+ -- ^ The effect in the local environment.
51− -> Eff handlerEs a
55+ -> Eff es a
57+data Handler :: Effect -> Type where
58+ Handler :: Env es -> EffectHandler e es -> Handler e
54runHandler :: Env es -> Handler e -> Eff (e : es) a -> IO a
60runHandler :: Env es -> Handler e -> Eff (e : es) a -> IO a
55runHandler es0 e m = do
61runHandler es0 e m = do
@@ -59,9 +65,9 @@ runHandler es0 e m = do
59 (\es -> unEff m es)
65 (\es -> unEff m es)
61 relinker :: Relinker Handler e
67 relinker :: Relinker Handler e
62− relinker = Relinker $ \relink Handler{..} -> do
68+ relinker = Relinker $ \relink (Handler env handle) -> do
63− env <- relink _env
69+ newEnv <- relink env
64− pure Handler { _env = env, .. }
70+ pure $ Handler newEnv handle
66----------------------------------------
72----------------------------------------
67-- Sending operations
73-- Sending operations
@@ -69,18 +75,15 @@ runHandler es0 e m = do
69-- | Send an operation of a given effect to its handler for execution.
75-- | Send an operation of a given effect to its handler for execution.
70send :: (HasCallStack, e :> es) => e (Eff es) a -> Eff es a
76send :: (HasCallStack, e :> es) => e (Eff es) a -> Eff es a
71send op = unsafeEff $ \es -> do
77send op = unsafeEff $ \es -> do
72− Handler{..} <- getEnv es
78+ Handler env handle <- getEnv es
73− unEff (_handle (LocalEnv es) op) _env
79+ unEff (handle (LocalEnv es) op) env
75----------------------------------------
81----------------------------------------
76-- Interpretation
82-- Interpretation
78-- | Interpret an effect.
84-- | Interpret an effect.
80−-- /Note:/ 'LocalEnv' is for handling local 'Eff' operations using a function
81−-- from the 'localUnlift' family.
83− :: (forall r localEs. HasCallStack => LocalEnv localEs -> e (Eff localEs) r -> Eff es r)
86+ :: EffectHandler e es
84 -- ^ The effect handler.
87 -- ^ The effect handler.
85 -> Eff (e : es) a
88 -> Eff (e : es) a
86 -> Eff es a
89 -> Eff es a
@@ -92,13 +95,10 @@ interpret handler m = unsafeEff $ \es -> do
92-- Reinterpretation
95-- Reinterpretation
94-- | Interpret an effect using other effects.
97-- | Interpret an effect using other effects.
96−-- /Note:/ 'LocalEnv' is for handling local 'Eff' operations using a function
97−-- from the 'localUnlift' family.
98reinterpret
98reinterpret
99 :: (Eff handlerEs a -> Eff es b)
99 :: (Eff handlerEs a -> Eff es b)
100 -- ^ Introduction of effects encapsulated within the handler.
100 -- ^ Introduction of effects encapsulated within the handler.
101− -> (forall r localEs. HasCallStack => LocalEnv localEs -> e (Eff localEs) r -> Eff handlerEs r)
101+ -> EffectHandler e handlerEs
102 -- ^ The effect handler.
102 -- ^ The effect handler.
103 -> Eff (e : es) a
103 -> Eff (e : es) a
104 -> Eff es b
104 -> Eff es b