Safe Haskell | None |
---|---|
Language | Haskell2010 |
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
- data CoRec :: (k -> *) -> [k] -> * where
- corec :: forall (l :: Symbol) (ts :: [(Symbol, Type)]) (f :: (Symbol, Type) -> Type). (KnownSymbol l, (l ::: FieldType l ts) ∈ ts) => f (l ::: FieldType l ts) -> CoRec f ts
- foldCoRec :: (forall a. RElem a ts (RIndex a ts) => f a -> b) -> CoRec f ts -> b
- type Field = CoRec Identity
- newtype Op b a = Op {
- runOp :: a -> b
- class ShowF f a where
- coRecToRec :: forall f ts. RecApplicative ts => CoRec f ts -> Rec (Maybe :. f) ts
- coRecToRec' :: (RecApplicative ts, RMap ts) => CoRec Identity ts -> Rec Maybe ts
- class FoldRec ss ts where
- coRecMap :: (forall x. f x -> g x) -> CoRec f ts -> CoRec g ts
- getDict :: forall c ts a proxy. (a ∈ ts, RPureConstrained c ts) => proxy a -> DictOnly c a
- coRecMapC :: forall c ts f g. RPureConstrained c ts => (forall x. (x ∈ ts, c x) => f x -> g x) -> CoRec f ts -> CoRec g ts
- coRecTraverse :: Functor h => (forall x. f x -> h (g x)) -> CoRec f ts -> h (CoRec g ts)
- 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)
- firstField :: FoldRec ts ts => Rec (Maybe :. f) ts -> Maybe (CoRec f ts)
- lastField :: FoldRec ts ts => Rec (Maybe :. f) ts -> Maybe (CoRec f ts)
- onCoRec :: forall c f ts b g. RPureConstrained c ts => (forall a. (a ∈ ts, c a) => f a -> g b) -> CoRec f ts -> g b
- onField :: forall c ts b. RPureConstrained c ts => (forall a. (a ∈ ts, c a) => a -> b) -> Field ts -> b
- variantIndexOf :: forall f ts. CoRec f ts -> Int
- asA :: NatToInt (RIndex t ts) => CoRec Identity ts -> Maybe t
- asA' :: forall t ts f. NatToInt (RIndex t ts) => CoRec f ts -> Maybe (f t)
- match :: forall ts b. CoRec Identity ts -> Handlers ts b -> b
- class RIndex t ts ~ i => Match1 t ts i where
- 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))
- matchNil :: CoRec f '[] -> r
- newtype Handler b a = H (a -> b)
- type Handlers ts b = Rec (Handler b) ts
- restrictCoRec :: forall t ts f. (RecApplicative ts, FoldRec ts ts) => CoRec f (t ': ts) -> Either (f t) (CoRec f ts)
- weakenCoRec :: (RecApplicative ts, FoldRec (t ': ts) (t ': ts)) => CoRec f ts -> CoRec f (t ': ts)
- restrictCoRecSafe :: forall t ts f. (RecApplicative ts, FoldRec ts ts) => CoRec f (t ': ts) -> Either (f t) (CoRec f ts)
- asASafe :: (t ∈ ts, RecApplicative ts, RMap ts) => CoRec Identity ts -> Maybe t
- asA'Safe :: (t ∈ ts, RecApplicative ts, RMap ts) => CoRec f ts -> (Maybe :. f) t
Documentation
data CoRec :: (k -> *) -> [k] -> * where Source #
Generalize algebraic sum types.
Instances
(RecApplicative ts, RecordToList ts, RApply ts, ReifyConstraint Eq Maybe ts, RMap ts) => Eq (CoRec Identity ts) Source # | |
RPureConstrained (ShowF f) ts => Show (CoRec f ts) Source # | |
corec :: forall (l :: Symbol) (ts :: [(Symbol, Type)]) (f :: (Symbol, Type) -> Type). (KnownSymbol l, (l ::: FieldType l ts) ∈ ts) => f (l ::: FieldType l ts) -> CoRec f ts Source #
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 function type constructor that takes its arguments in the reverse order.
coRecToRec :: forall f ts. RecApplicative ts => CoRec f ts -> Rec (Maybe :. f) ts Source #
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
.
foldRec :: (CoRec f ss -> CoRec f ss -> CoRec f ss) -> CoRec f ss -> Rec f 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.
getDict :: forall c ts a proxy. (a ∈ ts, RPureConstrained c ts) => proxy a -> DictOnly c a Source #
Get a DictOnly
from an RPureConstrained
instance.
coRecMapC :: forall c ts f g. RPureConstrained c ts => (forall x. (x ∈ ts, c x) => f x -> g x) -> CoRec f ts -> CoRec g ts Source #
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
.
onCoRec :: forall c f ts b g. RPureConstrained c ts => (forall a. (a ∈ ts, c a) => f a -> g b) -> CoRec f ts -> g b Source #
Apply methods from a type class to a CoRec
. Intended for use
with TypeApplications
, e.g. onCoRec @Show show r
onField :: forall c ts b. RPureConstrained c ts => (forall a. (a ∈ ts, c a) => a -> b) -> Field ts -> b Source #
Apply a type class method to a Field
. Intended for use with
TypeApplications
, e.g. onField @Show show r
.
Extracting values from a CoRec/Pattern matching on a CoRec
variantIndexOf :: forall f ts. CoRec f ts -> Int Source #
Compute a runtime Int
index identifying the position of the
variant held by a CoRec f ts
in the type-level list ts
.
asA' :: forall t ts f. NatToInt (RIndex t 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.
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 #
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 #
weakenCoRec :: (RecApplicative ts, FoldRec (t ': ts) (t ': ts)) => CoRec f ts -> CoRec f (t ': ts) Source #
Safe Variants
restrictCoRecSafe :: forall t ts f. (RecApplicative ts, FoldRec ts ts) => CoRec f (t ': ts) -> Either (f t) (CoRec f ts) Source #