functor-combinators-0.4.1.1: Tools for functor combinator-based program design
Copyright(c) Justin Le 2019
LicenseBSD3
Maintainerjustin@jle.im
Stabilityexperimental
Portabilitynon-portable
Safe HaskellSafe-Inferred
LanguageHaskell2010

Data.Functor.Invariant.Internative.Free

Description

Provide an invariant functor combinator choice-collector, like a combination of ListF and Dec.

This module was named DecAlt before v0.4.0.0

Since: 0.4.0.0

Synopsis

Chain

newtype DecAlt f a Source #

The invariant version of ListF and Dec: combines the capabilities of both ListF and Dec together.

Conceptually you can think of DecAlt f a as a way of consuming and producing as that contains a collection of f xs of different xs. 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.

To do this, the main tools to combine DecAlts are its Inalt instance, using swerve to combine two DecAlts in a choice-like manner (with the choosing and re-injecting function), and its Inplus instance, using reject to create an "empty" choice that is never taken.

This does have an Interpret function, but the target typeclass (Inplus) doesn't have too many useful instances. Instead, you are probably going to run it into either Plus instance (to "produce" an a from a DecAlt f a) with runCoDecAlt, or a Choose instance (to "consume" an a from a DecAlt f a) with runContraDecAlt.

If you think of this type as a combination of ListF and Dec, then 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 PostT Dec, except PostT Dec lets you use Conclude typeclass methods to assemble it.

Since: 0.3.5.0

Constructors

DecAlt 

Fields

Bundled Patterns

pattern Swerve :: (b -> a) -> (c -> a) -> (a -> Either b c) -> f b -> DecAlt f c -> DecAlt f a

Match on a non-empty DecAlt; 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) -> DecAlt f a

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

Instances

Instances details
Inject DecAlt Source # 
Instance details

Defined in Data.HFunctor.Chain.Internal

Methods

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

FreeOf Inplus DecAlt Source #

Since: 0.4.0.0

Instance details

Defined in Data.HFunctor.Final

Associated Types

type FreeFunctorBy DecAlt :: (Type -> Type) -> Constraint Source #

Methods

fromFree :: forall (f :: Type -> Type). DecAlt f ~> Final Inplus f Source #

toFree :: forall (f :: Type -> Type). FreeFunctorBy DecAlt f => Final Inplus f ~> DecAlt f Source #

HTraversable DecAlt Source # 
Instance details

Defined in Data.HFunctor.Chain.Internal

Methods

htraverse :: forall h f g (a :: k1). Applicative h => (forall (x :: k). f x -> h (g x)) -> DecAlt f a -> h (DecAlt g a) Source #

Inplus f => Interpret DecAlt (f :: Type -> TYPE LiftedRep) Source #

A free Inplus

Instance details

Defined in Data.HFunctor.Chain.Internal

Methods

retract :: DecAlt f ~> f Source #

interpret :: forall (g :: k -> Type). (g ~> f) -> DecAlt g ~> f Source #

Inalt (DecAlt f) Source # 
Instance details

Defined in Data.Functor.Invariant.Internative.Free

Methods

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

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

Inplus (DecAlt f) Source # 
Instance details

Defined in Data.Functor.Invariant.Internative.Free

Methods

reject :: (a -> Void) -> DecAlt f a Source #

Invariant (DecAlt f) Source # 
Instance details

Defined in Data.HFunctor.Chain.Internal

Methods

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

HFunctor DecAlt Source # 
Instance details

Defined in Data.HFunctor.Chain.Internal

Methods

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

type FreeFunctorBy DecAlt Source # 
Instance details

Defined in Data.HFunctor.Final

runCoDecAlt :: forall f g. Plus g => (f ~> g) -> DecAlt f ~> g Source #

In the covariant direction, we can interpret into any Plus.

In theory, this shouldn't never be necessary, because you should just be able to use interpret, since any instance of Plus is also an instance of Inplus. However, this can be handy if you are using an instance of Plus that has no Inplus instance. Consider also unsafeInplusCo if you are using a specific, concrete type for g.

runContraDecAlt :: forall f g. Conclude g => (f ~> g) -> DecAlt f ~> g Source #

In the contravariant direction, we can interpret into any Decide.

In theory, this shouldn't never be necessary, because you should just be able to use interpret, since any instance of Conclude is also an instance of Inplus. However, this can be handy if you are using an instance of Conclude that has no Inplus instance. Consider also unsafeInplusContra if you are using a specific, concrete type for g.

decAltListF :: Functor f => DecAlt f ~> ListF f Source #

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

Since: 0.3.2.0

decAltListF_ :: DecAlt f ~> ComposeT ListF Coyoneda f Source #

Extract the ListF part out of a DecAlt, 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

decAltDec :: DecAlt f ~> Dec f Source #

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

foldDecAlt :: (forall x. (x -> Void) -> g x) -> (Night f g ~> g) -> DecAlt f ~> g Source #

General-purpose folder of DecAlt. Provide a way to handle the identity (emptyconcludeReject) and a way to handle a cons (<!>decideswerve).

Since: 0.3.5.0

assembleDecAlt :: NP f as -> DecAlt f (NS I as) Source #

Convenient wrapper to build up a DecAlt on by providing each branch 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 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.

If each component is itself a DecAlt f (instead of f), you can use concatInplus.

