Safe Haskell | None |
---|---|
Language | Haskell2010 |
Synopsis
- type Effect = (* -> *) -> * -> *
- data Union (r :: [Effect]) m a where
- type Algebra r m = forall x. Union r m x -> m x
- type Algebra' r m a = Union r m a -> m a
- class (forall m n x. Coercible m n => Coercible (e m x) (e n x)) => RepresentationalEff (e :: Effect)
- decomp :: RepresentationalEff e => Union (e ': r) m a -> Either (Union r m a) (e m a)
- extract :: RepresentationalEff e => Union '[e] m a -> e m a
- weaken :: Union r m a -> Union (e ': r) m a
- absurdU :: Union '[] m a -> b
- weakenAlg :: Algebra' (e ': r) m a -> Algebra' r m a
- powerAlg :: forall e r m a. RepresentationalEff e => Algebra' r m a -> (e m a -> m a) -> Algebra' (e ': r) m a
- powerAlg' :: forall e r m a. Algebra' r m a -> (forall z. Coercible z m => e z a -> m a) -> Algebra' (e ': r) m a
- addPrim :: forall e r p m z a. Monad z => Reformulation' r p m z a -> Reformulation' (e ': r) (e ': p) m z a
- liftReform :: (MonadTrans t, Monad m) => Reformulation' r p m z a -> Reformulation' r p (t m) z a
- coerceReform :: Coercible m n => Reformulation' r p m z a -> Reformulation' r p n z a
- weakenReform :: Reformulation' (e ': r) p m z a -> Reformulation' r p m z a
- type Reformulation' r p m z a = (forall x. m x -> z x) -> Algebra p z -> Algebra' r z a
- type Reformulation r p m = forall z. Monad z => (forall x. m x -> z x) -> Algebra p z -> Algebra r z
- class RepresentationalEff e => ThreadsEff t e where
- class Threads t p where
- inj :: Member e r => e m a -> Union r m a
- class (forall i. Threads (ReaderT i) p) => ReaderThreads p
- coerceEff :: forall n m e a. (Coercible n m, RepresentationalEff e) => e m a -> e n a
- coerceAlg :: forall n m e a b. (Coercible n m, RepresentationalEff e) => (e m a -> m b) -> e n a -> n b
- data Bundle :: [Effect] -> Effect
- type family Append l r where ...
- type family FlattenBundles (e :: [Effect]) :: [Effect] where ...
- type family Members (es :: [Effect]) (r :: [Effect]) :: Constraint where ...
- type EffMembers (xs :: [Effect]) (r :: [Effect]) = Members (FlattenBundles xs) r
Documentation
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 ()
data Union (r :: [Effect]) m a where Source #
An effect for collecting multiple effects into one effect.
Behind the scenes, Union
is the most important effect
in the entire library, as the Carrier
class is built
around handling Union
s of effects.
However, even outside of defining novel Carrier
instances,
Union
can be useful as an effect in its own right.
Union
is useful for effect newtypes -- effects defined through creating a
newtype over an existing effect.
By making a newtype of Union
, it's possible to wrap multiple effects in one
newtype.
Not to be confused with Bundle
.
Unlike Bundle
, Union
is a proper effect that is given no
special treatment by Eff
or Effs
.
type Algebra r m = forall x. Union r m x -> m x Source #
An
desribes a collection of effect handlers for Algebra
r mm
over
all effects in the list r
.
type Algebra' r m a = Union r m a -> m a Source #
A first-rank type which can often be used instead of Algebra
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 |
extract :: RepresentationalEff e => Union '[e] m a -> e m a Source #
Extract the only effect of an Union
.
weakenAlg :: Algebra' (e ': r) m a -> Algebra' r m a Source #
Weaken an Algebra
by removing the topmost effect.
powerAlg :: forall e r m a. RepresentationalEff e => Algebra' r m a -> (e m a -> m a) -> Algebra' (e ': r) m a Source #
Strengthen an Algebra
by providing a handler for a new effect e
.
powerAlg' :: forall e r m a. Algebra' r m a -> (forall z. Coercible z m => e z a -> m a) -> Algebra' (e ': r) m a Source #
addPrim :: forall e r p m z a. Monad z => Reformulation' r p m z a -> Reformulation' (e ': r) (e ': p) m z a Source #
Add a primitive effect and corresponding derived effect to a Reformulation
.
liftReform :: (MonadTrans t, Monad m) => Reformulation' r p m z a -> Reformulation' r p (t m) z a Source #
Lift an m
-based Reformulation
to a t m
-based Reformulation
,
where t
is any MonadTrans
coerceReform :: Coercible m n => Reformulation' r p m z a -> Reformulation' r p n z a Source #
weakenReform :: Reformulation' (e ': r) p m z a -> Reformulation' r p m z a Source #
Weaken a Reformulation
by removing the topmost
derived effect.
type Reformulation' r p m z a = (forall x. m x -> z x) -> Algebra p z -> Algebra' r z a Source #
A less higher-rank variant of Reformulation
, which is sometimes
important.
type Reformulation r p m = forall z. Monad z => (forall x. m x -> z x) -> Algebra p z -> Algebra r z Source #
The type of reformulate
.
A
describes how the derived effects Reformulation
r p mr
are
formulated in terms of the primitive effects p
and first-order operations
of m
.
This is done by providing an
for any monad Algebra
r zz
that lifts
m
and implements an Algebra
over p
.
class RepresentationalEff e => ThreadsEff t e where Source #
An instance of ThreadsEff
represents the ability for a monad transformer
t
to thread a primitive effect e
-- i.e. lift handlers of that effect.
Instances of ThreadsEff
are accumulated into entire stacks of primitive
effects by Threads
.
You only need to make ThreadsEff
instances for monad transformers that
aren't simply newtypes over existing monad transformers. You also don't need
to make them for IdentityT
.
Instances
class Threads t p where Source #
is satisfied if Threads
t p
instances are defined for
each effect ThreadsEff
t ee
in p
. By using the
constraint, you're
able to lift Threads
t pAlgebra
s over p
from any monad m
to t m
. This is useful
when defining custom Carrier
instances.
Note that you should not place a
constraint if Threads
t pt
is
simply a newtype over an existsing monad transformer u
that already has
ThreadsEff
instances defined for it. Instead, you should place a
constraint, and use its Threads
u pthread
by coercing the resulting
algebra from
to Algebra
p (u m)
'.
That way, you avoid having to define redundant Algebra
p (t m)ThreadsEff
instances for
every newtype of a monad transformer.
Threads
forms the basis of threading constraints
(see Threaders
), and every threading constraint offered
in the library makes use of Threads
in one way or another.
inj :: Member e r => e m a -> Union r m a Source #
Inject an effect into a Union
containing that effect.
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 |
coerceEff :: forall n m e a. (Coercible n m, RepresentationalEff e) => e m a -> e n a Source #
coerceAlg :: forall n m e a b. (Coercible n m, RepresentationalEff e) => (e m a -> m b) -> e n a -> n b Source #
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:
Error
e =Bundle
'[Throw
e,Catch
e]
so
Eff
(Error
e) m = (Carrier
m,Member
(Throw
e) (Derivs
m),Member
(Catch
e) (Derivs
m))
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.
type family FlattenBundles (e :: [Effect]) :: [Effect] where ... Source #
FlattenBundles '[] = '[] | |
FlattenBundles (Bundle bs ': es) = Append (FlattenBundles bs) (FlattenBundles es) | |
FlattenBundles (e ': es) = e ': FlattenBundles es |
type EffMembers (xs :: [Effect]) (r :: [Effect]) = Members (FlattenBundles xs) r Source #