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 m`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

(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 m`r`

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 z`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`

.

#### Instances

class Threads t p where Source #

is satisfied if `Threads`

t p

instances are defined for
each effect `ThreadsEff`

t e`e`

in `p`

. By using the

constraint, you're
able to lift `Threads`

t p`Algebra`

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 p`t`

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 p`thread`

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 #