Copyright | (c) Justin Le 2019 |
---|---|
License | BSD3 |
Maintainer | justin@jle.im |
Stability | experimental |
Portability | non-portable |
Safe Haskell | None |
Language | Haskell2010 |
Provides an Invariant
version of the typical Haskell Day convolution
over tuples.
Since: 0.3.0.0
Synopsis
- newtype DayChain f a where
- runCoDayChain :: forall f g. Applicative g => (f ~> g) -> DayChain f ~> g
- runContraDayChain :: forall f g. Divisible g => (f ~> g) -> DayChain f ~> g
- chainAp :: DayChain f ~> Ap f
- chainDiv :: DayChain f ~> Div f
- gather :: (a -> (b, c)) -> (b -> c -> a) -> DayChain f b -> DayChain f c -> DayChain f a
- gathered :: DayChain f a -> DayChain f b -> DayChain f (a, b)
- assembleDayChain :: NP f as -> DayChain f (NP I as)
- assembleDayChainRec :: Rec f as -> DayChain f (XRec Identity as)
- concatDayChain :: NP (DayChain f) as -> DayChain f (NP I as)
- concatDayChainRec :: Rec (DayChain f) as -> DayChain f (XRec Identity as)
- newtype DayChain1 f a where
- DayChain1_ {
- unDayChain1 :: Chain1 Day f a
- pattern DayChain1 :: Invariant f => (a -> (b, c)) -> (b -> c -> a) -> f b -> DayChain f c -> DayChain1 f a
- DayChain1_ {
- runCoDayChain1 :: forall f g. Apply g => (f ~> g) -> DayChain1 f ~> g
- runContraDayChain1 :: forall f g. Divise g => (f ~> g) -> DayChain1 f ~> g
- chainAp1 :: DayChain1 f ~> Ap1 f
- chainDiv1 :: DayChain1 f ~> Div1 f
- gather1 :: Invariant f => (a -> (b, c)) -> (b -> c -> a) -> DayChain1 f b -> DayChain1 f c -> DayChain1 f a
- gathered1 :: Invariant f => DayChain1 f a -> DayChain1 f b -> DayChain1 f (a, b)
- assembleDayChain1 :: Invariant f => NP f (a ': as) -> DayChain1 f (NP I (a ': as))
- assembleDayChain1Rec :: Invariant f => Rec f (a ': as) -> DayChain1 f (XRec Identity (a ': as))
- concatDayChain1 :: Invariant f => NP (DayChain1 f) (a ': as) -> DayChain1 f (NP I (a ': as))
- concatDayChain1Rec :: Invariant f => Rec (DayChain1 f) (a ': as) -> DayChain1 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
Instead of defining yet another separate free monoid like
Ap
,
Div
, or
Dec
, we re-use Chain
.
You can assemble values using the combinators in Data.HFunctor.Chain,
and then tear them down/interpret them using runCoDayChain
and
runContraDayChain
. There is no general invariant interpreter (and so no
MonoidIn
instance for Day
) because the typeclasses used to express
the target contexts are probably not worth defining given how little the
Haskell ecosystem uses invariant functors as an abstraction.
DayChain | |
|
pattern Gather :: (a -> (b, c)) -> (b -> c -> a) -> f b -> DayChain f c -> DayChain f a | Match on a non-empty |
pattern Knot :: a -> DayChain f a | Match on an "empty" |
runCoDayChain :: forall f g. Applicative g => (f ~> g) -> DayChain f ~> g Source #
In the covariant direction, we can interpret out of a Chain
of Day
into any Applicative
.
assembleDayChain :: NP f as -> DayChain f (NP I as) Source #
Convenient wrapper to build up a DayChain
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) $ assembleDayChain $ 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.
assembleDayChainRec :: Rec f as -> DayChain f (XRec Identity as) Source #
A version of assembleDayChain
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) $ assembleDayChainRec $ intPrim :& boolPrim :& stringPrim :& Nil
concatDayChain :: NP (DayChain f) as -> DayChain f (NP I as) Source #
A version of assembleDayChain
where each component is itself
a DayChain
.
assembleDayChain (x :* y :* z :* Nil) = concatDayChain (injectChain x :* injectChain y :* injectChain z :* Nil)
concatDayChainRec :: Rec (DayChain f) as -> DayChain f (XRec Identity as) Source #
A version of concatDayChain
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.
Nonempty Chain
newtype DayChain1 f a Source #
Instead of defining yet another separate free semigroup like
Ap1
,
Div1
, or
Dec1
, we re-use Chain1
.
You can assemble values using the combinators in Data.HFunctor.Chain,
and then tear them down/interpret them using runCoDayChain1
and
runContraDayChain1
. There is no general invariant interpreter (and so no
SemigroupIn
instance for Day
) because the typeclasses used to
express the target contexts are probably not worth defining given how
little the Haskell ecosystem uses invariant functors as an abstraction.
DayChain1_ | |
|
pattern DayChain1 :: Invariant f => (a -> (b, c)) -> (b -> c -> a) -> f b -> DayChain f c -> DayChain1 f a | Match on a |
gather1 :: Invariant f => (a -> (b, c)) -> (b -> c -> a) -> DayChain1 f b -> DayChain1 f c -> DayChain1 f a Source #
assembleDayChain1 :: Invariant f => NP f (a ': as) -> DayChain1 f (NP I (a ': as)) Source #
A version of assembleDayChain
but for DayChain1
instead. Can be
useful if you intend on interpreting it into something with only
a Divise
or Apply
instance, but no Divisible
or Applicative
.
assembleDayChain1Rec :: Invariant f => Rec f (a ': as) -> DayChain1 f (XRec Identity (a ': as)) Source #
A version of assembleDayChain1
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.
concatDayChain1 :: Invariant f => NP (DayChain1 f) (a ': as) -> DayChain1 f (NP I (a ': as)) Source #
A version of concatDayChain
but for DayChain1
instead. Can be
useful if you intend on interpreting it into something with only
a Divise
or Apply
instance, but no Divisible
or Applicative
.
concatDayChain1Rec :: Invariant f => Rec (DayChain1 f) (a ': as) -> DayChain1 f (XRec Identity (a ': as)) Source #
A version of concatDayChain1
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.