| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
Control.Effect.Carrier.Internal.Interpret
Synopsis
- data HandlerCState p m z = HandlerCState (forall x. m x -> z x) (Algebra p z)
- newtype ReifiedReformulation r p m = ReifiedReformulation {
- getReifiedReformulation :: Reformulation r p m
- newtype HandlerC (sHandler :: Type) (sReform :: Type) (r :: [Effect]) (p :: [Effect]) (m :: Type -> Type) z (a :: Type) = HandlerC {
- unHandlerC :: z a
- data CarrierReform m
- newtype InterpretPrimC (s :: Type) (e :: Effect) (m :: Type -> Type) a = InterpretPrimC {
- unInterpretPrimC :: m a
- class (RepresentationalEff e, Carrier m) => Handler (h :: Type) e m where
- effHandler :: EffHandler e m
- type EffHandler e m = forall z x. (Carrier z, Derivs z ~ Derivs m, Prims z ~ Prims m, MonadBase m z) => e (Effly z) x -> Effly z x
- type EffPrimHandler e m = forall x. e m x -> m x
- class (RepresentationalEff e, Carrier m) => PrimHandler (h :: Type) e m where
- effPrimHandler :: EffPrimHandler e m
- newtype InterpretC (h :: Type) (e :: Effect) (m :: Type -> Type) a = InterpretC {
- unInterpretC :: m a
- newtype ReifiedHandler e m = ReifiedHandler {
- getReifiedHandler :: EffHandler e m
- newtype ReifiedPrimHandler (e :: Effect) m = ReifiedPrimHandler {
- getReifiedPrimHandler :: forall z x. Coercible z m => e z x -> m x
- coerceHandler :: (RepresentationalEff e, Coercible m n) => (e m a -> m a) -> e n a -> n a
- data ViaReifiedH (s :: Type)
- type InterpretReifiedC e m a = forall s. ReifiesHandler s e m => InterpretC (ViaReifiedH s) e m a
- type InterpretPrimReifiedC e m a = forall s. ReifiesPrimHandler s e m => InterpretPrimC (ViaReifiedH s) e m a
- newtype InterpretSimpleC (e :: Effect) (m :: Type -> Type) a = InterpretSimpleC {
- unInterpretSimpleC :: ReaderT (ReifiedHandler e m) m a
- newtype InterpretPrimSimpleC (e :: Effect) (m :: Type -> Type) a = InterpretPrimSimpleC {
- unInterpretPrimSimpleC :: ReaderT (ReifiedPrimHandler e m) m a
- interpret :: forall e m a. (RepresentationalEff e, Carrier m) => EffHandler e m -> InterpretReifiedC e m a -> m a
- interpretSimple :: forall e m a p. (RepresentationalEff e, Threaders '[ReaderThreads] m p, Carrier m) => EffHandler e m -> InterpretSimpleC e m a -> m a
- interpretViaHandler :: forall h e m a. Handler h e m => InterpretC h e m a -> m a
- interpretPrim :: forall e m a. (RepresentationalEff e, Carrier m) => EffPrimHandler e m -> InterpretPrimReifiedC e m a -> m a
- interpretPrimViaHandler :: forall h e m a. PrimHandler h e m => InterpretPrimC h e m a -> m a
- interpretPrimSimple :: forall e m a p. (RepresentationalEff e, Threaders '[ReaderThreads] m p, ReaderThreads '[e], Carrier m) => EffPrimHandler e m -> InterpretPrimSimpleC e m a -> m a
- addDeriv :: (RepresentationalEff e, Monad m) => (forall z x. (Carrier z, Derivs z ~ r, Prims z ~ p, MonadBase m z) => e (Effly z) x -> Effly z x) -> Reformulation r p m -> Reformulation (e ': r) p m
- newtype ReinterpretC h e new m a = ReinterpretC {
- unReinterpretC :: IntroUnderC e new (InterpretC h e m) a
- type ReifiesHandler s e m = Reifies s (ReifiedHandler e m)
- type ReifiesPrimHandler s e m = Reifies s (ReifiedPrimHandler e m)
- type ReinterpretReifiedC e new m a = forall s. ReifiesHandler s e m => ReinterpretC (ViaReifiedH s) e new m a
- reinterpret :: forall e new m a. (RepresentationalEff e, KnownList new, HeadEffs new m) => EffHandler e m -> ReinterpretReifiedC e new m a -> m a
- reinterpretViaHandler :: forall h e new m a. (Handler h e m, KnownList new, HeadEffs new m) => ReinterpretC h e new m a -> m a
- newtype ReinterpretSimpleC e new m a = ReinterpretSimpleC {
- unReinterpretSimpleC :: IntroUnderC e new (InterpretSimpleC e m) a
- reinterpretSimple :: forall e new m a p. (RepresentationalEff e, KnownList new, HeadEffs new m, Threaders '[ReaderThreads] m p) => EffHandler e m -> ReinterpretSimpleC e new m a -> m a
Documentation
data HandlerCState p m z Source #
Constructors
| HandlerCState (forall x. m x -> z x) (Algebra p z) |
newtype ReifiedReformulation r p m Source #
Constructors
| ReifiedReformulation | |
Fields
| |
Instances
| (Carrier m, r ~ Derivs m, p ~ Prims m) => Reifies (CarrierReform m :: Type) (ReifiedReformulation r p m) Source # | |
Defined in Control.Effect.Carrier.Internal.Interpret Methods reflect :: ReifiedReformulation r p m Source # | |
newtype HandlerC (sHandler :: Type) (sReform :: Type) (r :: [Effect]) (p :: [Effect]) (m :: Type -> Type) z (a :: Type) Source #
Constructors
| HandlerC | |
Fields
| |
Instances
| (Reifies sHandler (HandlerCState p m z), Monad z, Monad m) => MonadBase m (HandlerC sHandler sReform r p m z) Source # | |
Defined in Control.Effect.Carrier.Internal.Interpret | |
| Monad z => Monad (HandlerC sHandler sReform r p m z) Source # | |
Defined in Control.Effect.Carrier.Internal.Interpret | |
| Functor z => Functor (HandlerC sHandler sReform r p m z) Source # | |
| Applicative z => Applicative (HandlerC sHandler sReform r p m z) Source # | |
Defined in Control.Effect.Carrier.Internal.Interpret Methods pure :: a -> HandlerC sHandler sReform r p m z a # (<*>) :: HandlerC sHandler sReform r p m z (a -> b) -> HandlerC sHandler sReform r p m z a -> HandlerC sHandler sReform r p m z b # liftA2 :: (a -> b -> c) -> HandlerC sHandler sReform r p m z a -> HandlerC sHandler sReform r p m z b -> HandlerC sHandler sReform r p m z c # (*>) :: HandlerC sHandler sReform r p m z a -> HandlerC sHandler sReform r p m z b -> HandlerC sHandler sReform r p m z b # (<*) :: HandlerC sHandler sReform r p m z a -> HandlerC sHandler sReform r p m z b -> HandlerC sHandler sReform r p m z a # | |
| (Reifies sHandler (HandlerCState p m z), Reifies sReform (ReifiedReformulation r p m), Monad z) => Carrier (HandlerC sHandler sReform r p m z) Source # | |
Defined in Control.Effect.Carrier.Internal.Interpret Associated Types type Derivs (HandlerC sHandler sReform r p m z) :: [Effect] Source # type Prims (HandlerC sHandler sReform r p m z) :: [Effect] Source # Methods algPrims :: Algebra' (Prims (HandlerC sHandler sReform r p m z)) (HandlerC sHandler sReform r p m z) a Source # reformulate :: Monad z0 => Reformulation' (Derivs (HandlerC sHandler sReform r p m z)) (Prims (HandlerC sHandler sReform r p m z)) (HandlerC sHandler sReform r p m z) z0 a Source # algDerivs :: Algebra' (Derivs (HandlerC sHandler sReform r p m z)) (HandlerC sHandler sReform r p m z) a Source # | |
| type Derivs (HandlerC sHandler sReform r p m z) Source # | |
Defined in Control.Effect.Carrier.Internal.Interpret | |
| type Prims (HandlerC sHandler sReform r p m z) Source # | |
Defined in Control.Effect.Carrier.Internal.Interpret | |
data CarrierReform m Source #
Instances
| (Carrier m, r ~ Derivs m, p ~ Prims m) => Reifies (CarrierReform m :: Type) (ReifiedReformulation r p m) Source # | |
Defined in Control.Effect.Carrier.Internal.Interpret Methods reflect :: ReifiedReformulation r p m Source # | |
newtype InterpretPrimC (s :: Type) (e :: Effect) (m :: Type -> Type) a Source #
Constructors
| InterpretPrimC | |
Fields
| |
Instances
class (RepresentationalEff e, Carrier m) => Handler (h :: Type) e m where Source #
The class of effect handlers for derived effects.
Instances of this class can be used together interpretViaHandler
in order to interpret effects.
h is the tag for the handler, e is the effect to interpret,
and m is the Carrier on which the handler operates.
To define your own interpreter using this method, create a new
datatype without any constructors to serve as the tag
for the handler, and then define a Handler instance for it.
Then, you can use your handler to interpret effects with
interpretViaHandler.
Alternatively, you can use interpret or interpretSimple,
which lets you avoid the need to define instances of Handler,
but come at other costs.
Methods
effHandler :: EffHandler e m Source #
Instances
type EffHandler e m = forall z x. (Carrier z, Derivs z ~ Derivs m, Prims z ~ Prims m, MonadBase m z) => e (Effly z) x -> Effly z x Source #
The type of effect handlers for a derived effect e with current
carrier m.
Don't let the type overwhelm you; in most cases, you can treat this as
e m x -> m x.
Any EffHandler is required to work with any carrier monad z that
lifts m, and has the same derived and primitive effects as m does.
The only constraints that are propagated to z are membership
constraints:
MonadIO m doesn't imply MonadIO z, but Eff (Embed IO) m does
imply Eff (Embed IO) z.
In addition, since z lifts m, you can lift values of m
to z through liftBase. This is most useful when using
interpret or interpretSimple, as it allows you to
bring monadic values of m from outside of the handler
(like arguments to the interpreter) into the handler.
The z provided to the handler has Effly wrapped around it,
so the handler may make use of the various instances of Effly.
For example, you have access to MonadFix inside the handler
if you have .Eff Fix m
Any effect to be handled needs to be
representational in the monad parameter. See RepresentationalEff
for more information.
type EffPrimHandler e m = forall x. e m x -> m x Source #
The type of effect handlers for a primitive effect e with current
carrier m.
Unlike EffHandlers, EffPrimHandlers have direct access to m,
making them significantly more powerful.
That said, you should interpret your own effects as primitives only as a
last resort. Every primitive effect comes at the cost of enormous amounts
of boilerplate: namely, the need for a ThreadsEff instance for every
monad transformer that can thread that effect.
Some effects in this library are intended to be used as primitive effects,
such as Regional. Try to use such effects
to gain the power you need to interpret your effects instead of
defining your own primitive effects, since the primitive effects offered
in this library already have ThreadsEff instances defined for them.
class (RepresentationalEff e, Carrier m) => PrimHandler (h :: Type) e m where Source #
The class of effect handlers for primitive effects.
Instances of this class can be used together interpretPrimViaHandler
in order to interpret primitive effects.
h is the tag for the handler, e is the effect to interpret,
and m is the Carrier on which the handler operates.
To define your own interpreter using this method, create a new
datatype without any constructors to serve as the tag
for the handler, and then define a PrimHandler instance for it.
Then, you can use your handler to interpret effects with
interpretPrimViaHandler.
Alternatively, you can use interpretPrim or interpretPrimSimple,
which lets you avoid the need to define instances of PrimHandler,
but come at other costs.
Only interpret your own effects as primitives as a last resort.
See EffPrimHandler.
Methods
effPrimHandler :: EffPrimHandler e m Source #
Instances
newtype InterpretC (h :: Type) (e :: Effect) (m :: Type -> Type) a Source #
Constructors
| InterpretC | |
Fields
| |
Instances
newtype ReifiedHandler e m Source #
Constructors
| ReifiedHandler | |
Fields
| |
newtype ReifiedPrimHandler (e :: Effect) m Source #
Constructors
| ReifiedPrimHandler | |
Fields
| |
coerceHandler :: (RepresentationalEff e, Coercible m n) => (e m a -> m a) -> e n a -> n a Source #
data ViaReifiedH (s :: Type) Source #
Instances
| (RepresentationalEff e, Carrier m, Reifies s (ReifiedPrimHandler e m)) => PrimHandler (ViaReifiedH s) e m Source # | |
Defined in Control.Effect.Carrier.Internal.Interpret Methods effPrimHandler :: EffPrimHandler e m Source # | |
| (RepresentationalEff e, Carrier m, Reifies s (ReifiedHandler e m)) => Handler (ViaReifiedH s) e m Source # | |
Defined in Control.Effect.Carrier.Internal.Interpret Methods effHandler :: EffHandler e m Source # | |
type InterpretReifiedC e m a = forall s. ReifiesHandler s e m => InterpretC (ViaReifiedH s) e m a Source #
type InterpretPrimReifiedC e m a = forall s. ReifiesPrimHandler s e m => InterpretPrimC (ViaReifiedH s) e m a Source #
newtype InterpretSimpleC (e :: Effect) (m :: Type -> Type) a Source #
Constructors
| InterpretSimpleC | |
Fields
| |
Instances
newtype InterpretPrimSimpleC (e :: Effect) (m :: Type -> Type) a Source #
Constructors
| InterpretPrimSimpleC | |
Fields
| |
Instances
interpret :: forall e m a. (RepresentationalEff e, Carrier m) => EffHandler e m -> InterpretReifiedC e m a -> m a Source #
Interpret an effect in terms of other effects, without needing to
define an explicit Handler instance. This is an alternative to
interpretViaHandler, and is more performant than interpretSimple.
See EffHandler for more information about the handler you pass to
this function.
Derivs(InterpretReifiedCe m) = e ':Derivsm
Prims(InterpretReifiedCe m) =Primsm
This has a higher-rank type, as it makes use of InterpretReifiedC.
This makes interpret very difficult to use partially applied.
In particular, it can't be composed using . You must use
paranthesis or .$.
Consider using interpretSimple instead if performance is secondary.
Example usage:
data Teletype :: Effect where ReadTTY :: Teletype m String WriteTTY :: String -> Teletype m () readTTY ::EffTeletype m => m String readTTY = send ReadTTY writeTTY ::EffTeletype m => String -> m () writeTTY = send . WriteTTY echo ::EffTeletype m => m () echo = readTTY >>= sendTTY teletypeToIO ::Eff(EmbedIO) m =>InterpreterForTeletype m teletypeToIO =interpret$ \case ReadTTY ->embedgetLine WriteTTY str ->embed$ putStrLn str main :: IO () main =runM$ teletypeToIO $ echo
interpretSimple :: forall e m a p. (RepresentationalEff e, Threaders '[ReaderThreads] m p, Carrier m) => EffHandler e m -> InterpretSimpleC e m a -> m a Source #
Interpret an effect in terms of other effects, without needing to
define an explicit Handler instance. This is an alternative to
interpretViaHandler.
See EffHandler for more information about the handler you pass to
this function.
Derivs(InterpretSimpleCe m) = e ':Derivsm
Prims(InterpretSimpleCe m) =Primsm
This is a significantly slower variant of interpret that doesn't have
a higher-ranked type, making it much easier to use partially applied.
Note: this emits the threading constraint ReaderThreads (see Threaders).
This makes interpretSimple significantly less attractive to use
in application code, as it means propagating that constraint
through your application.
Example usage:
data Teletype :: Effect where ReadTTY :: Teletype m String WriteTTY :: String -> Teletype m () readTTY ::EffTeletype m => m String readTTY = send ReadTTY writeTTY ::EffTeletype m => String -> m () writeTTY = send . WriteTTY echo ::EffTeletype m => m () echo = readTTY >>= sendTTY teletypeToIO ::Eff(EmbedIO) m =>SimpleInterpreterForTeletype m teletypeToIO =interpretSimple$ \case ReadTTY ->embedgetLine WriteTTY str ->embed$ putStrLn str main :: IO () main =runM$ teletypeToIO $ echo
interpretViaHandler :: forall h e m a. Handler h e m => InterpretC h e m a -> m a Source #
Interpret an effect in terms of other effects by using
an explicit Handler instance.
See Handler for more information.
Unlike interpret, this does not have a higher-rank type,
making it easier to use partially applied, and unlike
interpretSimple doesn't sacrifice performance.
Derivs(InterpretCh e m) = e ':Derivsm
Prims(InterpretCh e m) =Primsm
Example usage:
data Teletype :: Effect where ReadTTY :: Teletype m String WriteTTY :: String -> Teletype m () readTTY ::EffTeletype m => m String readTTY = send ReadTTY writeTTY ::EffTeletype m => String -> m () writeTTY = send . WriteTTY echo ::EffTeletype m => m () echo = readTTY >>= sendTTY data TeletypeToIOH instanceEff(EmbedIO) m =>HandlerTeletypeToIOH Teletype m where effHandler = \case ReadTTY ->embedgetLine WriteTTY str ->embed$ putStrLn str type TeletypeToIOC =InterpretCTeletypeToIOH Teletype teletypeToIO ::Eff(EmbedIO) m => TeletypeToIOC m a -> m a teletypeToIO =interpretViaHandlermain :: IO () main =runM$ teletypeToIO $ echo
interpretPrim :: forall e m a. (RepresentationalEff e, Carrier m) => EffPrimHandler e m -> InterpretPrimReifiedC e m a -> m a Source #
Interpret an effect as a new primitive effect.
Only interpret your own effects as primitives as a last resort.
See EffPrimHandler.
Derivs(InterpretPrimReifiedCe m) = e ':Derivsm
Prims(InterpretPrimReifiedCe m) = e ':Primsm
This has a higher-rank type, as it makes use of InterpretPrimReifiedC.
This makes interpretPrim very difficult to use partially applied.
In particular, it can't be composed using . You must use
paranthesis or .$.
Consider using interpretPrimSimple instead if performance is secondary.
interpretPrimViaHandler :: forall h e m a. PrimHandler h e m => InterpretPrimC h e m a -> m a Source #
Interpret an effect as a new primitive effect by using
an explicit PrimHandler instance.
See PrimHandler for more information.
Only interpret your own effects as primitives as a last resort.
See EffPrimHandler.
interpretPrimSimple :: forall e m a p. (RepresentationalEff e, Threaders '[ReaderThreads] m p, ReaderThreads '[e], Carrier m) => EffPrimHandler e m -> InterpretPrimSimpleC e m a -> m a Source #
A significantly slower variant of interpretPrim that doesn't have
a higher-ranked type, making it much easier to use partially applied.
Only interpret your own effects as primitives as a last resort.
See EffPrimHandler.
Derivs(InterpretPrimSimpleCe m) = e ':Derivsm
Prims(InterpretPrimSimpleCe m) = e ':Primsm
Note the ReaderThreads '[e] constraint, meaning
you need to define a ThreadsEff e (ReaderT i) instance in order
to use interpretPrimSimple.
addDeriv :: (RepresentationalEff e, Monad m) => (forall z x. (Carrier z, Derivs z ~ r, Prims z ~ p, MonadBase m z) => e (Effly z) x -> Effly z x) -> Reformulation r p m -> Reformulation (e ': r) p m Source #
Add a derived effect to a Reformulation
by providing a handler for that effect.
The handler is an EffHandler, but with derived and primitive effects
determined by the transformed Reformulation.
newtype ReinterpretC h e new m a Source #
Constructors
| ReinterpretC | |
Fields
| |
Instances
type ReifiesHandler s e m = Reifies s (ReifiedHandler e m) Source #
type ReifiesPrimHandler s e m = Reifies s (ReifiedPrimHandler e m) Source #
type ReinterpretReifiedC e new m a = forall s. ReifiesHandler s e m => ReinterpretC (ViaReifiedH s) e new m a Source #
reinterpret :: forall e new m a. (RepresentationalEff e, KnownList new, HeadEffs new m) => EffHandler e m -> ReinterpretReifiedC e new m a -> m a Source #
Reinterpret an effect in terms of newly introduced effects.
This combines interpret and introUnder in order to introduce the effects
new under e, which you then may make use of inside the handler for e.
Derivs(ReinterpretReifiedCe new m) = e ':StripPrefixnew (Derivsm)
Prims(ReinterpretReifiedCe new m) =Primsm
This has a higher-rank type, as it makes use of ReinterpretReifiedC.
This makes reinterpret very difficult to use partially applied.
In particular, it can't be composed using . You must use
paranthesis or .$.
Consider using reinterpretSimple instead if performance is secondary.
reinterpretViaHandler :: forall h e new m a. (Handler h e m, KnownList new, HeadEffs new m) => ReinterpretC h e new m a -> m a Source #
Reinterpret an effect in terms of newly introduced effects by using
an explicit Handler instance.
See Handler for more information.
This combines interpretViaHandler and introUnder in order to introduce
the effects new under e, which you then may make use of inside the handler
for e.
Derivs(ReinterpretCh e new m) = e ':StripPrefixnew (Derivsm)
Prims(ReinterpretCh e new m) =Primsm
Unlike reinterpret, this does not have a higher-rank type,
making it easier to use partially applied, and unlike
reinterpretSimple doesn't sacrifice performance.
newtype ReinterpretSimpleC e new m a Source #
Constructors
| ReinterpretSimpleC | |
Fields
| |
Instances
reinterpretSimple :: forall e new m a p. (RepresentationalEff e, KnownList new, HeadEffs new m, Threaders '[ReaderThreads] m p) => EffHandler e m -> ReinterpretSimpleC e new m a -> m a Source #
Reinterpret an effect in terms of newly introduced effects.
This combines interpretSimple and introUnder in order to introduce
the effects new under e, which you then may make use of inside the
handler for e.
Derivs(ReinterpretSimpleCe new m) = e ':StripPrefixnew (Derivsm)
Prims(ReinterpretSimpleCe new m) =Primsm
This is a significantly slower variant of reinterpret that doesn't have
a higher-ranked type, making it much easier to use partially applied.