Safe Haskell | None |
---|---|
Language | Haskell2010 |
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 :: *) (sReform :: *) (r :: [Effect]) (p :: [Effect]) (m :: * -> *) z (a :: *) = HandlerC {
- unHandlerC :: z a
- data CarrierReform m
- newtype InterpretPrimC (s :: *) (e :: Effect) (m :: * -> *) a = InterpretPrimC {
- unInterpretPrimC :: m a
- class (RepresentationalEff e, Carrier m) => Handler (h :: *) 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 :: *) e m where
- effPrimHandler :: EffPrimHandler e m
- newtype InterpretC (h :: *) (e :: Effect) (m :: * -> *) 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 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 :: * -> *) a = InterpretSimpleC {
- unInterpretSimpleC :: ReaderT (ReifiedHandler e m) m a
- newtype InterpretPrimSimpleC (e :: Effect) (m :: * -> *) 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 #
HandlerCState (forall x. m x -> z x) (Algebra p z) |
newtype ReifiedReformulation r p 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 reflect :: ReifiedReformulation r p m Source # |
newtype HandlerC (sHandler :: *) (sReform :: *) (r :: [Effect]) (p :: [Effect]) (m :: * -> *) z (a :: *) Source #
HandlerC | |
|
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 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 type Derivs (HandlerC sHandler sReform r p m z) :: [Effect] Source # type Prims (HandlerC sHandler sReform r p m z) :: [Effect] Source # 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 reflect :: ReifiedReformulation r p m Source # |
newtype InterpretPrimC (s :: *) (e :: Effect) (m :: * -> *) a Source #
InterpretPrimC | |
|
Instances
class (RepresentationalEff e, Carrier m) => Handler (h :: *) 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.
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 EffHandler
s, EffPrimHandler
s 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 :: *) 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
.
effPrimHandler :: EffPrimHandler e m Source #
Instances
newtype InterpretC (h :: *) (e :: Effect) (m :: * -> *) a Source #
InterpretC | |
|
Instances
newtype ReifiedHandler e m Source #
newtype ReifiedPrimHandler (e :: Effect) m Source #
ReifiedPrimHandler | |
|
coerceHandler :: (RepresentationalEff e, Coercible m n) => (e m a -> m a) -> e n a -> n a Source #
data ViaReifiedH (s :: *) Source #
Instances
(RepresentationalEff e, Carrier m, Reifies s (ReifiedPrimHandler e m)) => PrimHandler (ViaReifiedH s) e m Source # | |
Defined in Control.Effect.Carrier.Internal.Interpret 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 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 :: * -> *) a Source #
InterpretSimpleC | |
|
Instances
newtype InterpretPrimSimpleC (e :: Effect) (m :: * -> *) a Source #
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
(InterpretReifiedC
e m) = e ':Derivs
m
Prims
(InterpretReifiedC
e m) =Prims
m
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 ::Eff
Teletype m => m String readTTY = send ReadTTY writeTTY ::Eff
Teletype m => String -> m () writeTTY = send . WriteTTY echo ::Eff
Teletype m => m () echo = readTTY >>= sendTTY teletypeToIO ::Eff
(Embed
IO) m =>InterpreterFor
Teletype m teletypeToIO =interpret
$ \case ReadTTY ->embed
getLine 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
(InterpretSimpleC
e m) = e ':Derivs
m
Prims
(InterpretSimpleC
e m) =Prims
m
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 ::Eff
Teletype m => m String readTTY = send ReadTTY writeTTY ::Eff
Teletype m => String -> m () writeTTY = send . WriteTTY echo ::Eff
Teletype m => m () echo = readTTY >>= sendTTY teletypeToIO ::Eff
(Embed
IO) m =>SimpleInterpreterFor
Teletype m teletypeToIO =interpretSimple
$ \case ReadTTY ->embed
getLine 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
(InterpretC
h e m) = e ':Derivs
m
Prims
(InterpretC
h e m) =Prims
m
Example usage:
data Teletype :: Effect where ReadTTY :: Teletype m String WriteTTY :: String -> Teletype m () readTTY ::Eff
Teletype m => m String readTTY = send ReadTTY writeTTY ::Eff
Teletype m => String -> m () writeTTY = send . WriteTTY echo ::Eff
Teletype m => m () echo = readTTY >>= sendTTY data TeletypeToIOH instanceEff
(Embed
IO) m =>Handler
TeletypeToIOH Teletype m where effHandler = \case ReadTTY ->embed
getLine WriteTTY str ->embed
$ putStrLn str type TeletypeToIOC =InterpretC
TeletypeToIOH Teletype teletypeToIO ::Eff
(Embed
IO) m => TeletypeToIOC m a -> m a teletypeToIO =interpretViaHandler
main :: 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
(InterpretPrimReifiedC
e m) = e ':Derivs
m
Prims
(InterpretPrimReifiedC
e m) = e ':Prims
m
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
(InterpretPrimSimpleC
e m) = e ':Derivs
m
Prims
(InterpretPrimSimpleC
e m) = e ':Prims
m
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 #
ReinterpretC | |
|
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
(ReinterpretReifiedC
e new m) = e ':StripPrefix
new (Derivs
m)
Prims
(ReinterpretReifiedC
e new m) =Prims
m
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
(ReinterpretC
h e new m) = e ':StripPrefix
new (Derivs
m)
Prims
(ReinterpretC
h e new m) =Prims
m
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 #
ReinterpretSimpleC | |
|
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
(ReinterpretSimpleC
e new m) = e ':StripPrefix
new (Derivs
m)
Prims
(ReinterpretSimpleC
e new m) =Prims
m
This is a significantly slower variant of reinterpret
that doesn't have
a higher-ranked type, making it much easier to use partially applied.