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 aa
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 producer of DecAlt
f aa
, using
runCoDecAlt
. You can run this in any Conclude
context if you you
want to interpret it contravariantly, treating
as
a consumer of DecAlt
f aa
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
<!>
anddecide
(typeclass methods), useswerve
and other variants, which work specifically on this type only. - Instead of
empty
andconclude
(typeclass methods), useReject
. - Instead of using
interpret
(to run in a typeclass), either userunCoDecAlt
(to run inPlus
),runContraDecAlt
(to run inConclude
), orfoldDecAlt
(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
orinjectChain
directly. - If you have 2 components, use
toListBy
ortoChain
. - 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 aa
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 producer of DecAlt1
f aa
, using
runCoDecAlt1
. You can run this in any Decide
context if you you
want to interpret it contravariantly, treating
as
a consumer of DecAlt1
f aa
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
<!>
anddecide
(typeclass methods), useswerve1
and other variants, which work specifically on this type only. - Instead of using
interpret
(to run in a typeclass), either userunCoDecAlt1
(to run inAlt
),runContraDecAlt1
(to run inDecide
), orfoldDecAlt1
(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 |
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
.