Copyright | (c) Justin Le 2019 |
---|---|

License | BSD3 |

Maintainer | justin@jle.im |

Stability | experimental |

Portability | non-portable |

Safe Haskell | None |

Language | Haskell2010 |

## Synopsis

- newtype DecAlt f a where
- runCoDecAlt :: forall f g. Plus g => (f ~> g) -> DecAlt f ~> g
- runContraDecAlt :: forall f g. Conclude g => (f ~> g) -> DecAlt f ~> g
- decAltListF :: Functor f => DecAlt f ~> ListF f
- decAltListF_ :: DecAlt f ~> ComposeT ListF Coyoneda f
- decAltDec :: DecAlt f ~> Dec f
- foldDecAlt :: (forall x. (x -> Void) -> g x) -> (Night f g ~> g) -> DecAlt f ~> g
- swerve :: (a -> Either b c) -> (b -> a) -> (c -> a) -> DecAlt f b -> DecAlt f c -> DecAlt f a
- swerved :: DecAlt f a -> DecAlt f b -> DecAlt f (Either a b)
- assembleDecAlt :: NP f as -> DecAlt f (NS I as)
- concatDecAlt :: NP (DecAlt f) as -> DecAlt f (NS I as)
- newtype DecAlt1 f a where
- runCoDecAlt1 :: forall f g. Alt g => (f ~> g) -> DecAlt1 f ~> g
- runContraDecAlt1 :: forall f g. Decide g => (f ~> g) -> DecAlt1 f ~> g
- decAltNonEmptyF :: Functor f => DecAlt1 f ~> NonEmptyF f
- decAltNonEmptyF_ :: DecAlt1 f ~> ComposeT NonEmptyF Coyoneda f
- decAltDec1 :: DecAlt1 f ~> Dec1 f
- foldDecAlt1 :: (f ~> g) -> (Night f g ~> g) -> DecAlt1 f ~> g
- swerve1 :: Invariant f => (a -> Either b c) -> (b -> a) -> (c -> a) -> DecAlt1 f b -> DecAlt1 f c -> DecAlt1 f a
- swerved1 :: Invariant f => DecAlt1 f a -> DecAlt1 f b -> DecAlt1 f (Either a b)
- assembleDecAlt1 :: Invariant f => NP f (a ': as) -> DecAlt1 f (NS I (a ': as))
- concatDecAlt1 :: Invariant f => NP (DecAlt1 f) (a ': as) -> DecAlt1 f (NS I (a ': as))

# Chain

The invariant version of `ListF`

and `Dec`

: combines the capabilities of
both `ListF`

and `Dec`

together.

Conceptually you can think of

as a way of consuming and
producing `DecAlt`

f a`a`

s that contains a collection of `f x`

s of different `x`

s.
When interpreting this, a *specific* `f`

is chosen to handle the
interpreting; the `a`

is sent to that `f`

, and the single result is
returned back out.

You run this in any `Plus`

context if you want to interpret it
covariantly, treating

as a `DecAlt`

f a*producer* of `a`

, using
`runCoDecAlt`

. You can run this in any `Conclude`

context if you you
want to interpret it contravariantly, treating

as
a `DecAlt`

f a*consumer* of `a`

s, using `runContraDecAlt`

.

Because there is no typeclass that combines both `Plus`

and
`Conclude`

, this type is a little bit tricker to construct/use than
`ListF`

or `Dec`

.

- Instead of
`<!>`

and`decide`

(typeclass methods), use`swerve`

and other variants, which work specifically on this type only. - Instead of
`empty`

and`conclude`

(typeclass methods), use`Reject`

. - Instead of using
`interpret`

(to run in a typeclass), either use`runCoDecAlt`

(to run in`Plus`

),`runContraDecAlt`

(to run in`Conclude`

), or`foldDecAlt`

(to interpret by manually providing handlers)

You can also extract the `ListF`

part out using `decAltListF`

, and
extract the `Dec`

part out using `decAltDec`

.

Note that this type's utility is similar to that of

,
except `PostT`

`Dec`

lets you use `PostT`

`Dec`

`Conclude`

typeclass methods to
assemble it.

*Since: 0.3.5.0*

pattern Swerve :: (a -> Either b c) -> (b -> a) -> (c -> a) -> f b -> DecAlt f c -> DecAlt f a | Match on a non-empty |

pattern Reject :: (a -> Void) -> DecAlt f a | Match on an "empty" |

swerve :: (a -> Either b c) -> (b -> a) -> (c -> a) -> DecAlt f b -> DecAlt f c -> DecAlt f a Source #

