| Copyright | (c) Justin Le 2019 |
|---|---|
| License | BSD3 |
| Maintainer | justin@jle.im |
| Stability | experimental |
| Portability | non-portable |
| Safe Haskell | None |
| Language | Haskell2010 |
Data.Functor.Invariant.Day.Chain
Contents
Description
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.
Constructors
| DayChain | |
Fields
| |
Bundled Patterns
| 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
Knotdirectly. - If you have 1 component, use
injectorinjectChaindirectly. - If you have 2 components, use
toListByortoChain. - 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.
Constructors
| DayChain1_ | |
Fields
| |
Bundled Patterns
| 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.