mirror of
https://github.com/github/semantic.git
synced 2024-12-01 00:33:59 +03:00
Add a helper lifting handlers over subterm algebras.
This commit is contained in:
parent
40af10cf39
commit
bc7b639b11
@ -9,14 +9,16 @@ module Control.Effect
|
||||
, State
|
||||
-- * Handlers
|
||||
, raiseHandler
|
||||
, liftHandlerOverSubtermAlgebra
|
||||
, handleReader
|
||||
, handleState
|
||||
) where
|
||||
|
||||
import Control.Monad.Effect as Effect
|
||||
import Control.Monad.Effect.Internal
|
||||
import Control.Monad.Effect.Reader
|
||||
import Control.Monad.Effect.Resumable as Resumable
|
||||
import Control.Monad.Effect.State
|
||||
import Prologue hiding (throwError)
|
||||
|
||||
throwResumable :: (Member (Resumable exc) effects, Effectful m) => exc v -> m effects v
|
||||
throwResumable = raise . throwError
|
||||
@ -41,14 +43,14 @@ instance Effectful Eff where
|
||||
|
||||
-- | Interpreters determine and interpret a list of effects, optionally taking extra arguments.
|
||||
--
|
||||
-- Instances will generally be defined recursively in terms of underlying interpreters, bottoming out with the instance for 'Eff' which uses 'Effect.run' to produce a final value.
|
||||
-- Instances will generally be defined recursively in terms of underlying interpreters, bottoming out with the instance for 'Eff' which uses 'run' to produce a final value.
|
||||
class Effectful m => Interpreter m effects | m -> effects where
|
||||
type Result m effects result
|
||||
type instance Result m effects result = result
|
||||
interpret :: m effects result -> Result m effects result
|
||||
|
||||
instance Interpreter Eff '[] where
|
||||
interpret = Effect.run
|
||||
interpret = run
|
||||
|
||||
|
||||
-- Handlers
|
||||
@ -57,6 +59,12 @@ instance Interpreter Eff '[] where
|
||||
raiseHandler :: Effectful m => (Eff effectsA a -> Eff effectsB b) -> m effectsA a -> m effectsB b
|
||||
raiseHandler handler = raise . handler . lower
|
||||
|
||||
liftHandlerOverSubtermAlgebra :: (Effectful m, Functor base) => (m (effect ': effects) a -> m effects a) -> SubtermAlgebra base term (m (effect ': effects) a) -> SubtermAlgebra base term (m effects a)
|
||||
liftHandlerOverSubtermAlgebra handler recur = handler . recur . fmap (second (raiseHandler weakenEff))
|
||||
where weakenEff m = case m of
|
||||
Val a -> Val a
|
||||
E u q -> E (weaken u) (tsingleton (q >>> weakenEff))
|
||||
|
||||
-- | Run a 'Reader' effect in an 'Effectful' context.
|
||||
handleReader :: Effectful m => info -> m (Reader info ': effects) a -> m effects a
|
||||
handleReader = raiseHandler . flip runReader
|
||||
|
Loading…
Reference in New Issue
Block a user