polysemy-conc-0.3.0.0: lib/Polysemy/Conc/Interpreter/Scoped.hs
{-# options_haddock prune #-}
-- |Description: Scoped Interpreters, Internal
module Polysemy.Conc.Interpreter.Scoped where
import Polysemy.Internal (Sem (Sem, runSem), liftSem)
import Polysemy.Internal.Union (Weaving (Weaving), decomp, hoist, injWeaving)
import Polysemy.Conc.Effect.Scoped (Scoped (InScope, Run))
interpretH' ::
∀ e r .
(∀ x . Weaving e (Sem (e : r)) x -> Sem r x) ->
InterpreterFor e r
interpretH' h sem =
Sem \ k -> runSem sem $ decomp >>> \case
Right wav -> runSem (h wav) k
Left g -> k $ hoist (interpretH' h) g
-- |Interpreter for 'Scoped', taking a @resource@ allocation function and a parameterized interpreter for the plain
-- @effect@.
--
-- @withResource@ is a callback function, allowing the user to acquire the resource for each program from other effects.
--
-- @scopedInterpreter@ is a regular interpreter that is called with the @resource@ argument produced by @scope@.
-- /Note/: This function will be called for each action in the program, so if the interpreter allocates any resources,
-- they will be scoped to a single action. Move them to @withResource@ instead.
runScoped ::
∀ resource effect r .
(∀ x . (resource -> Sem r x) -> Sem r x) ->
(resource -> InterpreterFor effect r) ->
InterpreterFor (Scoped resource effect) r
runScoped withResource scopedInterpreter =
run
where
run :: InterpreterFor (Scoped resource effect) r
run =
interpretH' \ (Weaving effect s wv ex ins) -> case effect of
Run resource act ->
scopedInterpreter resource (liftSem $ injWeaving $ Weaving act s (raise . run . wv) ex ins)
InScope main ->
ex <$> withResource \ resource -> run (wv (main resource <$ s))
-- |Variant of 'Scoped' in which the resource allocator is a plain action.
runScopedAs ::
∀ resource effect r .
Sem r resource ->
(resource -> InterpreterFor effect r) ->
InterpreterFor (Scoped resource effect) r
runScopedAs resource =
runScoped \ f -> f =<< resource