Copyright | (c) Justin Le 2019 |
---|---|
License | BSD3 |
Maintainer | justin@jle.im |
Stability | experimental |
Portability | non-portable |
Safe Haskell | None |
Language | Haskell2010 |
Synopsis
- newtype DivAp f a where
- runCoDivAp :: forall f g. Applicative g => (f ~> g) -> DivAp f ~> g
- runContraDivAp :: forall f g. Divisible g => (f ~> g) -> DivAp f ~> g
- divApAp :: DivAp f ~> Ap f
- divApDiv :: DivAp f ~> Div f
- foldDivAp :: (forall x. x -> g x) -> (Day f g ~> g) -> DivAp f ~> g
- assembleDivAp :: NP f as -> DivAp f (NP I as)
- assembleDivApRec :: Rec f as -> DivAp f (XRec Identity as)
- newtype DivAp1 f a where
- runCoDivAp1 :: forall f g. Apply g => (f ~> g) -> DivAp1 f ~> g
- runContraDivAp1 :: forall f g. Divise g => (f ~> g) -> DivAp1 f ~> g
- divApAp1 :: DivAp1 f ~> Ap1 f
- divApDiv1 :: DivAp1 f ~> Div1 f
- foldDivAp1 :: (f ~> g) -> (Day f g ~> g) -> DivAp1 f ~> g
- assembleDivAp1 :: Invariant f => NP f (a ': as) -> DivAp1 f (NP I (a ': as))
- assembleDivAp1Rec :: Invariant f => Rec f (a ': as) -> DivAp1 f (XRec Identity (a ': as))
- runDayApply :: forall f g h. Apply h => (f ~> h) -> (g ~> h) -> Day f g ~> h
- runDayDivise :: forall f g h. Divise h => (f ~> h) -> (g ~> h) -> Day f g ~> h
Chain
The invariant version of Ap
and Div
: combines the capabilities of
both Ap
and Div
together.
Conceptually you can think of
as a way of consuming and
producing DivAp
f aa
s that contains a collection of f x
s of different x
s.
When interpreting this, each a
is distributed across all f x
s to
each interpret, and then re-combined again to produce the resulting a
.
To do this, the main tools to combine DivAp
s are its Inply
instance, using gather
to combine two DivAp
s in a choice-like
manner (with the splitting and re-combining function), and its
Inplicative
instance, using knot
to create an "empty" branch that
does not contribute to the structure.
This does have an Interpret
function, but the target typeclass
(Inplicative
) doesn't have too many useful instances. Instead, you
are probably going to run it into either Applicative
instance (to
"produce" an a
from a
) with DivAp
f arunCoDivAp
, or
a Divisible
instance (to "consume" an a
from a
) with
DivAp
f arunContraDivAp
.
If you think of this type as a combination of Ap
and Div
, then
you can also extract the Ap
part out using divApAp
, and
extract the Div
part out using divApDiv
.
Note that this type's utility is similar to that of
,
except PreT
Ap
lets you use PreT
Ap
Applicative
typeclass methods to
assemble it.
Since: 0.3.5.0
pattern Gather :: (b -> c -> a) -> (a -> (b, c)) -> f b -> DivAp f c -> DivAp f a | Match on a non-empty Note that the order of the first two arguments has swapped as of v0.4.0.0 |
pattern Knot :: a -> DivAp f a | Match on an "empty" |
Instances
FreeOf Inplicative DivAp Source # | Since: 0.4.0.0 |
Defined in Data.HFunctor.Final type FreeFunctorBy DivAp :: (Type -> Type) -> Constraint Source # | |
Invariant (DivAp f) Source # | |
Defined in Data.HFunctor.Chain.Internal | |
Inplicative (DivAp f) Source # | The free |
Defined in Data.Functor.Invariant.Inplicative.Free | |
Inply (DivAp f) Source # | |
Inject DivAp Source # | |
Inplicative f => Interpret DivAp (f :: Type -> Type) Source # | A free |
HFunctor DivAp Source # | |
HTraversable DivAp Source # | |
Defined in Data.HFunctor.Chain.Internal | |
type FreeFunctorBy DivAp Source # | |
Defined in Data.HFunctor.Final |
runCoDivAp :: forall f g. Applicative g => (f ~> g) -> DivAp f ~> g Source #
In the covariant direction, we can interpret out of a Chain
of Day
into any Applicative
.
runContraDivAp :: forall f g. Divisible g => (f ~> g) -> DivAp f ~> g Source #
In the contravariant direction, we can interpret out of a Chain
of
Day
into any Divisible
.
assembleDivAp :: NP f as -> DivAp f (NP I as) Source #
Convenient wrapper to build up a DivAp
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 = MT Int Bool 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 ((MyType x y z) -> I x :* I y :* I z :* Nil) ((I x :* I y :* I z :* Nil) -> MyType x y z) $ assembleDivAp $ intPrim :* boolPrim :* stringPrim :* Nil
Some notes on usefulness depending on how many components you have:
- If you have 0 components, use
Knot
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 tuples one-by-one.
If each component is itself a
(instead of DivAp
ff
), you can use
concatInplicative
.
assembleDivApRec :: Rec f as -> DivAp f (XRec Identity as) Source #
A version of assembleDivAp
using XRec
from vinyl instead of
NP
from sop-core. This can be more convenient because it doesn't
require manual unwrapping/wrapping of components.
data MyType = MT Int Bool String invmap ((MyType x y z) -> x ::& y ::& z ::& RNil) ((x ::& y ::& z ::& RNil) -> MyType x y z) $ assembleDivApRec $ intPrim :& boolPrim :& stringPrim :& Nil
If each component is itself a
(instead of DivAp
ff
), you can use
concatDivApRec
.
Nonempty Chain
The invariant version of Ap1
and Div1
: combines the capabilities
of both Ap1
and Div1
together.
Conceptually you can think of
as a way of consuming and
producing DivAp1
f aa
s that contains a (non-empty) collection of f x
s of
different x
s. When interpreting this, each a
is distributed across
all f x
s to each interpret, and then re-combined again to produce the
resulting a
.
To do this, the main tools to combine DivAp1
s are its Inply
instance, using gather
to combine two DivAp1
s in
a parallel-fork-like manner (with the splitting and re-combining
function).
This does have an Interpret
function, but the target typeclass
(Inply
) doesn't have too many useful instances. Instead, you are
probably going to run it into either Apply
instance (to "produce" an
a
from a
) with DivAp1
f arunCoDivAp1
, or a Divise
instance
(to "consume" an a
from a
) with DivAp1
f arunContraDivAp1
.
If you think of this type as a combination of Ap1
and Div1
, then
you can also extract the Ap1
part out using divApAp1
, and
extract the Div1
part out using divApDiv1
.
Note that this type's utility is similar to that of
,
except PreT
Ap1
lets you use PreT
Ap1
Apply
typeclass methods to assemble
it.
Since: 0.3.5.0
pattern DivAp1 :: Invariant f => (b -> c -> a) -> (a -> (b, c)) -> f b -> DivAp f c -> DivAp1 f a | Match on a Note that the order of the first two arguments has swapped as of v0.4.0.0 |
Instances
FreeOf Inply DivAp1 Source # | Since: 0.4.0.0 |
Invariant f => Invariant (DivAp1 f) Source # | |
Defined in Data.HFunctor.Chain.Internal | |
Invariant f => Inply (DivAp1 f) Source # | The free |
Inject DivAp1 Source # | |
Inply f => Interpret DivAp1 (f :: Type -> Type) Source # | A free |
HFunctor DivAp1 Source # | |
HTraversable DivAp1 Source # | |
Defined in Data.HFunctor.Chain.Internal | |
HTraversable1 DivAp1 Source # | |
Defined in Data.HFunctor.Chain.Internal htraverse1 :: forall h f g (a :: k). Apply h => (forall (x :: k). f x -> h (g x)) -> DivAp1 f a -> h (DivAp1 g a) Source # | |
type FreeFunctorBy DivAp1 Source # | |
Defined in Data.HFunctor.Final |
runCoDivAp1 :: forall f g. Apply g => (f ~> g) -> DivAp1 f ~> g Source #
In the covariant direction, we can interpret out of a Chain1
of Day
into any Apply
.
assembleDivAp1 :: Invariant f => NP f (a ': as) -> DivAp1 f (NP I (a ': as)) Source #
A version of assembleDivAp
but for DivAp1
instead. Can be
useful if you intend on interpreting it into something with only
a Divise
or Apply
instance, but no Divisible
or Applicative
.
If each component is itself a
(instead of DivAp1
ff
), you can use
concatInply
.
assembleDivAp1Rec :: Invariant f => Rec f (a ': as) -> DivAp1 f (XRec Identity (a ': as)) Source #
A version of assembleDivAp1
using XRec
from vinyl instead of
NP
from sop-core. This can be more convenient because it doesn't
require manual unwrapping/wrapping of components.
If each component is itself a
(instead of DivAp1
ff
), you can use
concatDivAp1Rec
.
Day Utility
runDayApply :: forall f g h. Apply h => (f ~> h) -> (g ~> h) -> Day f g ~> h Source #
Interpret the covariant part of a Day
into a target context h
,
as long as the context is an instance of Apply
. The Apply
is used to
combine results back together using <*>
.