assembleDecAlt :: NP f as -> DecAlt f (NS I as) Source #

Convenient wrapper to build up a `DecAlt`

on by providing each
component of it. This makes it much easier to build up longer chains
because you would only need to write the splitting/joining functions in
one place.

For example, if you had a data type

data MyType = MTI Int | MTB Bool | MTS String

and an invariant functor `Prim`

(representing, say, a bidirectional
parser, where `Prim Int`

is a bidirectional parser for an `Int`

```
),
then you could assemble a bidirectional parser for a
```

MyType@ using:

invmap (case MTI x -> Z (I x); MTB y -> S (Z (I y)); MTS z -> S (S (Z (I z)))) (case Z (I x) -> MTI x; S (Z (I y)) -> MTB y; S (S (Z (I z))) -> MTS z) $ assembleDecAlt $ intPrim :* boolPrim :* stringPrim :* Nil

Some notes on usefulness depending on how many components you have:

- If you have 0 components, use
`Reject`

directly. - If you have 1 component, use
`inject`

or`injectChain`

directly. - If you have 2 components, use
`toListBy`

or`toChain`

. - If you have 3 or more components, these combinators may be useful; otherwise you'd need to manually peel off eithers one-by-one.

concatDecAlt :: NP (DecAlt f) as -> DecAlt f (NS I as) Source #

A version of `assembleDecAlt`

where each component is itself
a `DecAlt`

.

assembleDecAlt (x :* y :* z :* Nil) = concatDecAlt (injectChain x :* injectChain y :* injectChain z :* Nil)

# Nonempty Chain

The invariant version of `NonEmptyF`

and `Dec1`

: combines the
capabilities of both `NonEmptyF`

and `Dec1`

together.

Conceptually you can think of

as a way of consuming and
producing `DecAlt1`

f a`a`

s that contains a (non-empty) collection of `f x`

s of
different `x`

s. When interpreting this, a *specific* `f`

is chosen to
handle the interpreting; the `a`

is sent to that `f`

, and the single
result is returned back out.

You run this in any `Alt`

context if you want to interpret it
covariantly, treating

as a `DecAlt1`

f a*producer* of `a`

, using
`runCoDecAlt1`

. You can run this in any `Decide`

context if you you
want to interpret it contravariantly, treating

as
a `DecAlt1`

f a*consumer* of `a`

s, using `runContraDecAlt1`

.

Because there is no typeclass that combines both `Alt`

and
`Decide`

, this type is a little bit tricker to construct/use than
`NonEmptyF`

or `Dec1`

.

- Instead of
`<!>`

and`decide`

(typeclass methods), use`swerve1`

and other variants, which work specifically on this type only. - Instead of using
`interpret`

(to run in a typeclass), either use`runCoDecAlt1`

(to run in`Alt`

),`runContraDecAlt1`

(to run in`Decide`

), or`foldDecAlt1`

(to interpret by manually providing handlers)

You can also extract the `NonEmptyF`

part out using `decAltNonEmptyF`

, and
extract the `Dec1`

part out using `decAltDec1`

.

Note that this type's utility is similar to that of

,
except `PostT`

`Dec1`

lets you use `PostT`

`Dec1`

`Decide`

typeclass methods to
assemble it.

*Since: 0.3.5.0*

pattern DecAlt1 :: Invariant f => (a -> Either b c) -> (b -> a) -> (c -> a) -> f b -> DecAlt f c -> DecAlt1 f a | Match on a |

#### Instances

HTraversable DecAlt1 Source # | |

Defined in Data.HFunctor.Chain.Internal | |

HTraversable1 DecAlt1 Source # | |

Defined in Data.HFunctor.Chain.Internal | |

Invariant f => Invariant (DecAlt1 f) Source # | |

Defined in Data.HFunctor.Chain.Internal | |

Inject DecAlt1 Source # | |

HFunctor DecAlt1 Source # | |

swerve1 :: Invariant f => (a -> Either b c) -> (b -> a) -> (c -> a) -> DecAlt1 f b -> DecAlt1 f c -> DecAlt1 f a Source #

assembleDecAlt1 :: Invariant f => NP f (a ': as) -> DecAlt1 f (NS I (a ': as)) Source #

A version of `assembleDecAlt`

but for `DecAlt1`

instead. Can
be useful if you intend on interpreting it into something with only
a `Decide`

or `Alt`

instance, but no
`Decidable`

or `Plus`

or
`Alternative`

.