on master help sign in
Add the EffectHandler type synonym
commita7bc404998668d90631f91927507230e3e3e381a authorAndrzej Rybczak <andrzej@rybczak.net> dateTue 27 Jul 2021, 19:06 (5 years ago) parent0366320
6 files changed+27−42
effectful-core/src/Effectful/Handler.hs+20−20 effectful-core/src/Effectful/Internal/Effect.hs+3 effectful-core/src/Effectful/Internal/Env.hs−1 effectful-core/src/Effectful/State/Dynamic.hs+2−10 effectful-core/src/Effectful/Writer/Dynamic.hs+2−10 effectful/src/Effectful/Async.hs−1
effectful-core/src/Effectful/Handler.hs+20−20
@@ -3,6 +3,7 @@ module Effectful.Handler
33 send
44
55 -- * Handling effects
6+ , EffectHandler
67 , interpret
78 , reinterpret
89
@@ -43,13 +44,18 @@ import Effectful.Internal.Monad
4344-- handler.
4445newtype LocalEnv es = LocalEnv (Env es)
4546
46−data Handler (e :: Effect) = forall handlerEs. Handler
47− { _env :: Env handlerEs
48− , _handle :: forall a localEs. HasCallStack
49− => LocalEnv localEs
50− -> e (Eff localEs) a
51− -> Eff handlerEs a
52− }
47+-- | Type signature of the effect handler.
48+type EffectHandler e es
49+ = forall a localEs. HasCallStack
50+ => LocalEnv localEs
51+ -- ^ The environment for handling local 'Eff' operations with functions from
52+ -- the 'localUnlift' family when given a higher order effect.
53+ -> e (Eff localEs) a
54+ -- ^ The effect in the local environment.
55+ -> Eff es a
56+
57+data Handler :: Effect -> Type where
58+ Handler :: Env es -> EffectHandler e es -> Handler e
5359
5460runHandler :: Env es -> Handler e -> Eff (e : es) a -> IO a
5561runHandler es0 e m = do
@@ -59,9 +65,9 @@ runHandler es0 e m = do
5965 (\es -> unEff m es)
6066 where
6167 relinker :: Relinker Handler e
62− relinker = Relinker $ \relink Handler{..} -> do
63− env <- relink _env
64− pure Handler { _env = env, .. }
68+ relinker = Relinker $ \relink (Handler env handle) -> do
69+ newEnv <- relink env
70+ pure $ Handler newEnv handle
6571
6672----------------------------------------
6773-- Sending operations
@@ -69,18 +75,15 @@ runHandler es0 e m = do
6975-- | Send an operation of a given effect to its handler for execution.
7076send :: (HasCallStack, e :> es) => e (Eff es) a -> Eff es a
7177send op = unsafeEff $ \es -> do
72− Handler{..} <- getEnv es
73− unEff (_handle (LocalEnv es) op) _env
78+ Handler env handle <- getEnv es
79+ unEff (handle (LocalEnv es) op) env
7480
7581----------------------------------------
7682-- Interpretation
7783
7884-- | Interpret an effect.
79−--
80−-- /Note:/ 'LocalEnv' is for handling local 'Eff' operations using a function
81−-- from the 'localUnlift' family.
8285interpret
83− :: (forall r localEs. HasCallStack => LocalEnv localEs -> e (Eff localEs) r -> Eff es r)
86+ :: EffectHandler e es
8487 -- ^ The effect handler.
8588 -> Eff (e : es) a
8689 -> Eff es a
@@ -92,13 +95,10 @@ interpret handler m = unsafeEff $ \es -> do
9295-- Reinterpretation
9396
9497-- | Interpret an effect using other effects.
95−--
96−-- /Note:/ 'LocalEnv' is for handling local 'Eff' operations using a function
97−-- from the 'localUnlift' family.
9898reinterpret
9999 :: (Eff handlerEs a -> Eff es b)
100100 -- ^ 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
102102 -- ^ The effect handler.
103103 -> Eff (e : es) a
104104 -> Eff es b
effectful-core/src/Effectful/Internal/Effect.hs+3
@@ -9,6 +9,9 @@ module Effectful.Internal.Effect
99 ( Effect
1010 , (:>)(..)
1111 , IdE(..)
12+
13+ -- * Re-exports
14+ , Type
1215 ) where
1316
1417import Data.Kind
effectful-core/src/Effectful/Internal/Env.hs−1
@@ -30,7 +30,6 @@ module Effectful.Internal.Env
3030import Control.Monad
3131import Control.Monad.Primitive
3232import Data.IORef
33−import Data.Kind
3433import Data.Primitive.SmallArray
3534import GHC.Exts (Any)
3635import GHC.Stack (HasCallStack)
effectful-core/src/Effectful/State/Dynamic.hs+2−10
@@ -57,11 +57,7 @@ evalLocalState s0 = reinterpret (L.evalState s0) localState
5757execLocalState :: s -> Eff (State s : es) a -> Eff es s
5858execLocalState s0 = reinterpret (L.execState s0) localState
5959
60−localState
61− :: L.State s :> es
62− => LocalEnv localEs
63− -> State s (Eff localEs) a
64− -> Eff es a
60+localState :: L.State s :> es => EffectHandler (State s) es
6561localState env = \case
6662 Get -> L.get
6763 Put s -> L.put s
@@ -80,11 +76,7 @@ evalSharedState s0 = reinterpret (S.evalState s0) sharedState
8076execSharedState :: s -> Eff (State s : es) a -> Eff es s
8177execSharedState s0 = reinterpret (S.execState s0) sharedState
8278
83−sharedState
84− :: S.State s :> es
85− => LocalEnv localEs
86− -> State s (Eff localEs) a
87− -> Eff es a
79+sharedState :: S.State s :> es => EffectHandler (State s) es
8880sharedState env = \case
8981 Get -> S.get
9082 Put s -> S.put s
effectful-core/src/Effectful/Writer/Dynamic.hs+2−10
@@ -33,11 +33,7 @@ runLocalWriter = reinterpret L.runWriter localWriter
3333execLocalWriter :: Monoid w => Eff (Writer w : es) a -> Eff es w
3434execLocalWriter = reinterpret L.execWriter localWriter
3535
36−localWriter
37− :: (L.Writer w :> es, Monoid w)
38− => LocalEnv localEs
39− -> Writer w (Eff localEs) a
40− -> Eff es a
36+localWriter :: (L.Writer w :> es, Monoid w) => EffectHandler (Writer w) es
4137localWriter env = \case
4238 Tell w -> L.tell w
4339 Listen m -> localSeqUnlift env $ \unlift -> L.listen (unlift m)
@@ -51,11 +47,7 @@ runSharedWriter = reinterpret S.runWriter sharedWriter
5147execSharedWriter :: Monoid w => Eff (Writer w : es) a -> Eff es w
5248execSharedWriter = reinterpret S.execWriter sharedWriter
5349
54−sharedWriter
55− :: (S.Writer w :> es, Monoid w)
56− => LocalEnv localEs
57− -> Writer w (Eff localEs) a
58− -> Eff es a
50+sharedWriter :: (S.Writer w :> es, Monoid w) => EffectHandler (Writer w) es
5951sharedWriter env = \case
6052 Tell w -> S.tell w
6153 Listen m -> localSeqUnlift env $ \unlift -> S.listen (unlift m)
effectful/src/Effectful/Async.hs−1
@@ -76,7 +76,6 @@ import Control.Concurrent (threadDelay)
7676import Control.Concurrent.Async (Async)
7777import Control.Exception (Exception, SomeException)
7878import Control.Monad (forever)
79−import Data.Kind
8079import qualified Control.Concurrent.Async as A
8180import qualified UnliftIO.Async as U
8281import qualified UnliftIO.Internals.Async as I