| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
Control.Effect
Synopsis
- class Monad m => Carrier m where
- type Effect = (* -> *) -> * -> *
- class (forall m n x. Coercible m n => Coercible (e m x) (e n x)) => RepresentationalEff (e :: Effect)
- type Eff e m = Effs '[e] m
- type Effs es m = (EffMembers es (Derivs m), Carrier m)
- data Bundle :: [Effect] -> Effect
- class Member e r
- send :: (Member e (Derivs m), Carrier m) => e m a -> m a
- run :: RunC a -> a
- runM :: Monad m => RunMC m a -> m a
- newtype Embed b (m :: * -> *) a where
- embed :: Eff (Embed b) m => b 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
- type SimpleInterpreterFor e m = forall x p. Threaders '[ReaderThreads] m p => InterpretSimpleC e m x -> m x
- interpretViaHandler :: forall h e m a. Handler h e m => InterpretC h e m a -> m a
- class (RepresentationalEff e, Carrier m) => Handler (h :: *) e m where
- effHandler :: EffHandler e m
- interpret :: forall e m a. (RepresentationalEff e, Carrier m) => EffHandler e m -> InterpretReifiedC e m a -> m a
- type InterpreterFor e m = forall x. InterpretReifiedC e m x -> m x
- 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
- 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
- reinterpretViaHandler :: forall h e new m a. (Handler h e m, KnownList new, HeadEffs new m) => ReinterpretC h e new m a -> 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
- type Threaders cs m p = (p ~ Prims m, SatisfiesAll p cs)
- class (forall i. Threads (ReaderT i) p) => ReaderThreads p
- intro1 :: forall e m a. IntroConsistent '[] '[e] m => IntroTopC '[e] m a -> m a
- intro :: forall new m a. (KnownList new, IntroConsistent '[] new m) => IntroTopC new m a -> m a
- introUnder1 :: forall new e m a. IntroConsistent '[e] '[new] m => IntroUnderC e '[new] m a -> m a
- introUnder :: forall new e m a. (KnownList new, IntroConsistent '[e] new m) => IntroUnderC e new m a -> m a
- introUnderMany :: forall top new m a. (KnownList top, KnownList new, IntroConsistent top new m) => IntroUnderManyC top new m a -> m a
- type HeadEff e m = (IntroConsistent '[] '[e] m, Carrier m)
- type HeadEffs new m = (IntroConsistent '[] new m, Carrier m)
- data CompositionC ts m a
- runComposition :: CompositionC ts m a -> CompositionBaseM ts m a
- newtype Effly m a = Effly {
- runEffly :: m a
- subsume :: (Carrier m, Member e (Derivs m)) => SubsumeC e m a -> m a
- class (Applicative b, Applicative m, Monad b, Monad m) => MonadBase (b :: Type -> Type) (m :: Type -> Type) | m -> b where
- liftBase :: b α -> m α
- class MonadTrans (t :: (Type -> Type) -> Type -> Type) where
- type RunC = Identity
- data RunMC m a
- data InterpretSimpleC (e :: Effect) (m :: * -> *) a
- data InterpretC (h :: *) (e :: Effect) (m :: * -> *) a
- type InterpretReifiedC e m a = forall s. ReifiesHandler s e m => InterpretC (ViaReifiedH s) e m a
- type ReifiesHandler s e m = Reifies s (ReifiedHandler e m)
- data ViaReifiedH (s :: *)
- data ReinterpretSimpleC e new m a
- data ReinterpretC h e new m a
- type ReinterpretReifiedC e new m a = forall s. ReifiesHandler s e m => ReinterpretC (ViaReifiedH s) e new m a
- type IntroConsistent top new m = Append top (Append new (StripPrefix new (StripPrefix top (Derivs m)))) ~ Derivs m
- data IntroC (top :: [Effect]) (new :: [Effect]) (m :: * -> *) a
- type IntroTopC = IntroC '[]
- type IntroUnderC e = IntroC '[e]
- type IntroUnderManyC = IntroC
- class KnownList l
- data SubsumeC (e :: Effect) m a
Core class
class Monad m => Carrier m Source #
The class of effect carriers, and the underlying mechanism with which effects are implemented.
Each carrier is able to implement a number of derived effects, and primitive effects. Users usually only interact with derived effects, as these determine the effects that users have access to.
The standard interpretation tools are typically powerful enough to
let you avoid making instances of this class directly. If you need to make
your own instance of Carrier, import Control.Effect.Carrier and consult the
wiki.
Minimal complete definition
Associated Types
type Derivs m :: [Effect] Source #
The derived effects that m carries. Each derived effect is eventually
reformulated into terms of the primitive effects or other
effects in Prims m.Derivs m
In application code, you gain access to effects by placing membership
constraints upon . You can use Derivs mEff or Effs for this
purpose.
Although rarely relevant for users, can also contain effects
that aren't expressed in terms of other effects, as longs as the handlers
for those effects can be lifted generically using Derivs mlift. Such effects don't
need to be part of , which is exclusively for primitive effects
whose handlers need special treatment to be lifted.Prims m
For example, first order effects such as State
never need to be part of . Certain higher-order effects -
such as Prims mCont - can also be handled such that they
never need to be primitive.
Instances
type Effect = (* -> *) -> * -> * Source #
The kind of effects.
Helpful for defining new effects:
data InOut i o :: Effect where Input :: InOut i o m i Output :: o -> InOut i o m ()
class (forall m n x. Coercible m n => Coercible (e m x) (e n x)) => RepresentationalEff (e :: Effect) Source #
RepresentationalEff is the constraint every effect is expected
to satisfy: namely, that any effect e m a is representational in m,
which -- in practice -- means that no constraints are ever placed upon
m within the definion of e, and that m isn't present in
the return type of any action of e.
You don't need to make instances of RepresentationalEff; the compiler
will automatically infer if your effect satisfies it.
RepresentationalEff is not a very serious requirement, and
even effects that don't satisfy it can typically be rewritten into
equally powerful variants that do.
If you ever encounter that an effect you've written doesn't satisfy
RepresentationalEff, please consult
the wiki.
Instances
| (forall (m :: Type -> Type) (n :: Type -> Type) x. Coercible m n => Coercible (e m x) (e n x)) => RepresentationalEff e Source # | |
Defined in Control.Effect.Internal.Union | |
Effect membership
type Eff e m = Effs '[e] m Source #
(Morally) a type synonym for
(.
This and Member e (Derivs m), Carrier m)Effs are the typical methods to gain
access to effects.
Unlike Member, Eff gives Bundle special treatment.
As a side-effect, Eff will get stuck if e is a type variable.
If you need access to some completely polymorphic effect e,
use ( instead of Member e (Derivs m), Carrier m)Eff e m.
type Effs es m = (EffMembers es (Derivs m), Carrier m) Source #
A variant of Eff that takes a list of effects, and expands them into
multiple Member constraints on .
This and Derivs mEff are the typical methods to gain access to effects.
Like Eff, Effs gives Bundle special treatment.
As a side-effect, Effs will get stuck if any element of the list
is a type variable.
If you need access to some completetely polymorphic effect e,
use a separate constraint.Member e (Derivs m)
data Bundle :: [Effect] -> Effect Source #
A pseudo-effect given special treatment by Eff
and Effs.
An constraint on
Eff/s
will expand it into membership constraints for Bundle '[eff1, eff2, ... , effn]eff1 through effn.
For example:
Errore =Bundle'[Throwe,Catche]
so
Eff(Errore) m = (Carrierm,Member(Throwe) (Derivsm),Member(Catche) (Derivsm))
Bundle should never be used in any other contexts but within
Eff and Effs, as it isn't an actual effect.
Not to be confused with Union, which is a proper
effect that combines multiple effects into one.
A constraint that e is part of the effect row r.
r is typically for some Derivs mm.
Member e ( allows you to use
actions of Derivs m)e with m.
If e occurs multiple times in r, then the first
occurence will be used.
If possible, use instead.Eff/s
Minimal complete definition
Instances
| (TypeError ((('Text "Unhandled effect: " :<>: 'ShowType e) :$$: 'Text "You need to either add or replace an interpreter in your interpretation stack so that the effect gets handled.") :$$: 'Text "To check what effects are currently handled by your interpretation stack, use `debugEffects' from `Control.Effect.Debug'.") :: Constraint) => Member (e :: k) ('[] :: [k]) Source # | |
Defined in Control.Effect.Internal.Membership Methods membership :: ElemOf e '[] Source # | |
| Member e r => Member (e :: a) (_e ': r :: [a]) Source # | |
Defined in Control.Effect.Internal.Membership Methods membership :: ElemOf e (_e ': r) Source # | |
| Member (e :: a) (e ': r :: [a]) Source # | |
Defined in Control.Effect.Internal.Membership Methods membership :: ElemOf e (e ': r) Source # | |
Sending actions of effects
send :: (Member e (Derivs m), Carrier m) => e m a -> m a Source #
Perform an action of an effect.
send should be used to create actions of your own effects.
For example:
data CheckString :: Effect where CheckString :: String -> CheckString m Bool checkString :: Eff CheckString m => String -> m Bool checkString str = send (CheckString str)
Running final monad
Extract the final result from a computation of which no effects remain to be handled.
runM :: Monad m => RunMC m a -> m a Source #
Extract the final monad m from a computation of which
no effects remain to be handled except for .Embed m
Integrating external monads
newtype Embed b (m :: * -> *) a where Source #
An effect for embedding actions of a base monad into the current one.
Effect interpretation
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
type SimpleInterpreterFor e m = forall x p. Threaders '[ReaderThreads] m p => InterpretSimpleC e m x -> m x Source #
A useful type synonym for the type of interpretSimple provided a handler
m is left polymorphic so that you may place constraints on it.Eff/s
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
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.
Methods
effHandler :: EffHandler e m 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(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
type InterpreterFor e m = forall x. InterpretReifiedC e m x -> m x Source #
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.
Effect reinterpretation
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.
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.
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.
Threading constraints
type Threaders cs m p = (p ~ Prims m, SatisfiesAll p cs) Source #
A constraint that satisfies all the constraints in the list
Prims mcs.
This is used for threading constraints.
Every interpreter that relies on an underlying
non-trivial monad transformer -- such as runState,
which uses StateT internally --
must be able to lift all primitive effect handlers of the monad it's transforming
so that the resulting transformed monad can also handle the primitive effects.
The ability of a monad transformer to lift handlers of a particular primitive effect is called threading that effect. Threading constraints correspond to the requirement that the primitive effects of the monad that's being transformed can be thread by certain monad transformers.
For example, the runState places the threading
constraint StateThreads on , so that
Prims m can carry all primitive effects that
StateC s mm does.
Threaders is used to handle threading constraints.
allows you to use Threaders '[StateThreads, ExceptThreads] m prunState and
runError with the carrier m.
Sometimes, you may want to have a local effect which you interpret
inside of application code, such as a local State
or Error effect. In such cases, try to use
split interpretation instead of using interpreters with threading constraints
inside of application code. If you can't, then using Threaders
is necessary to propagate the threading constraints
throughout the application.
The third argument p should always be a polymorphic type variable, which
you can simply provide and ignore.
It exists as a work-around to the fact that many threading constraints
don't actually work if they operate on directly, since
threading constraints often involve quantified constraints, which are fragile
in combination with type families -- like Prims mPrims.
So
doesn't expand to Threaders '[StateThreads] m p, but rather,
StateThreads (Prims m)(p ~ Prims m, StateThreads p)
class (forall i. Threads (ReaderT i) p) => ReaderThreads p Source #
The most common threading constraint of the library, as it is emitted by
-Simple interpreters (interpreters that internally make use of
interpretSimple or reinterpretSimple).
ReaderThreads accepts all the primitive effects
(intended to be used as such) offered in this library.
Most notably, ReaderThreads accepts .Unlift b
Instances
| (forall i. Threads (ReaderT i) p) => ReaderThreads p Source # | |
Defined in Control.Effect.Internal.Union | |
Effect Introduction
intro1 :: forall e m a. IntroConsistent '[] '[e] m => IntroTopC '[e] m a -> m a Source #
intro :: forall new m a. (KnownList new, IntroConsistent '[] new m) => IntroTopC new m a -> m a Source #
introUnder1 :: forall new e m a. IntroConsistent '[e] '[new] m => IntroUnderC e '[new] m a -> m a Source #
Introduce an effect under the top effect of the effect stack -- or rather, reveal that effect which was previously hidden.
Derivs(IntroUnderCe '[new] m) = e ':StripPrefix[e, new] (Derivsm)
Prims(IntroUnderCe '[new] m) =Primsm
introUnder :: forall new e m a. (KnownList new, IntroConsistent '[e] new m) => IntroUnderC e new m a -> m a Source #
Introduce multiple effects under the top effect of the effect stack -- or rather, reveal those effects which were previously hidden.
Derivs(IntroUnderCe new m) = e ':StripPrefix(e ': new) (Derivsm)
Prims(IntroUnderCe new m) =Primsm
introUnderMany :: forall top new m a. (KnownList top, KnownList new, IntroConsistent top new m) => IntroUnderManyC top new m a -> m a Source #
Introduce multiple effects under a number of top effects of the effect stack -- or rather, reveal those effects which were previously hidden.
Derivs(IntroUnderManyCtop new m) = Append top (StripPrefix(Append top new) (Derivsm))
Prims(IntroUnderManyCtop new m) =Primsm
type HeadEff e m = (IntroConsistent '[] '[e] m, Carrier m) Source #
type HeadEffs new m = (IntroConsistent '[] new m, Carrier m) Source #
Combining effect carriers
data CompositionC ts m a Source #
Composition of a list of carrier transformers.
This is useful when you have multiple interpretations whose
carriers you'd like to treat as one larger object, such that
lift lifts past all those carriers.
For example:
data Counter m a where Probe :: Counter m Int type CounterC =CompositionC'[ReinterpretSimpleCCounter '[StateInt] ,StateCInt ] runCounter :: (Carrierm,Threaders'[StateThreads] m p) => CounterC m a -> m a runCounter =runState0 .reinterpretSimple(case Probe ->state'(s -> (s+1,s)) ) .runComposition
Then you have lift :: Monad m => m a -> CounterC m a
Instances
runComposition :: CompositionC ts m a -> CompositionBaseM ts m a Source #
Transform to CompositionC [t1, t2, ..., tn] m at1 (t2 (... (tn m) ...)) a
Other utilities
A newtype wrapper with instances based around the effects of m
when possible; Effly as in "Effectfully."
This is often useful for making use of these instances inside of interpreter handlers, or within application code.
Instances
subsume :: (Carrier m, Member e (Derivs m)) => SubsumeC e m a -> m a Source #
Interpret an effect in terms of another, identical effect.
This is very rarely useful, but one use-case is to transform reinterpreters into regular interpreters.
For example,
is morally equivalent
to subsume . reinterpretSimple @e hinterpretSimple @e h
Reexports from other modules
class (Applicative b, Applicative m, Monad b, Monad m) => MonadBase (b :: Type -> Type) (m :: Type -> Type) | m -> b where #
Instances
class MonadTrans (t :: (Type -> Type) -> Type -> Type) where #
The class of monad transformers. Instances should satisfy the
following laws, which state that lift is a monad transformation:
Methods
lift :: Monad m => m a -> t m a #
Lift a computation from the argument monad to the constructed monad.
Instances
Carriers and other misc. types
Instances
data InterpretSimpleC (e :: Effect) (m :: * -> *) a Source #
Instances
data InterpretC (h :: *) (e :: Effect) (m :: * -> *) a Source #
Instances
type InterpretReifiedC e m a = forall s. ReifiesHandler s e m => InterpretC (ViaReifiedH s) e m a Source #
type ReifiesHandler s e m = Reifies s (ReifiedHandler e m) 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 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 # | |
data ReinterpretSimpleC e new m a Source #
Instances
data ReinterpretC h e new m a Source #
Instances
type ReinterpretReifiedC e new m a = forall s. ReifiesHandler s e m => ReinterpretC (ViaReifiedH s) e new m a Source #
type IntroConsistent top new m = Append top (Append new (StripPrefix new (StripPrefix top (Derivs m)))) ~ Derivs m Source #
A constraint that the effect stack of m -- --
begins with Derivs mAppend top new.
data IntroC (top :: [Effect]) (new :: [Effect]) (m :: * -> *) a Source #
Instances
type IntroUnderC e = IntroC '[e] Source #
type IntroUnderManyC = IntroC Source #
Synonym for IntroC to match introUnderMany
Minimal complete definition
data SubsumeC (e :: Effect) m a Source #