vinyl-0.9.0: Extensible Records

Data.Vinyl.CoRec

Description

Co-records: open sum types.

Consider a record with three fields A, B, and C. A record is a product of its fields; that is, it contains all of them: A, B, and C. If we want to talk about a value whose type is one of those three types, it is any one of type A, B, or C. The type CoRec '[A,B,C] corresponds to this sum type.

Synopsis

Documentation

data CoRec :: (k -> *) -> [k] -> * where Source #

Generalize algebraic sum types.

Constructors

 CoRec :: RElem a ts (RIndex a ts) => !(f a) -> CoRec f ts
Instances
 (RecApplicative ts, RecordToList ts, RZipWith ts, ReifyConstraint Eq Maybe ts, RMap ts) => Eq (CoRec Identity ts) Source # Instance detailsDefined in Data.Vinyl.CoRec Methods(==) :: CoRec Identity ts -> CoRec Identity ts -> Bool #(/=) :: CoRec Identity ts -> CoRec Identity ts -> Bool # (RPureConstrained Show ts, RecApplicative ts) => Show (CoRec Identity ts) Source # Instance detailsDefined in Data.Vinyl.CoRec MethodsshowsPrec :: Int -> CoRec Identity ts -> ShowS #show :: CoRec Identity ts -> String #showList :: [CoRec Identity ts] -> ShowS #

foldCoRec :: (forall a. RElem a ts (RIndex a ts) => f a -> b) -> CoRec f ts -> b Source #

Apply a function to a CoRec value. The function must accept any variant.

A Field of a Rec Identity is a CoRec Identity.

newtype Op b a Source #

A function type constructor that takes its arguments in the reverse order.

Constructors

 Op FieldsrunOp :: a -> b

coRecToRec :: forall f ts. RecApplicative ts => CoRec f ts -> Rec (Maybe :. f) ts Source #

We can inject a a CoRec into a Rec where every field of the Rec is Nothing except for the one whose type corresponds to the type of the given CoRec variant.

coRecToRec' :: (RecApplicative ts, RMap ts) => CoRec Identity ts -> Rec Maybe ts Source #

Shorthand for applying coRecToRec with common functors.

class FoldRec ss ts where Source #

Fold a field selection function over a Rec.

Minimal complete definition

foldRec

Methods

foldRec :: (CoRec f ss -> CoRec f ss -> CoRec f ss) -> CoRec f ss -> Rec f ts -> CoRec f ss Source #

Instances
 FoldRec (ss :: [k]) ([] :: [k]) Source # Instance detailsDefined in Data.Vinyl.CoRec MethodsfoldRec :: (CoRec f ss -> CoRec f ss -> CoRec f ss) -> CoRec f ss -> Rec f [] -> CoRec f ss Source # (t ∈ ss, FoldRec ss ts) => FoldRec (ss :: [a]) (t ': ts :: [a]) Source # Instance detailsDefined in Data.Vinyl.CoRec MethodsfoldRec :: (CoRec f ss -> CoRec f ss -> CoRec f ss) -> CoRec f ss -> Rec f (t ': ts) -> CoRec f ss Source #

coRecMap :: (forall x. f x -> g x) -> CoRec f ts -> CoRec g ts Source #

Apply a natural transformation to a variant.

coRecTraverse :: Functor h => (forall x. f x -> h (g x)) -> CoRec f ts -> h (CoRec g ts) Source #

This can be used to pull effects out of a CoRec.

foldRec1 :: FoldRec (t ': ts) ts => (CoRec f (t ': ts) -> CoRec f (t ': ts) -> CoRec f (t ': ts)) -> Rec f (t ': ts) -> CoRec f (t ': ts) Source #

Fold a field selection function over a non-empty Rec.

firstField :: FoldRec ts ts => Rec (Maybe :. f) ts -> Maybe (CoRec f ts) Source #

Similar to First: find the first field that is not Nothing.

lastField :: FoldRec ts ts => Rec (Maybe :. f) ts -> Maybe (CoRec f ts) Source #

Similar to Last: find the last field that is not Nothing.

onCoRec :: forall (cs :: [* -> Constraint]) f ts b. (AllAllSat cs ts, Functor f, RecApplicative ts) => Proxy cs -> (forall a. AllSatisfied cs a => a -> b) -> CoRec f ts -> f b Source #

