Copyright | (c) 2016 Allele Dev; 2017 Ixperta Solutions s.r.o.; 2017 Alexis King |
---|---|

License | BSD3 |

Maintainer | Alexis King <lexi.lambda@gmail.com> |

Stability | experimental |

Portability | GHC specific language extensions. |

Safe Haskell | None |

Language | Haskell2010 |

These are internal definitions and should be used with caution. There are no guarantees that the API of this module will be preserved between minor versions of this package.

Open unions (type-indexed co-products, i.e. type-indexed sums) for extensible effects All operations are constant-time.

Based on OpenUnion51.hs.

Type-list `r :: [* -> *]`

of open union components is a small Universe.
Therefore, we can use a `Typeable`

-like evidence in that universe. In our
case a simple index of an element in the type-list is sufficient
substitution for `Typeable`

.

- data Union (r :: [* -> *]) a where
- unsafeInj :: Word -> t a -> Union r a
- unsafePrj :: Word -> Union r a -> Maybe (t a)
- newtype P t r = P {}
- class FindElem (t :: * -> *) (r :: [* -> *]) where
- class IfNotFound (t :: * -> *) (r :: [* -> *]) (w :: [* -> *])
- class FindElem eff effs => Member (eff :: * -> *) effs where
- decomp :: Union (t ': r) a -> Either (Union r a) (t a)
- decomp0 :: Union '[t] a -> Either (Union '[] a) (t a)
- extract :: Union '[t] a -> t a
- weaken :: Union r a -> Union (any ': r) a
- type family xs :++: ys where ...
- class Weakens q where

# Documentation

data Union (r :: [* -> *]) a where Source #

Open union is a strong sum (existential with an evidence).

unsafePrj :: Word -> Union r a -> Maybe (t a) Source #

Project a value of type

into a possible
summand of the type `Union`

(t ': r) :: * -> *`t :: * -> *`

. `Nothing`

means that `t :: * -> *`

is not
the value stored in the

.`Union`

(t ': r) :: * -> *

It is assumed that summand is stored in the `Union`

when the `Word`

value is
the same value as is stored in the `Union`

.

**This function is unsafe.**

*O(1)*

Represents position of element `t :: * -> *`

in a type list
`r :: [* -> *]`

.

class FindElem (t :: * -> *) (r :: [* -> *]) where Source #

Find an index of an element `t :: * -> *`

in a type list `r :: [* -> *]`

.
The element must exist. The `w :: [* -> *]`

type represents the entire list,
prior to recursion, and it is used to produce better type errors.

This is essentially a compile-time computation without run-time overhead.

Position of the element `t :: * -> *`

in a type list `r :: [* -> *]`

.

Position is computed during compilation, i.e. there is no run-time overhead.

*O(1)*

class IfNotFound (t :: * -> *) (r :: [* -> *]) (w :: [* -> *]) Source #

Instance resolution for this class fails with a custom type error
if `t :: * -> *`

is not in the list `r :: [* -> *]`

.

IfNotFound t r w Source # | Pass if |

TypeError Constraint ((:$$:) ((:$$:) ((:<>:) ((:<>:) (Text "\8216") (ShowType (* -> *) t)) (Text "\8217 is not a member of the type-level list")) ((:<>:) ((:<>:) (Text " \8216") (ShowType [* -> *] w)) (Text "\8217"))) ((:<>:) ((:<>:) (Text "In the constraint (") (ShowType Constraint (Member t w))) (Text ")"))) => IfNotFound t ([] (* -> *)) w Source # | If we reach an empty list, that’s a failure, since it means the type isn’t in the list. For GHC >=8, we can render a custom type error that explicitly states what went wrong. |

IfNotFound t r w => IfNotFound t ((:) (* -> *) t' r) w Source # | |

IfNotFound t ((:) (* -> *) t r) w Source # | |

class FindElem eff effs => Member (eff :: * -> *) effs where Source #

A constraint that requires that a particular effect, `eff`

, is a member of
the type-level list `effs`

. This is used to parameterize an
`Eff`

computation over an arbitrary list of effects, so
long as `eff`

is *somewhere* in the list.

For example, a computation that only needs access to a cell of mutable state
containing an `Integer`

would likely use the following type:

`Member`

(`State`

`Integer`

) effs =>`Eff`

effs ()

inj :: eff a -> Union effs a Source #

Takes a request of type `t :: * -> *`

, and injects it into the
`Union`

.

*O(1)*

(FindElem t r, IfNotFound t r r) => Member t r Source # | |