in-other-words-0.1.0.0: A higher-order effect system where the sky's the limit

Control.Effect.Internal.Union

Synopsis

# Documentation

type Effect = (* -> *) -> * -> * Source #

The kind of 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 Unions 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.

Constructors

 Union :: Coercible z m => ElemOf e r -> e z a -> Union r m a

type Algebra r m = forall x. Union r m x -> m x Source #

An Algebra r m desribes a collection of effect handlers for m 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 definition 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

Instances details
 (forall (m :: Type -> Type) (n :: Type -> Type) x. Coercible m n => Coercible (e m x) (e n x)) => RepresentationalEff e Source # Instance detailsDefined in Control.Effect.Internal.Union

decomp :: RepresentationalEff e => Union (e ': r) m a -> Either (Union r m a) (e m a) Source #

extract :: RepresentationalEff e => Union '[e] m a -> e m a Source #

Extract the only effect of an Union.

weaken :: Union r m a -> Union (e ': r) m a Source #

absurdU :: Union '[] m a -> b Source #

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 Reformulation r p m describes how the derived effects r are formulated in terms of the primitive effects p and first-order operations of m. This is done by providing an Algebra r z for any monad z 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.

Methods

threadEff :: Monad m => (forall x. e m x -> m x) -> e (t m) a -> t m a Source #

#### Instances

Instances details

class Threads t p where Source #

Threads t p is satisfied if ThreadsEff t e instances are defined for each effect e in p. By using the Threads t p constraint, you're able to lift Algebras over p from any monad m to t m. This is useful when defining custom Carrier instances.

Note that you should not place a Threads t p constraint if t is simply a newtype over an existsing monad transformer u that already has ThreadsEff instances defined for it. Instead, you should place a Threads u p constraint, and use its thread by coercing the resulting algebra from Algebra p (u m) to Algebra p (t m)'. That way, you avoid having to define redundant 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.

Methods

thread :: Monad m => Algebra p m -> Algebra p (t m) Source #

#### Instances

Instances details
 Threads t ('[] :: [Effect]) Source # Instance detailsDefined in Control.Effect.Internal.Union Methodsthread :: forall (m :: Type -> Type). Monad m => Algebra '[] m -> Algebra '[] (t m) Source # (ThreadsEff t e, Threads t p) => Threads t (e ': p) Source # Instance detailsDefined in Control.Effect.Internal.Union Methodsthread :: forall (m :: Type -> Type). Monad m => Algebra (e ': p) m -> Algebra (e ': p) (t m) Source #

inj :: Member e r => e m a -> Union r m a Source #

Inject an effect into a Union containing that effect.

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

Instances details

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 Eff/s constraint on Bundle '[eff1, eff2, ... , effn] will expand it into membership constraints for 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 Append l r where ... Source #

Equations

 Append '[] r = r Append (x ': l) r = x ': Append l r

type family FlattenBundles (e :: [Effect]) :: [Effect] where ... Source #

Equations

 FlattenBundles '[] = '[] FlattenBundles (Bundle bs ': es) = Append (FlattenBundles bs) (FlattenBundles es) FlattenBundles (e ': es) = e ': FlattenBundles es

type family Members (es :: [Effect]) (r :: [Effect]) :: Constraint where ... Source #

Equations

 Members '[] r = () Members (e ': es) r = (Member e r, Members es r)

type EffMembers (xs :: [Effect]) (r :: [Effect]) = Members (FlattenBundles xs) r Source #