on master help sign in
Rename effect interpreters to effect handlers
commit48138ff547d07e669ac3bba3e032300b07f3e545 authorAndrzej Rybczak <andrzej@rybczak.net> dateMon 12 Jul 2021, 18:00 (5 years ago) parent91e64bf
8 files changed+67−56
README.md+1−1 effectful.cabal+1−1 src/Effectful.hs+1−1 src/Effectful/Interpreter.hs → src/Effectful/Handler.hs+29−29 src/Effectful/Internal/Env.hs+24−13 src/Effectful/Internal/Monad.hs+9−9 src/Effectful/State/Dynamic.hs+1−1 src/Effectful/Writer/Dynamic.hs+1−1
README.md+1−1
@@ -73,7 +73,7 @@ dedicated, well established solution such as
7373
7474This is where `effectful` comes in. The `Eff` monad it uses is essentially a
7575`ReaderT` over `IO` on steroids, allowing us to dynamically extend its
76−environment with data types that represent effects or their interpreters.
76+environment with data types that represent effects or their handlers.
7777
7878Because this concept is so simple:
7979
effectful.cabal+1−1
@@ -87,11 +87,11 @@ library
8787 Effectful.Async
8888 Effectful.Error
8989 Effectful.Fail
90+ Effectful.Handler
9091 Effectful.Internal.Effect
9192 Effectful.Internal.Env
9293 Effectful.Internal.Monad
9394 Effectful.Internal.Unlift
94− Effectful.Interpreter
9595 Effectful.Monad
9696 Effectful.Reader
9797 Effectful.Resource
src/Effectful.hs+1−1
@@ -53,5 +53,5 @@ module Effectful
5353 , localLiftUnliftIO
5454 ) where
5555
56−import Effectful.Interpreter
56+import Effectful.Handler
5757import Effectful.Monad
src/Effectful/Interpreter.hs → src/Effectful/Handler.hsrenamed+29−29
@@ -1,4 +1,4 @@
1−module Effectful.Interpreter
1+module Effectful.Handler
22 ( -- * Sending operations to the handler
33 send
44
@@ -30,50 +30,50 @@ module Effectful.Interpreter
3030 , localLiftUnliftIO
3131 ) where
3232
33−import Control.Exception
3433import Control.Monad.IO.Unlift
3534import GHC.Stack
35+import qualified Control.Exception as E
3636
3737import Effectful.Internal.Effect
3838import Effectful.Internal.Env
3939import Effectful.Internal.Monad
4040
4141----------------------------------------
42−-- Interpreter
42+-- Handler
4343
4444-- | Opaque representation of the 'Eff' environment at the point of calling the
4545-- 'send' function, i.e. right before the control is passed to the effect
4646-- handler.
4747newtype LocalEnv es = LocalEnv (Env es)
4848
49−data Interpreter (e :: Effect) = forall handlerEs. Interpreter
50− { _env :: Env handlerEs
51− , _interpret :: forall a localEs. HasCallStack
52− => LocalEnv localEs
53− -> e (Eff localEs) a
54− -> Eff handlerEs a
49+data Handler (e :: Effect) = forall handlerEs. Handler
50+ { _env :: Env handlerEs
51+ , _handle :: forall a localEs. HasCallStack
52+ => LocalEnv localEs
53+ -> e (Eff localEs) a
54+ -> Eff handlerEs a
5555 }
5656
57−runInterpreter :: Env es -> Interpreter e -> Eff (e : es) a -> IO a
58−runInterpreter es0 e m = do
57+runHandler :: Env es -> Handler e -> Eff (e : es) a -> IO a
58+runHandler es0 e m = do
5959 size0 <- sizeEnv es0
60− bracket (unsafeConsEnv e relinker es0)
61− (unsafeTailEnv size0)
62− (\es -> unEff m es)
60+ E.bracket (unsafeConsEnv e relinker es0)
61+ (unsafeTailEnv size0)
62+ (\es -> unEff m es)
6363 where
64− relinker :: Relinker Interpreter e
65− relinker = Relinker $ \relink Interpreter{..} -> do
64+ relinker :: Relinker Handler e
65+ relinker = Relinker $ \relink Handler{..} -> do
6666 env <- relink _env
67− pure Interpreter { _env = env, .. }
67+ pure Handler { _env = env, .. }
6868
6969----------------------------------------
70−-- Sending commands
70+-- Sending operations
7171
72−-- | Send an operation of a given effect to the interpreter for execution.
72+-- | Send an operation of a given effect to its handler for execution.
7373send :: (HasCallStack, e :> es) => e (Eff es) a -> Eff es a
7474send op = unsafeEff $ \es -> do
75− Interpreter{..} <- getEnv es
76− unEff (_interpret (LocalEnv es) op) _env
75+ Handler{..} <- getEnv es
76+ unEff (_handle (LocalEnv es) op) _env
7777
7878----------------------------------------
7979-- Interpretation
@@ -84,9 +84,9 @@ interpret
8484 -- ^ The effect handler.
8585 -> Eff (e : es) a
8686 -> Eff es a
87−interpret interpreter m = unsafeEff $ \es -> do
87+interpret handler m = unsafeEff $ \es -> do
8888 les <- forkEnv es
89− runInterpreter es (Interpreter les $ \_ -> interpreter) m
89+ runHandler es (Handler les $ \_ -> handler) m
9090
9191-- | Interpret a higher order effect.
9292--
@@ -97,9 +97,9 @@ interpretM
9797 -- ^ The effect handler.
9898 -> Eff (e : es) a
9999 -> Eff es a
100−interpretM interpreter m = unsafeEff $ \es -> do
100+interpretM handler m = unsafeEff $ \es -> do
101101 les <- forkEnv es
102− runInterpreter es (Interpreter les interpreter) m
102+ runHandler es (Handler les handler) m
103103
104104----------------------------------------
105105-- Reinterpretation
@@ -112,10 +112,10 @@ reinterpret
112112 -- ^ The effect handler.
113113 -> Eff (e : es) a
114114 -> Eff es b
115−reinterpret runHandlerEs interpreter m = unsafeEff $ \es -> do
115+reinterpret runHandlerEs handler m = unsafeEff $ \es -> do
116116 les0 <- forkEnv es
117117 (`unEff` les0) . runHandlerEs . unsafeEff $ \les -> do
118− runInterpreter es (Interpreter les $ \_ -> interpreter) m
118+ runHandler es (Handler les $ \_ -> handler) m
119119
120120-- | Interpret a higher order effect using other effects.
121121--
@@ -128,10 +128,10 @@ reinterpretM
128128 -- ^ The effect handler.
129129 -> Eff (e : es) a
130130 -> Eff es b
131−reinterpretM runHandlerEs interpreter m = unsafeEff $ \es -> do
131+reinterpretM runHandlerEs handler m = unsafeEff $ \es -> do
132132 les0 <- forkEnv es
133133 (`unEff` les0) . runHandlerEs . unsafeEff $ \les -> do
134− runInterpreter es (Interpreter les interpreter) m
134+ runHandler es (Handler les handler) m
135135
136136----------------------------------------
137137-- Unlifts
src/Effectful/Internal/Env.hs+24−13
@@ -43,7 +43,7 @@ type role Env nominal
4343-- of kind 'Effect'.
4444--
4545-- Supports forking, i.e. introduction of local branches for encapsulation of
46−-- data specific to effect interpreters.
46+-- data specific to effect handlers.
4747--
4848-- Offers very good performance characteristics:
4949--
@@ -150,10 +150,10 @@ newForkId (ForkIdGen ref) = do
150150
151151newtype Relinker i (e :: Effect) where
152152 Relinker
153− :: ((forall es. Env es -> IO (Env es)) -> i e -> IO (i e))
154− -> Relinker i e
153+ :: ((forall es. Env es -> IO (Env es)) -> handler e -> IO (handler e))
154+ -> Relinker handler e
155155
156−noRelinker :: Relinker i e
156+noRelinker :: Relinker handler e
157157noRelinker = Relinker $ \_ -> pure
158158
159159----------------------------------------
@@ -238,7 +238,7 @@ copyForks es fs len = \case
238238
239239type EnvRefCache = IORef (IM.IntMap (IORef EnvRef))
240240
241−-- | Relink local environments hiding in the interpreters.
241+-- | Relink local environments hiding in the handlers.
242242relinkData
243243 :: IORef EnvRef
244244 -> ForkIdGen
@@ -294,7 +294,7 @@ cloneEnvRef gref gen cache fid lref0 = do
294294
295295----------------------------------------
296296
297−-- | Create a local fork of the environment for interpreters.
297+-- | Create a local fork of the environment for handlers.
298298forkEnv :: Env es -> IO (Env es)
299299forkEnv env@(Env NoFork gref gen) = do
300300 size <- sizeEnv env
@@ -321,7 +321,7 @@ sizeEnv (Env (Forks _ baseIx lref _) _ _) = do
321321{-# NOINLINE sizeEnv #-}
322322
323323-- | Extract a specific data type from the environment.
324−getEnv :: forall e es i. e :> es => Env es -> IO (i e)
324+getEnv :: forall e es handler. e :> es => Env es -> IO (handler e)
325325getEnv env = do
326326 (i, es) <- getLocation @e env
327327 fromAny <$> readSmallArray es i
@@ -343,7 +343,7 @@ checkSizeEnv k (Env (Forks _ baseIx lref _) _ _) = do
343343-- Extending and shrinking
344344
345345-- | Extend the environment with a new data type (in place).
346−unsafeConsEnv :: i e -> Relinker i e -> Env es -> IO (Env (e : es))
346+unsafeConsEnv :: handler e -> Relinker handler e -> Env es -> IO (Env (e : es))
347347unsafeConsEnv e f (Env fork gref gen) = case fork of
348348 NoFork -> do
349349 extendEnvRef gref
@@ -402,20 +402,31 @@ unsafeTailEnv len (Env fork gref gen) = case fork of
402402-- Data retrieval and update
403403
404404-- | Replace the data type in the environment with a new value (in place).
405−unsafePutEnv :: forall e es i. e :> es => i e -> Env es -> IO ()
405+unsafePutEnv
406+ :: forall e es handler. e :> es
407+ => handler e
408+ -> Env es -> IO ()
406409unsafePutEnv e env = do
407410 (i, es) <- getLocation @e env
408411 e `seq` writeSmallArray es i (toAny e)
409412
410413-- | Modify the data type in the environment (in place).
411−unsafeModifyEnv :: forall e es i. e :> es => (i e -> i e) -> Env es -> IO ()
414+unsafeModifyEnv
415+ :: forall e es handler. e :> es
416+ => (handler e -> handler e)
417+ -> Env es
418+ -> IO ()
412419unsafeModifyEnv f env = do
413420 (i, es) <- getLocation @e env
414421 e <- f . fromAny <$> readSmallArray es i
415422 e `seq` writeSmallArray es i (toAny e)
416423
417424-- | Modify the data type in the environment (in place) and return a value.
418−unsafeStateEnv :: forall e es i a. e :> es => (i e -> (a, i e)) -> Env es -> IO a
425+unsafeStateEnv
426+ :: forall e es handler a. e :> es
427+ => (handler e -> (a, handler e))
428+ -> Env es
429+ -> IO a
419430unsafeStateEnv f env = do
420431 (i, es) <- getLocation @e env
421432 (a, e) <- f . fromAny <$> readSmallArray es i
@@ -443,8 +454,8 @@ getLocation (Env fork ref _) = do
443454 -- - Most application code has no access to forks, in which case we look at
444455 -- the global EnvRef.
445456 --
446− -- - Interpreters will most likely access the newest fork for reinterpretation
447− -- of effects that are there.
457+ -- - Effect handlers will most likely access the newest fork with handler
458+ -- specific effects for reinterpretation.
448459 case fork of
449460 NoFork -> pure (ix n, es)
450461 Forks _ baseIx lref forks -> do
src/Effectful/Internal/Monad.hs+9−9
@@ -390,46 +390,46 @@ unliftEff f = unliftStrategy >>= \case
390390----------------------------------------
391391-- Helpers
392392
393−runEffect :: i e -> Eff (e : es) a -> Eff es (a, i e)
393+runEffect :: handler e -> Eff (e : es) a -> Eff es (a, handler e)
394394runEffect e0 m = unsafeEff $ \es0 -> do
395395 size0 <- sizeEnv es0
396396 bracket (unsafeConsEnv e0 noRelinker es0)
397397 (unsafeTailEnv size0)
398398 (\es -> (,) <$> unEff m es <*> getEnv es)
399399
400−evalEffect :: i e -> Eff (e : es) a -> Eff es a
400+evalEffect :: handler e -> Eff (e : es) a -> Eff es a
401401evalEffect e m = unsafeEff $ \es0 -> do
402402 size0 <- sizeEnv es0
403403 bracket (unsafeConsEnv e noRelinker es0)
404404 (unsafeTailEnv size0)
405405 (\es -> unEff m es)
406406
407−execEffect :: i e -> Eff (e : es) a -> Eff es (i e)
407+execEffect :: handler e -> Eff (e : es) a -> Eff es (handler e)
408408execEffect e0 m = unsafeEff $ \es0 -> do
409409 size0 <- sizeEnv es0
410410 bracket (unsafeConsEnv e0 noRelinker es0)
411411 (unsafeTailEnv size0)
412412 (\es -> unEff m es *> getEnv es)
413413
414−getEffect :: e :> es => Eff es (i e)
414+getEffect :: e :> es => Eff es (handler e)
415415getEffect = unsafeEff $ \es -> getEnv es
416416
417−putEffect :: e :> es => i e -> Eff es ()
417+putEffect :: e :> es => handler e -> Eff es ()
418418putEffect e = unsafeEff $ \es -> unsafePutEnv e es
419419
420−stateEffect :: e :> es => (i e -> (a, i e)) -> Eff es a
420+stateEffect :: e :> es => (handler e -> (a, handler e)) -> Eff es a
421421stateEffect f = unsafeEff $ \es -> unsafeStateEnv f es
422422
423−localEffect :: e :> es => (i e -> i e) -> Eff es a -> Eff es a
423+localEffect :: e :> es => (handler e -> handler e) -> Eff es a -> Eff es a
424424localEffect f m = unsafeEff $ \es -> do
425425 bracket (unsafeStateEnv (\e -> (e, f e)) es)
426426 (\e -> unsafePutEnv e es)
427427 (\_ -> unEff m es)
428428
429−readerEffectM :: e :> es => (i e -> Eff es a) -> Eff es a
429+readerEffectM :: e :> es => (handler e -> Eff es a) -> Eff es a
430430readerEffectM f = unsafeEff $ \es -> getEnv es >>= \e -> unEff (f e) es
431431
432−stateEffectM :: e :> es => (i e -> Eff es (a, i e)) -> Eff es a
432+stateEffectM :: e :> es => (handler e -> Eff es (a, handler e)) -> Eff es a
433433stateEffectM f = unsafeEff $ \es -> mask $ \release -> do
434434 (a, e) <- (\e -> release $ unEff (f e) es) =<< getEnv es
435435 unsafePutEnv e es
src/Effectful/State/Dynamic.hs+1−1
@@ -33,7 +33,7 @@ module Effectful.State.Dynamic
3333 , modifyM
3434 ) where
3535
36−import Effectful.Interpreter
36+import Effectful.Handler
3737import Effectful.Monad
3838import qualified Effectful.State as SP
3939import qualified Effectful.State.MVar as SM
src/Effectful/Writer/Dynamic.hs+1−1
@@ -15,7 +15,7 @@ module Effectful.Writer.Dynamic
1515 , listens
1616 ) where
1717
18−import Effectful.Interpreter
18+import Effectful.Handler
1919import Effectful.Monad
2020import qualified Effectful.Writer as WP
2121import qualified Effectful.Writer.MVar as WM