Apply a type class method on a CoRec. The first argument is a Proxy value for a list of Constraint constructors. For example, onCoRec [pr|Num,Ord|] (> 20) r. If only one constraint is needed, use the pr1 quasiquoter.

onField :: forall cs ts b. (AllAllSat cs ts, RecApplicative ts) => Proxy cs -> (forall a. AllSatisfied cs a => a -> b) -> Field ts -> b Source #

Apply a type class method on a Field. The first argument is a Proxy value for a list of Constraint constructors. For example, onCoRec [pr|Num,Ord|] (> 20) r. If only one constraint is needed, use the pr1 quasiquoter.

reifyDicts :: forall cs f proxy (ts :: [*]). (AllAllSat cs ts, RecApplicative ts) => proxy cs -> (forall a. AllSatisfied cs a => f a) -> Rec f ts Source #

Build a record whose elements are derived solely from a list of constraint constructors satisfied by each.

Extracting values from a CoRec/Pattern matching on a CoRec

asA :: (t ts, RecApplicative ts, RMap ts) => CoRec Identity ts -> Maybe t Source #

If a CoRec is a variant of the requested type, return Just that value; otherwise return Nothing.

asA' :: (t ts, RecApplicative ts, RMap ts) => CoRec f ts -> (Maybe :. f) t Source #

Like asA, but for any interpretation functor.

match :: forall ts b. CoRec Identity ts -> Handlers ts b -> b Source #

Pattern match on a CoRec by specifying handlers for each case. Note that the order of the Handlers has to match the type level list (t:ts).

>>> :{
let testCoRec = Col (Identity False) :: CoRec Identity [Int, String, Bool] in
match testCoRec $(H$ \i -> "my Int is the successor of " ++ show (i - 1))
:& (H $\s -> "my String is: " ++ s) :& (H$ \b -> "my Bool is not: " ++ show (not b) ++ " thus it is " ++ show b)
:& RNil
:}
"my Bool is not: True thus it is False"


class RIndex t ts ~ i => Match1 t ts i where Source #

Helper for handling a variant of a CoRec: either the function is applied to the variant or the type of the CoRec is refined to reflect the fact that the variant is not compatible with the type of the would-be handler.

Minimal complete definition

match1'

Methods

match1' :: Handler r t -> Rec Maybe ts -> Either r (Rec Maybe (RDelete t ts)) Source #

Instances
 Match1 t (t ': ts) Z Source # Instance detailsDefined in Data.Vinyl.CoRec Methodsmatch1' :: Handler r t -> Rec Maybe (t ': ts) -> Either r (Rec Maybe (RDelete t (t ': ts))) Source # (Match1 t ts i, RIndex t (s ': ts) ~ S i, RDelete t (s ': ts) ~ (s ': RDelete t ts)) => Match1 t (s ': ts) (S i) Source # Instance detailsDefined in Data.Vinyl.CoRec Methodsmatch1' :: Handler r t -> Rec Maybe (s ': ts) -> Either r (Rec Maybe (RDelete t (s ': ts))) Source #

match1 :: (Match1 t ts (RIndex t ts), RecApplicative ts, RMap ts, RMap (RDelete t ts), FoldRec (RDelete t ts) (RDelete t ts)) => Handler r t -> CoRec Identity ts -> Either r (CoRec Identity (RDelete t ts)) Source #

Handle a single variant of a CoRec: either the function is applied to the variant or the type of the CoRec is refined to reflect the fact that the variant is not compatible with the type of the would-be handler

matchNil :: CoRec f '[] -> r Source #

newtype Handler b a Source #

Newtype around functions for a to b

Constructors

 H (a -> b)

type Handlers ts b = Rec (Handler b) ts Source #

'Handlers ts b', is essentially a list of functions, one for each type in ts. All functions produce a value of type b. Hence, 'Handlers ts b' would represent something like the type-level list: [t -> b | t in ts ]

restrictCoRec :: forall t ts f. (RecApplicative ts, FoldRec ts ts) => CoRec f (t ': ts) -> Either (f t) (CoRec f ts) Source #

A CoRec is either the first possible variant indicated by its type, or a CoRec that must be one of the remaining types.

weakenCoRec :: (RecApplicative ts, FoldRec (t ': ts) (t ': ts)) => CoRec f ts -> CoRec f (t ': ts) Source #

A CoRec whose possible types are ts may be used at a type of CoRec whose possible types are t:ts.