functor-combinators-0.3.4.0: Tools for functor combinator-based program design
Safe HaskellNone
LanguageHaskell2010

Data.Functor.Invariant.Night.Chain

Synopsis

Chain

data NightChain f a Source #

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 runCoNightChain and runContraNightChain. There is no general invariant interpreter (and so no MonoidIn instance for Night) 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.

Instances

Instances details
Inject NightChain Source # 
Instance details

Defined in Data.HFunctor.Chain.Internal

Methods

inject :: forall (f :: k -> Type). f ~> NightChain f Source #

Invariant (NightChain f) Source # 
Instance details

Defined in Data.HFunctor.Chain.Internal

Methods

invmap :: (a -> b) -> (b -> a) -> NightChain f a -> NightChain f b #

HFunctor NightChain Source # 
Instance details

Defined in Data.HFunctor.Chain.Internal

Methods

hmap :: forall (f :: k -> Type) (g :: k -> Type). (f ~> g) -> NightChain f ~> NightChain g Source #

pattern Swerve :: (a -> Either b c) -> (b -> a) -> (c -> a) -> f b -> NightChain f c -> NightChain f a Source #

Match on a non-empty NightChain; contains the splitting function, the two rejoining functions, the first f, and the rest of the chain. Analogous to the Choose constructor.

pattern Reject :: (a -> Void) -> NightChain f a Source #

Match on an "empty" NightChain; contains no fs, but only the terminal value. Analogous to the Lose constructor.

runCoNightChain :: forall f g. Plus g => (f ~> g) -> NightChain f ~> g Source #

In the covariant direction, we can interpret out of a Chain of Night into any Plus.

runContraNightChain :: forall f g. Conclude g => (f ~> g) -> NightChain f ~> g Source #

In the contravariant direction, we can interpret out of a Chain of Night into any Conclude.

chainListF :: Functor f => NightChain f ~> ListF f Source #

Extract the ListF part out of a NightChain, shedding the contravariant bits.

Since: 0.3.2.0

chainListF_ :: NightChain f ~> ComposeT ListF Coyoneda f Source #

Extract the ListF part out of a NightChain, shedding the contravariant bits.

This version does not require a Functor constraint because it converts to the coyoneda-wrapped product, which is more accurately the true conversion to a covariant chain.

Since: 0.3.2.0

chainDec :: NightChain f ~> Dec f Source #

Extract the Dec part out of a NightChain, shedding the covariant bits.

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

Invariantly combine two NightChains.

Analogous to <|> and decide. If there was some typeclass that represented semigroups on invariant Night, this would be the method of that typeclass.

The identity of this is Reject.

Since: 0.3.4.0

swerved :: NightChain f a -> NightChain f b -> NightChain f (Either a b) Source #

Convenient wrapper over swerve that simply combines the two options in an Either. Analogous to <|> and decided.

Since: 0.3.4.0

assembleNightChain :: NP f as -> NightChain f (NS I as) Source #

Convenient wrapper to build up a NightChain 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) $
  assembleNightChain $ 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.

concatNightChain :: NP (NightChain f) as -> NightChain f (NS I as) Source #

A version of assembleNightChain where each component is itself a NightChain.

assembleNightChain (x :* y :* z :* Nil)
  = concatNightChain (injectChain x :* injectChain y :* injectChain z :* Nil)

Nonempty Chain

data NightChain1 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 runCoNightChain1 and runContraNightChain1. There is no general invariant interpreter (and so no SemigroupIn instance for Night) 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.

Instances

Instances details
Invariant f => Invariant (NightChain1 f) Source # 
Instance details

Defined in Data.HFunctor.Chain.Internal

Methods

invmap :: (a -> b) -> (b -> a) -> NightChain1 f a -> NightChain1 f b #

Inject NightChain1 Source # 
Instance details

Defined in Data.HFunctor.Chain.Internal

Methods

inject :: forall (f :: k -> Type). f ~> NightChain1 f Source #

HFunctor NightChain1 Source # 
Instance details

Defined in Data.HFunctor.Chain.Internal

Methods

hmap :: forall (f :: k -> Type) (g :: k -> Type). (f ~> g) -> NightChain1 f ~> NightChain1 g Source #

pattern NightChain1 :: Invariant f => (a -> Either b c) -> (b -> a) -> (c -> a) -> f b -> NightChain f c -> NightChain1 f a Source #

Match on a NightChain1 to get the head and the rest of the items. Analogous to the Dec1 constructor.

runCoNightChain1 :: forall f g. Alt g => (f ~> g) -> NightChain1 f ~> g Source #

In the covariant direction, we can interpret out of a Chain1 of Night into any Alt.

runContraNightChain1 :: forall f g. Decide g => (f ~> g) -> NightChain1 f ~> g Source #

In the contravariant direction, we can interpret out of a Chain1 of Night into any Decide.

chainNonEmptyF :: Functor f => NightChain1 f ~> NonEmptyF f Source #

Extract the NonEmptyF part out of a NightChain1, shedding the contravariant bits.

Since: 0.3.2.0

chainNonEmptyF_ :: NightChain1 f ~> ComposeT NonEmptyF Coyoneda f Source #

Extract the NonEmptyF part out of a NightChain1, shedding the contravariant bits.

This version does not require a Functor constraint because it converts to the coyoneda-wrapped product, which is more accurately the true conversion to a covariant chain.

Since: 0.3.2.0

chainDec1 :: NightChain1 f ~> Dec1 f Source #

Extract the Dec1 part out of a NightChain1, shedding the covariant bits.

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

Invariantly combine two NightChain1s.

Analogous to <|> and decide. If there was some typeclass that represented semigroups on invariant Night, this would be the method of that typeclass.

Since: 0.3.4.0

swerved1 :: Invariant f => NightChain1 f a -> NightChain1 f b -> NightChain1 f (Either a b) Source #

Convenient wrapper over swerve1 that simply combines the two options in an Either. Analogous to <|> and decided.

Since: 0.3.4.0

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

A version of assembleNightChain but for NightChain1 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.

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

A version of concatNightChain but for NightChain1 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.