Nonempty Chain

newtype DecAlt1 f a Source #

The invariant version of NonEmptyF and Dec1: combines the capabilities of both NonEmptyF and Dec1 together.

Conceptually you can think of DecAlt1 f a as a way of consuming and producing as that contains a (non-empty) collection of f xs of different xs. 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.

To do this, the main tools to combine DecAlt1s are its Inalt instance, using swerve to combine two DecAlt1s in a choice-like manner (with the choosing and re-injecting function).

This does have an Interpret function, but the target typeclass (Inalt) doesn't have too many useful instances. Instead, you are probably going to run it into either an Alt instance (to "produce" an a from a DecAlt1 f a) with runCoDecAlt1, or a Decide instance (to "consume" an a from a DecAlt1 f a) with runContraDecAlt1.

If you think of this type as a combination of NonEmptyF and Dec1, then 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 PostT Dec1, except PostT Dec1 lets you use Decide typeclass methods to assemble it.

Since: 0.3.5.0

Constructors

DecAlt1_ 

Fields

Bundled Patterns

pattern DecAlt1 :: Invariant f => (b -> a) -> (c -> a) -> (a -> Either b c) -> f b -> DecAlt f c -> DecAlt1 f a

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

Instances

Instances details
FreeOf Inalt DecAlt1 Source #

Since: 0.4.0.0

Instance details

Defined in Data.HFunctor.Final

Associated Types

type FreeFunctorBy DecAlt1 :: (Type -> Type) -> Constraint Source #

Methods

fromFree :: forall (f :: Type -> Type). DecAlt1 f ~> Final Inalt f Source #

toFree :: forall (f :: Type -> Type). FreeFunctorBy DecAlt1 f => Final Inalt f ~> DecAlt1 f Source #

HTraversable DecAlt1 Source # 
Instance details

Defined in Data.HFunctor.Chain.Internal

Methods

htraverse :: forall h f g (a :: k1). Applicative h => (forall (x :: k). f x -> h (g x)) -> DecAlt1 f a -> h (DecAlt1 g a) Source #

HTraversable1 DecAlt1 Source # 
Instance details

Defined in Data.HFunctor.Chain.Internal

Methods

htraverse1 :: forall h f g (a :: k1). Apply h => (forall (x :: k). f x -> h (g x)) -> DecAlt1 f a -> h (DecAlt1 g a) Source #

Inalt f => Interpret DecAlt1 (f :: Type -> TYPE LiftedRep) Source #

A free Inalt

Instance details

Defined in Data.HFunctor.Chain.Internal

Methods

retract :: DecAlt1 f ~> f Source #

interpret :: forall (g :: k -> Type). (g ~> f) -> DecAlt1 g ~> f Source #

Invariant f => Inalt (DecAlt1 f) Source # 
Instance details

Defined in Data.Functor.Invariant.Internative.Free

Methods

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

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

Invariant f => Invariant (DecAlt1 f) Source # 
Instance details

Defined in Data.HFunctor.Chain.Internal

Methods

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

Inject DecAlt1 Source # 
Instance details

Defined in Data.HFunctor.Chain.Internal

Methods

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

HFunctor DecAlt1 Source # 
Instance details

Defined in Data.HFunctor.Chain.Internal

Methods

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

type FreeFunctorBy DecAlt1 Source # 
Instance details

Defined in Data.HFunctor.Final

runCoDecAlt1 :: forall f g. Alt g => (f ~> g) -> DecAlt1 f ~> g Source #

In the covariant direction, we can interpret into any Alt.

In theory, this shouldn't never be necessary, because you should just be able to use interpret, since any instance of Alt is also an instance of Inalt. However, this can be handy if you are using an instance of Alt that has no Inalt instance. Consider also unsafeInaltCo if you are using a specific, concrete type for g.

runContraDecAlt1 :: forall f g. Decide g => (f ~> g) -> DecAlt1 f ~> g Source #

In the contravariant direction, we can interpret into any Decide.

In theory, this shouldn't never be necessary, because you should just be able to use interpret, since any instance of Decide is also an instance of Inalt. However, this can be handy if you are using an instance of Decide that has no Inalt instance. Consider also unsafeInaltContra if you are using a specific, concrete type for g.

decAltNonEmptyF :: Functor f => DecAlt1 f ~> NonEmptyF f Source #

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

Since: 0.3.2.0

decAltNonEmptyF_ :: DecAlt1 f ~> ComposeT NonEmptyF Coyoneda f Source #

Extract the NonEmptyF part out of a DecAlt1, 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

decAltDec1 :: DecAlt1 f ~> Dec1 f Source #

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

foldDecAlt1 :: (f ~> g) -> (Night f g ~> g) -> DecAlt1 f ~> g Source #

General-purpose folder of DecAlt1. Provide a way to handle the individual leaves and a way to handle a cons (<!>decideswerve).

Since: 0.3.5.0

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.

If each component is itself a DecAlt1 f (instead of f), you can use concatInalt.

Orphan instances

Inalt (DecAlt f) Source # 
Instance details

Methods

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

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

Invariant f => Inalt (DecAlt1 f) Source # 
Instance details

Methods

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

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

Inplus (DecAlt f) Source # 
Instance details

Methods

reject :: (a -> Void) -> DecAlt f a Source #