Copyright | (C) 2004 Oleg Kiselyov Ralf Laemmel Keean Schupke |
---|---|
Safe Haskell | None |
Language | Haskell2010 |
The HList library
This module re-exports everything needed to use HList.
- module Data.HList.FakePrelude
- module Data.HList.HListPrelude
- module Data.HList.HArray
- module Data.HList.HOccurs
- module Data.HList.HTypeIndexed
- module Data.HList.Record
- module Data.HList.RecordPuns
- data RecordU l
- data RecordUS (x :: [*])
- class SortForRecordUS x x' | x -> x' where
- class HUpdateMany lv rx where
- hMapRU :: HMapCxt RecordU f x y => f -> RecordU x -> RecordU y
- class HFindMany (ls :: [k]) (r :: [k]) (ns :: [HNat]) | ls r -> ns
- class HNats2Integrals (ns :: [HNat]) where
- class RecordUSCxt (x :: [*]) (u :: [*]) | x -> u, u -> x
- class HLookupByHNatUS (n :: HNat) (us :: [*]) (e :: *) | n us -> e
- class HLookupByHNatUS1 (r :: Either HNat HNat) (n :: HNat) (u :: [*]) (us :: [*]) (e :: *) | r n u us -> e
- type family HSubtract (n1 :: HNat) (n2 :: HNat) :: Either HNat HNat
- class HMapUnboxF (xs :: [*]) (us :: [*]) | xs -> us, us -> xs
- data UnboxF
- data BoxF
- data EqTagValue
- type family GetElemTy (x :: [*]) :: *
- class ElemTyEq (xs :: [*])
- class RecordToRecordU x
- class RecordUToRecord x
- module Data.HList.HList
- module Data.HList.HZip
- hSort :: HSort x y => HList x -> HList y
- type HSort x y = HSortBy HLeFn x y
- class (SameLength a b, HEqByFn le) => HSortBy le (a :: [*]) (b :: [*]) | le a -> b where
- data HLeFn
- data HDown a
- class HSetBy (HNeq HLeFn) ps => HSet (ps :: [*])
- class HEqByFn lt => HSetBy lt (ps :: [*])
- class HIsSet (ps :: [*]) (b :: Bool) | ps -> b
- class HEqByFn lt => HIsSetBy lt (ps :: [*]) (b :: Bool) | lt ps -> b
- class HEqByFn le => HAscList le (ps :: [*])
- class HEqByFn le => HIsAscList le (xs :: [*]) (b :: Bool) | le xs -> b
- class HLengthEq xs n => HCurry' (n :: HNat) f xs r | f xs -> r, r xs -> f, n f -> xs, xs -> n where
- hCurry :: (ArityRev f n, ArityFwd f n, HCurry' n f xs r) => (HList xs -> r) -> f
- hUncurry :: (ArityRev f n, ArityFwd f n, HCurry' n f xs r) => f -> HList xs -> r
- hCompose :: (HSplitAt1 ([] *) n2 xsys xs1 xs2, HCurry' n2 f1 xs1 x, HCurry' n1 b xs2 r, HCurry' n3 f2 xsys r, ArityFwd f1 n2, ArityFwd b n1, ArityRev f1 n2, ArityRev b n1, HAppendList1 * xs1 xs2 xsys) => (x -> b) -> f1 -> f2
- data TIP (l :: [*])
- emptyTIP :: TIP '[]
- tipyUpdate :: (SameLength' * * r r, HUpdateAtLabel * record v v r r) => v -> record r -> record r
- tipyLens :: (Functor f, HAppendList l1 ((:) * (Tagged * a2 a2) xs2), HAllTaggedLV (HAppendListR * l1 ((:) * (Tagged * a2 a2) xs2)), HLabelSet [*] (LabelsOf (HAppendListR * l1 ((:) * (Tagged * a2 a2) xs2))), HAllTaggedEq (HAppendListR * l1 ((:) * (Tagged * a2 a2) xs2)), HFind2 * b (Label * a1) (LabelsOf xs1) ((:) * (Label * x) (LabelsOf xs1)) n, HEq * (Label * a1) (Label * x) b, HLengthEq2 HNat l1 n, HLengthEq1 HNat l1 n, SameLength' * * (HReplicateR * n ()) l1, HAppendList1 * l1 ((:) * (Tagged * a1 a1) xs2) ((:) * (Tagged * x x) xs1), HSplitAt1 ([] *) n ((:) * (Tagged * x x) xs1) l1 ((:) * (Tagged * a1 a1) xs2)) => (a1 -> f a2) -> TIP ((:) * (Tagged * x x) xs1) -> f (TIP (HAppendListR * l1 ((:) * (Tagged * a2 a2) xs2)))
- tipyLens' :: (Functor f, SameLabels [*] [*] t t, SameLength' * * t t, HAllTaggedLV t, HLabelSet [*] (LabelsOf t), HAllTaggedEq t, HUpdateAtLabel2 * a a t t, HasField * a (Record t) a) => (a -> f a) -> TIP t -> f (TIP t)
- tipyProject :: (H2ProjectByLabels ls t l b, HAllTaggedEq l, HLabelSet [*] (LabelsOf l), HAllTaggedLV l) => proxy ls -> TIP t -> TIP l
- tipyProject2 :: (HAllTaggedLV l2, HAllTaggedLV l1, HLabelSet [*] (LabelsOf l2), HLabelSet [*] (LabelsOf l1), HAllTaggedEq l2, HAllTaggedEq l1, H2ProjectByLabels ls r l1 l2) => proxy ls -> TIP r -> (TIP l1, TIP l2)
- tipyTuple :: (HDeleteAtLabel * r b v1 v2, HDeleteAtLabel * r b v3 v'2, HDeleteAtLabel * r a v2 v'1, HDeleteAtLabel * r a v1 v3, HOccurs b (r v1), HOccurs b (r v3), HOccurs a (r v2), HOccurs a (r v1)) => r v1 -> (a, b)
- tipyTuple3 :: (HDeleteAtLabel * r b v1 v5, HDeleteAtLabel * r b v7 v'3, HDeleteAtLabel * r b v6 v4, HDeleteAtLabel * r c v5 v3, HDeleteAtLabel * r c v1 v2, HDeleteAtLabel * r c v4 v'2, HDeleteAtLabel * r a v3 v'1, HDeleteAtLabel * r a v2 v7, HDeleteAtLabel * r a v1 v6, HOccurs b (r v1), HOccurs b (r v7), HOccurs b (r v6), HOccurs c (r v5), HOccurs c (r v1), HOccurs c (r v4), HOccurs a (r v3), HOccurs a (r v2), HOccurs a (r v1)) => r v1 -> (a, b, c)
- tipyTuple4 :: (HDeleteAtLabel * r b v1 v10, HDeleteAtLabel * r b v13 v'4, HDeleteAtLabel * r b v12 v9, HDeleteAtLabel * r b v11 v8, HDeleteAtLabel * r c v10 v7, HDeleteAtLabel * r c v1 v6, HDeleteAtLabel * r c v9 v'3, HDeleteAtLabel * r c v8 v5, HDeleteAtLabel * r d v7 v4, HDeleteAtLabel * r d v6 v3, HDeleteAtLabel * r d v1 v2, HDeleteAtLabel * r d v5 v'2, HDeleteAtLabel * r a v4 v'1, HDeleteAtLabel * r a v3 v13, HDeleteAtLabel * r a v2 v12, HDeleteAtLabel * r a v1 v11, HOccurs b (r v1), HOccurs b (r v13), HOccurs b (r v12), HOccurs b (r v11), HOccurs c (r v10), HOccurs c (r v1), HOccurs c (r v9), HOccurs c (r v8), HOccurs d (r v7), HOccurs d (r v6), HOccurs d (r v1), HOccurs d (r v5), HOccurs a (r v4), HOccurs a (r v3), HOccurs a (r v2), HOccurs a (r v1)) => r v1 -> (a, b, c, d)
- tipyTuple5 :: (HDeleteAtLabel * r b v1 v17, HDeleteAtLabel * r b v21 v'5, HDeleteAtLabel * r b v20 v16, HDeleteAtLabel * r b v19 v15, HDeleteAtLabel * r b v18 v14, HDeleteAtLabel * r c v17 v13, HDeleteAtLabel * r c v1 v12, HDeleteAtLabel * r c v16 v'4, HDeleteAtLabel * r c v15 v11, HDeleteAtLabel * r c v14 v10, HDeleteAtLabel * r d v13 v9, HDeleteAtLabel * r d v12 v8, HDeleteAtLabel * r d v1 v7, HDeleteAtLabel * r d v11 v'3, HDeleteAtLabel * r d v10 v6, HDeleteAtLabel * r e v9 v5, HDeleteAtLabel * r e v8 v4, HDeleteAtLabel * r e v7 v3, HDeleteAtLabel * r e v1 v2, HDeleteAtLabel * r e v6 v'2, HDeleteAtLabel * r a v5 v'1, HDeleteAtLabel * r a v4 v21, HDeleteAtLabel * r a v3 v20, HDeleteAtLabel * r a v2 v19, HDeleteAtLabel * r a v1 v18, HOccurs b (r v1), HOccurs b (r v21), HOccurs b (r v20), HOccurs b (r v19), HOccurs b (r v18), HOccurs c (r v17), HOccurs c (r v1), HOccurs c (r v16), HOccurs c (r v15), HOccurs c (r v14), HOccurs d (r v13), HOccurs d (r v12), HOccurs d (r v1), HOccurs d (r v11), HOccurs d (r v10), HOccurs e (r v9), HOccurs e (r v8), HOccurs e (r v7), HOccurs e (r v1), HOccurs e (r v6), HOccurs a (r v5), HOccurs a (r v4), HOccurs a (r v3), HOccurs a (r v2), HOccurs a (r v1)) => r v1 -> (a, b, c, d, e)
- type TagUntag xs = TagUntagFD xs (TagR xs)
- class SameLength a ta => TagUntagFD a ta | a -> ta, ta -> a where
- type family TagR (a :: [*]) :: [*]
- class TransTIP op db where
- class Monad m => TransTIPM m op db where
- data TIC (l :: [*])
- mkTIC :: (HAllTaggedEq l, HLabelSet [*] (LabelsOf l), HAllTaggedLV l, KnownNat (HNat2Nat n), HasField * i (Record l) i, HFind1 * i (UnLabel * i (LabelsOf l)) (UnLabel * i (LabelsOf l)) n) => i -> TIC l
- mkTIC1 :: forall i. MkVariant i i '[Tagged i i] => i -> TIC '[Tagged i i]
- mkTIC' :: forall i l proxy. (HTypeIndexed l, MkVariant i i l) => i -> proxy l -> TIC l
- ticPrism :: (TICPrism s t a b, SameLength s t, Choice p, Applicative f) => (a `p` f b) -> TIC s `p` f (TIC t)
- ticPrism' :: forall s t a b. (HPrism a s t a b, a ~ b, s ~ t) => forall f p. (Applicative f, Choice p) => (a `p` f b) -> TIC s `p` f (TIC t)
- data Variant (vs :: [*])
- mkVariant :: MkVariant x v vs => Label x -> v -> proxy vs -> Variant vs
- mkVariant1 :: Label k l -> e -> Variant ((:) * (Tagged k l e) ([] *))
- castVariant :: (RecordValuesR v ~ RecordValuesR v', SameLength v v') => Variant v -> Variant v'
- newtype HMapV f = HMapV f
- hMapV :: (SameLength' * * y x, SameLength' * * x y, HMapAux Variant (HFmap f) x y) => f -> Variant x -> Variant y
- hMapOutV :: forall x y z f. (SameLength x y, HMapAux Variant (HFmap f) x y, Unvariant y z, HMapOutV_gety x z ~ y) => f -> Variant x -> z
- class ZipVariant x y xy | x y -> xy, xy -> x y where
- class (SameLength v v', SameLabels v v') => ZipVR fs v v' | fs v -> v' where
- zipVR :: (SameLabels fs v, SameLength fs v, ZipVR fs v v', ZipVRCxt fs v v') => Record fs -> Variant v -> Variant v'
- class (ProjectVariant x yin, ProjectVariant x yout) => SplitVariant x yin yout where
- class ProjectVariant x y where
- class (HAllTaggedLV y, HAllTaggedLV x) => ExtendsVariant x y where
- class HAllTaggedLV y => ProjectExtendVariant x y where
- class (SameLength s t, SameLabels s t) => HPrism x s t a b | x s -> a, x t -> b, x s b -> t, x t a -> s where
- unvarianted :: (Unvariant' s a, Unvariant' t b, SameLabels s t, SameLength s t, Functor f) => (a -> f b) -> Variant s -> f (Variant t)
- unvarianted' :: (Functor f, SameLength' * * t t, SameLabels [*] [*] t t, HAllEqVal ((:) * (Tagged * () a) t) b, HAllEqVal t b, HAllEqVal' ((:) * (Tagged * () a) t), Unvariant1 Bool b t a) => (a -> f a) -> Variant t -> f (Variant t)
- splitVariant1 :: Variant (Tagged s x ': xs) -> Either x (Variant xs)
- splitVariant1' :: Variant (x ': xs) -> Either x (Variant xs)
- extendVariant :: Variant l -> Variant (e ': l)
- class Unvariant v e | v -> e where
- class Unvariant' v e | v -> e where
- class TypeIndexed r tr | r -> tr, tr -> r where
- typeIndexed' :: ((~#) [*] [*] (RecordValuesR (TagR b)) b, Functor f, Profunctor p, TagUntagFD b (TagR b), HLabelSet [*] (LabelsOf (TagR b)), HAllTaggedLV (TagR b), SameLength' * * b b, SameLength' * * (TagR b) (TagR b), SameLabels [*] [*] (TagR b) (TagR b), RecordValues (TagR b), HMapAux HList TaggedFn b (TagR b), TypeIndexed r tr) => p (tr (TagR b)) (f (tr (TagR b))) -> p (r (TagR b)) (f (r (TagR b)))
- tipHList :: (TagUntagFD a2 l, TagUntagFD a1 ta, Functor f, Profunctor p) => p (HList a1) (f (HList a2)) -> p (TIP ta) (f (TIP l))
- tipHList' :: (Profunctor p, Functor f, TagUntagFD a l) => p (HList a) (f (HList a)) -> p (TIP l) (f (TIP l))
- unboxed :: forall x y f p. (Profunctor p, Functor f, RecordToRecordU x, RecordUToRecord y) => (RecordU x `p` f (RecordU y)) -> Record x `p` f (Record y)
- unboxed' :: (HMapAux HList TaggedFn (RecordValuesR y) y, SameLength' * * (HReplicateR * n ()) y, IArray UArray (GetElemTy y), HLengthEq2 HNat y n, HLengthEq1 HNat y n, KnownNat (HNat2Nat n), HList2List (RecordValuesR y) (GetElemTy y), RecordValues y, Functor f, Profunctor p) => p (RecordU y) (f (RecordU y)) -> p (Record y) (f (Record y))
- unboxedS :: (HMapAux HList BoxF u1 g1, HMapAux HList UnboxF g2 u2, SameLength' * * g1 u1, SameLength' * * u1 g1, SameLength' * * g2 u2, SameLength' * * u2 g2, HConcatFD g1 x1, Functor f, Profunctor p, HGroupBy * EqTagValue x2 g2, HGroupBy * EqTagValue x1 g1, HMapUnboxF g2 u2, HMapUnboxF g1 u1) => p (RecordUS x2) (f (RecordUS x1)) -> p (Record x2) (f (Record x1))
- unboxedS' :: (HMapAux HList UnboxF g u, HMapAux HList BoxF u g, HGroupBy * EqTagValue x g, Profunctor p, Functor f, HConcatFD g x, SameLength' * * u g, SameLength' * * g u, HMapUnboxF g u) => p (RecordUS x) (f (RecordUS x)) -> p (Record x) (f (Record x))
- hMaybied :: (Applicative f, Choice p, SameLength' * * x r, SameLength' * * r x, HMapAux HList (HFmap HCastF) x r, VariantToHMaybied v1 x, VariantToHMaybied v2 r, HFoldr HMaybiedToVariantFs [Variant ([] *)] x [Variant v1]) => p (Variant v1) (f (Variant v2)) -> p (Record x) (f (Record r))
- hMaybied' :: (HFoldr HMaybiedToVariantFs [Variant ([] *)] x [Variant v], VariantToHMaybied v x, HMapAux HList (HFmap HCastF) x x, SameLength' * * x x, Choice p, Applicative f) => p (Variant v) (f (Variant v)) -> p (Record x) (f (Record x))
- ticVariant :: (Functor f, Profunctor p) => p (Variant l1) (f (Variant l2)) -> p (TIC l1) (f (TIC l2))
- ticVariant' :: (Profunctor p, Functor f) => p (Variant l) (f (Variant l)) -> p (TIC l) (f (TIC l))
- tipRecord :: (Functor f, Profunctor p) => p (Record r) (f (Record l)) -> p (TIP r) (f (TIP l))
- tipRecord' :: (Profunctor p, Functor f) => p (Record l) (f (Record l)) -> p (TIP l) (f (TIP l))
- class VariantToHMaybied v r | v -> r, r -> v where
- data HMaybiedToVariantFs
- hMaybiedToVariants :: (HFoldr HMaybiedToVariantFs [Variant '[]] r [Variant v], VariantToHMaybied v r) => Record r -> [Variant v]
- class Kw (fn :: *) (arg_def :: [*]) r where
- recToKW :: forall a b. (HMapCxt HList TaggedToKW a b, HConcat b) => Record a -> HList (HConcatR b)
- class IsKeyFN (t :: *) (flag :: Bool) | t -> flag
- data K s (c :: *)
- data ErrReqdArgNotFound x
- data ErrUnexpectedKW x
- module Data.HList.Labelable
- dredge :: (EnsureLabel x (Label k2 l), HSingleton ErrorMessage ErrorMessage [*] (NonUnique * * k2 r v l) (TypesDontMatch * [[*]] [*] * r ns1 vs1 v) ns2 xs, HGuardNonNull ErrorMessage [*] (NamesDontMatch * [[*]] k2 r ns l) ns1, FilterVEq1 [*] v vs1 ns1 ns2, FilterLastEq * * (Label k2 l) ns vs vs1, FilterLastEq * [*] (Label k2 l) ns ns ns1, MapFieldTreeVal r (TryCollectionListTF r) vs, MapFieldTree (TryCollectionListTF r) ns, LabelablePath xs (p v fb) (p r rft), SameLength' [*] * ns vs, SameLength' [*] * ns1 vs1, SameLength' * [*] vs ns, SameLength' * [*] vs1 ns1) => x -> p v fb -> p r rft
- dredge' :: (SameLength' * [*] vs1 ns1, SameLength' * [*] vs ns, SameLength' [*] * ns1 vs1, SameLength' [*] * ns vs, LabelablePath xs (p a (f a)) (p s (f s)), MapFieldTree (TryCollectionListTF s) ns, MapFieldTreeVal s (TryCollectionListTF s) vs, FilterLastEq * [*] (Label k l) ns ns ns1, FilterLastEq * * (Label k l) ns vs vs1, FilterVEq1 [*] a vs1 ns1 ns2, HGuardNonNull ErrorMessage [*] (NamesDontMatch * [[*]] k s ns l) ns1, HSingleton ErrorMessage ErrorMessage [*] (NonUnique * * k s a l) (TypesDontMatch * [[*]] [*] * s ns1 vs1 a) ns2 xs, EnsureLabel x (Label k l)) => x -> p a (f a) -> p s (f s)
- dredgeND :: (EnsureLabel x (Label k2 l), HSingleton ErrorMessage ErrorMessage [*] (NonUnique' * k2 r l) (NamesDontMatch * [[*]] k2 r ns l) ns' xs, FilterLastEq * [*] (Label k2 l) ns ns ns', MapFieldTree (TryCollectionListTF r) ns, LabelablePath xs (p a fb) (p r rft)) => x -> p a fb -> p r rft
- dredgeND' :: (LabelablePath xs (p a (f a)) (p s (f s)), MapFieldTree (TryCollectionListTF s) ns, FilterLastEq * [*] (Label k l) ns ns ns', HSingleton ErrorMessage ErrorMessage [*] (NonUnique' * k s l) (NamesDontMatch * [[*]] k s ns l) ns' xs, EnsureLabel x (Label k l)) => x -> p a (f a) -> p s (f s)
- dredgeTI' :: (HSingleton ErrorMessage ErrorMessage [*] (NonUnique' * * s a) (NamesDontMatch * [[*]] * s ns a) ns' xs, FilterLastEq * [*] (Label * a) ns ns ns', MapFieldTree (TryCollectionListTF s) ns, LabelablePath xs (p a (f a)) (p s (f s))) => q a -> p a (f a) -> p s (f s)
- hLookupByLabelDredge :: (HSingleton ErrorMessage ErrorMessage [*] (NonUnique' * k r2 l) (NamesDontMatch * [[*]] k r2 ns l) ns' ls, FilterLastEq * [*] (Label k l) ns ns ns', MapFieldTree (TryCollectionListTF r2) ns, HasFieldPath False ls (r1 r2) v) => Label k l -> r1 r2 -> v
- class HasFieldPath (needJust :: Bool) (ls :: [*]) r v | needJust ls r -> v
- module Data.HList.Label3
- module Data.HList.MakeLabels
- module Data.HList.TypeEqO
- class HAllTaggedEq (l :: [*])
Faking dependent types in Haskell
module Data.HList.FakePrelude
Functions for all collections
module Data.HList.HListPrelude
Array-like access to HLists
module Data.HList.HArray
Result-type-driven operations
module Data.HList.HOccurs
Type-indexed operations
module Data.HList.HTypeIndexed
Record
module Data.HList.Record
quasiquoter pun
helps to avoid needing a proxy value with
type Label
in the first place: when you take values out of or into
records with pattern matching, the variable name determines the label
name.
module Data.HList.RecordPuns
Unpacked / Unboxed Records
A type which behaves similarly to Record
, except
all elements must fit in the same UArray
. A consequence of
this is that RecordU
has the following properties:
- it is strict in the element types
- it cannot do type-changing updates of
RecordU
, except if the function applies to all elements - it probably is slower to update the very first elements
of the
RecordU
The benefit is that lookups should be faster and records
should take up less space. However benchmarks done with
a slow HNat2Integral
do not suggest that RecordU is
faster than Record.
data RecordUS (x :: [*]) Source #
RecordUS
is stored as a HList
of RecordU
to allow the RecordUS
to contain elements of different
types, so long all of the types can be put into an unboxed
array (UArray
).
It is advantageous (at least space-wise) to sort the record to keep
elements with the same types elements adjacent. See SortForRecordUS
for more details.
(HFindLabel k l r n, HLookupByHNatUS n u (Tagged k l v), HasField k l (Record r) v, RecordUSCxt r u) => HasField k l (RecordUS r) v Source # | works expected. See examples attached to |
(RecordUSCxt x u, Show (HList u)) => Show (RecordUS x) Source # | |
class SortForRecordUS x x' | x -> x' where Source #
Reorders a Record
such that the RecordUS
made from it takes up
less space
Bad
has alternating Double and Int fields
>>>
bad
Record{x=1.0,i=2,y=3.0,j=4}
4 arrays containing one element each are needed when this Record is stored as a RecordUS
>>>
recordToRecordUS bad
RecordUS H[RecordU (array (0,0) [(0,1.0)]),RecordU (array (0,0) [(0,2)]),RecordU (array (0,0) [(0,3.0)]),RecordU (array (0,0) [(0,4)])]
It is possible to sort the record
>>>
sortForRecordUS bad
Record{x=1.0,y=3.0,i=2,j=4}
This allows the same content to be stored in two unboxed arrays
>>>
recordToRecordUS (sortForRecordUS bad)
RecordUS H[RecordU (array (0,1) [(0,1.0),(1,3.0)]),RecordU (array (0,1) [(0,2),(1,4)])]
sortForRecordUS :: Record x -> Record x' Source #
SortForRecordUS ([] *) ([] *) Source # | |
(HPartitionEq * * EqTagValue x ((:) * x xs) xi xo, SortForRecordUS xo xo', (~) [*] sorted (HAppendListR * xi xo'), HAppendList xi xo') => SortForRecordUS ((:) * x xs) sorted Source # | |
class HUpdateMany lv rx where Source #
analogous flip //
. Similar to .<++.
, except it is restricted
to cases where the left argument holds a subset of elements.
hUpdateMany :: Record lv -> rx -> rx Source #
(HLeftUnion lv x lvx, HRLabelSet x, HLabelSet [*] (LabelsOf x), HRearrange (LabelsOf x) lvx x) => HUpdateMany lv (Record x) Source # | implementation in terms of |
(RecordValues lv, HList2List (RecordValuesR lv) v, HFindMany * (LabelsOf lv) (LabelsOf r) ixs, IArray UArray v, (~) * v (GetElemTy r), HNats2Integrals ixs) => HUpdateMany lv (RecordU r) Source # | |
internals for types
class HNats2Integrals (ns :: [HNat]) where Source #
hNats2Integrals :: Integral i => Proxy ns -> [i] Source #
HNats2Integrals ([] HNat) Source # | |
(HNats2Integrals ns, HNat2Integral n) => HNats2Integrals ((:) HNat n ns) Source # | |
class RecordUSCxt (x :: [*]) (u :: [*]) | x -> u, u -> x Source #
connect the unpacked x
representation with the
corresponding list of RecordU u
representation.
(HGroupBy * EqTagValue x g, HMapUnboxF g u) => RecordUSCxt x u Source # | the only instance |
class HLookupByHNatUS1 (r :: Either HNat HNat) (n :: HNat) (u :: [*]) (us :: [*]) (e :: *) | r n u us -> e Source #
(HNat2Integral n, (~) * (HLookupByHNatR n u) le, (~) * le (Tagged k l e), IArray UArray e, (~) * e (GetElemTy u)) => HLookupByHNatUS1 (Left HNat HNat t) n u us le Source # | |
HLookupByHNatUS t us e => HLookupByHNatUS1 (Right HNat HNat t) n u us e Source # | |
type family HSubtract (n1 :: HNat) (n2 :: HNat) :: Either HNat HNat Source #
HSubtract a b
is Left (a-b)
, Right (b-a)
or Right HZero
class HMapUnboxF (xs :: [*]) (us :: [*]) | xs -> us, us -> xs Source #
HMapUnboxF ([] *) ([] *) Source # | |
HMapUnboxF xs us => HMapUnboxF ((:) * (HList x) xs) ((:) * (RecordU x) us) Source # | |
data EqTagValue Source #
class RecordToRecordU x Source #
(RecordValues x, HList2List (RecordValuesR x) (GetElemTy x), HNat2Integral n, HLengthEq x n, IArray UArray (GetElemTy x)) => RecordToRecordU x Source # | |
class RecordUToRecord x Source #
(HMapCxt HList TaggedFn (RecordValuesR x) x, IArray UArray (GetElemTy x), HList2List (RecordValuesR x) (GetElemTy x)) => RecordUToRecord x Source # | |
HList
A subset of Data.HList.HList is re-exported.
module Data.HList.HList
module Data.HList.HZip
A subset of Data.HList.HSort
class (SameLength a b, HEqByFn le) => HSortBy le (a :: [*]) (b :: [*]) | le a -> b where Source #
quick sort with a special case for sorted lists
(SameLength * * a b, HIsAscList k le a ok, HSortBy1 Bool k ok le a b, HEqByFn k le) => HSortBy k le a b Source # | |
the "standard" <=
for types. Reuses HEqBy
Note that ghc-7.6 is missing instances for Symbol and Nat, so that
sorting only works HNat
(as used by Data.HList.Label3).
HEqByFn * HLeFn Source # | |
(~) Bool ((<=?) x y) b => HEqBy * Nat HLeFn x y b Source # | only in ghc >= 7.7 |
(HEq Ordering (CmpSymbol x y) GT nb, (~) Bool (HNot nb) b) => HEqBy * Symbol HLeFn x y b Source # | only in ghc >= 7.7
|
(~) Bool (HLe x y) b => HEqBy * HNat HLeFn x y b Source # | |
HEqBy * k HLeFn x y b => HEqBy * * HLeFn (Proxy k x) (Proxy k y) b Source # | |
HEqBy * k HLeFn x y b => HEqBy * * HLeFn (Label k x) (Label k y) b Source # | |
HEqBy * k HLeFn x y b => HEqBy * * HLeFn (Tagged k x v) (Tagged k y w) b Source # | |
(HEqBy * HNat HLeFn n m b, (~) * ns ns') => HEqBy * * HLeFn (Lbl n ns desc) (Lbl m ns' desc') b Source # | Data.HList.Label3 labels can only be compared if they belong to the same namespace. |
analogous to Down
class HEqByFn lt => HSetBy lt (ps :: [*]) Source #
Provided the labels involved have an appropriate instance of HEqByFn, it would be possible to use the following definitions:
type HRLabelSet = HSet type HLabelSet = HSet
class HIsSet (ps :: [*]) (b :: Bool) | ps -> b Source #
>>>
let xx = Proxy :: HIsSet [Label "x", Label "x"] b => Proxy b
>>>
:t xx
xx :: Proxy 'False
>>>
let xy = Proxy :: HIsSet [Label "x", Label "y"] b => Proxy b
>>>
:t xy
xy :: Proxy 'True
class HEqByFn le => HAscList le (ps :: [*]) Source #
HAscList le xs
confirms that xs is in ascending order,
and reports which element is duplicated otherwise.
class HEqByFn le => HIsAscList le (xs :: [*]) (b :: Bool) | le xs -> b Source #
HIsAscList le xs b
is analogous to
b = all (\(x,y) -> x `le` y) (xs `zip` tail xs)
A subset of Data.HList.HCurry
class HLengthEq xs n => HCurry' (n :: HNat) f xs r | f xs -> r, r xs -> f, n f -> xs, xs -> n where Source #
'curry'/'uncurry' for many arguments and HLists instead of tuples
XXX the last FD xs -> n
is needed to make hCompose infer the right types:
arguably it shouldn't be needed
hCurry :: (ArityRev f n, ArityFwd f n, HCurry' n f xs r) => (HList xs -> r) -> f Source #
Note: with ghc-7.10 the Arity constraint added here does not work
properly with hCompose, so it is possible that other uses of hCurry
are better served by hCurry' Proxy
.
hCompose :: (HSplitAt1 ([] *) n2 xsys xs1 xs2, HCurry' n2 f1 xs1 x, HCurry' n1 b xs2 r, HCurry' n3 f2 xsys r, ArityFwd f1 n2, ArityFwd b n1, ArityRev f1 n2, ArityRev b n1, HAppendList1 * xs1 xs2 xsys) => (x -> b) -> f1 -> f2 Source #
compose two functions that take multiple arguments. The result of the second function is the first argument to the first function. An example is probably clearer:
>>>
let f = hCompose (,,) (,)
>>>
:t f
f :: ... -> ... -> ... -> ... -> ((..., ...), ..., ...)
>>>
f 1 2 3 4
((1,2),3,4)
Note: polymorphism can make it confusing as to how many parameters a function
actually takes. For example, the first two ids are id :: (a -> b) -> (a -> b)
in
>>>
(.) id id id 'y'
'y'
>>>
hCompose id id id 'y'
'y'
still typechecks, but in that case hCompose i1 i2 i3 x == i1 ((i2 i3) x)
has id with different types than @(.) i1 i2 i3 x == (i1 (i2 i3)) x
Prompted by http://stackoverflow.com/questions/28932054/can-hlistelim-be-composed-with-another-function
TIP
Public interface of Data.HList.TIP
TIPs are like Record
, except element "i" of the list "l"
has type Tagged e_i e_i
TypeIndexed Record TIP Source # | |
(HUnzip TIP x y xy, HZipList xL yL xyL, (~) * lty (HList xL -> HList yL -> HList xyL), Coercible * lty (TIP x -> TIP y -> TIP xy), (~) [*] (UntagR x) xL, (~) [*] (UntagR y) yL, (~) [*] (UntagR xy) xyL, UntagTag x, UntagTag y, UntagTag xy) => HZip TIP x y xy Source # | |
(HZipList xL yL xyL, (~) * lty (HList xyL -> (HList xL, HList yL)), Coercible * lty (TIP xy -> (TIP x, TIP y)), (~) [*] (UntagR x) xL, (~) [*] (TagR xL) x, (~) [*] (UntagR y) yL, (~) [*] (TagR yL) y, (~) [*] (UntagR xy) xyL, (~) [*] (TagR xyL) xy, SameLengths * ((:) [*] x ((:) [*] y ((:) [*] xy ([] [*])))), UntagTag x, UntagTag y, UntagTag xy) => HUnzip TIP x y xy Source # | |
(HDeleteAtLabel k Record e v v', HTypeIndexed v') => HDeleteAtLabel k TIP e v v' Source # | |
(HUpdateAtLabel * Record e' e r r', HTypeIndexed r', (~) * e e') => HUpdateAtLabel * TIP e' e r r' Source # | |
LabelableTIPCxt k x s t a b => Labelable k x TIP s t a b Source # | make a
|
HasField * e (Record ((:) * x ((:) * y l))) e => HOccurs e (TIP ((:) * x ((:) * y l))) Source # | |
(~) * tee (Tagged * e e) => HOccurs e (TIP ((:) * tee ([] *))) Source # | One occurrence and nothing is left This variation provides an extra feature for singleton lists. That is, the result type is unified with the element in the list. Hence the explicit provision of a result type can be omitted. |
(HRLabelSet ((:) * (Tagged * e e) l), HTypeIndexed l) => HExtend e (TIP l) Source # | |
Bounded (HList r) => Bounded (TIP r) Source # | |
Eq (HList a) => Eq (TIP a) Source # | |
Ord (HList r) => Ord (TIP r) Source # | |
HMapOut (HComp HShow HUntag) l String => Show (TIP l) Source # | |
Ix (HList r) => Ix (TIP r) Source # | |
Semigroup (HList a) => Semigroup (TIP a) Source # | |
Monoid (HList a) => Monoid (TIP a) Source # | |
((~) * e e', HasField * e (Record l) e') => HasField * e (TIP l) e' Source # | |
(HAppend (HList l) (HList l'), HTypeIndexed (HAppendListR * l l')) => HAppend (TIP l) (TIP l') Source # | |
(HOccurs e (TIP l1), SubType * * (TIP l1) (TIP l2)) => SubType * * (TIP l1) (TIP ((:) * e l2)) Source # | |
SubType * * (TIP l) (TIP ([] *)) Source # | Subtyping for TIPs |
type LabelableTy TIP Source # | |
type HExtendR e (TIP l) Source # | |
type HAppendR * (TIP l) (TIP l') Source # | |
tipyUpdate :: (SameLength' * * r r, HUpdateAtLabel * record v v r r) => v -> record r -> record r Source #
tipyLens :: (Functor f, HAppendList l1 ((:) * (Tagged * a2 a2) xs2), HAllTaggedLV (HAppendListR * l1 ((:) * (Tagged * a2 a2) xs2)), HLabelSet [*] (LabelsOf (HAppendListR * l1 ((:) * (Tagged * a2 a2) xs2))), HAllTaggedEq (HAppendListR * l1 ((:) * (Tagged * a2 a2) xs2)), HFind2 * b (Label * a1) (LabelsOf xs1) ((:) * (Label * x) (LabelsOf xs1)) n, HEq * (Label * a1) (Label * x) b, HLengthEq2 HNat l1 n, HLengthEq1 HNat l1 n, SameLength' * * (HReplicateR * n ()) l1, HAppendList1 * l1 ((:) * (Tagged * a1 a1) xs2) ((:) * (Tagged * x x) xs1), HSplitAt1 ([] *) n ((:) * (Tagged * x x) xs1) l1 ((:) * (Tagged * a1 a1) xs2)) => (a1 -> f a2) -> TIP ((:) * (Tagged * x x) xs1) -> f (TIP (HAppendListR * l1 ((:) * (Tagged * a2 a2) xs2))) Source #
provides a Lens (TIP s) (TIP t) a b
When using set
(also known as .~
), tipyLens'
can address the
ambiguity as to which field "a" should actually be updated.
tipyLens' :: (Functor f, SameLabels [*] [*] t t, SameLength' * * t t, HAllTaggedLV t, HLabelSet [*] (LabelsOf t), HAllTaggedEq t, HUpdateAtLabel2 * a a t t, HasField * a (Record t) a) => (a -> f a) -> TIP t -> f (TIP t) Source #
provides a Lens' (TIP s) a
. hLens'
:: Label a -> Lens' (TIP s) a
is another option.
projection
tipyProject :: (H2ProjectByLabels ls t l b, HAllTaggedEq l, HLabelSet [*] (LabelsOf l), HAllTaggedLV l) => proxy ls -> TIP t -> TIP l Source #
Use Labels
to specify the first argument
tipyProject2 :: (HAllTaggedLV l2, HAllTaggedLV l1, HLabelSet [*] (LabelsOf l2), HLabelSet [*] (LabelsOf l1), HAllTaggedEq l2, HAllTaggedEq l1, H2ProjectByLabels ls r l1 l2) => proxy ls -> TIP r -> (TIP l1, TIP l2) Source #
The same as tipyProject
, except also return the
types not requested in the proxy
argument
tipyTuple :: (HDeleteAtLabel * r b v1 v2, HDeleteAtLabel * r b v3 v'2, HDeleteAtLabel * r a v2 v'1, HDeleteAtLabel * r a v1 v3, HOccurs b (r v1), HOccurs b (r v3), HOccurs a (r v2), HOccurs a (r v1)) => r v1 -> (a, b) Source #
project a TIP (or HList) into a tuple
tipyTuple' x = (hOccurs
x, hOccurs x)
behaves similarly, except tipyTuple
excludes
the possibility of looking up the same element
twice, which allows inferring a concrete type
in more situations. For example
(\x y z -> tipyTuple (x .*. y .*. emptyTIP) `asTypeOf` (x, z)) () 'x'
has type Char -> ((), Char)
. tipyTuple' would
need a type annotation to decide whether the type
should be Char -> ((), Char)
or () -> ((), ())
tipyTuple3 :: (HDeleteAtLabel * r b v1 v5, HDeleteAtLabel * r b v7 v'3, HDeleteAtLabel * r b v6 v4, HDeleteAtLabel * r c v5 v3, HDeleteAtLabel * r c v1 v2, HDeleteAtLabel * r c v4 v'2, HDeleteAtLabel * r a v3 v'1, HDeleteAtLabel * r a v2 v7, HDeleteAtLabel * r a v1 v6, HOccurs b (r v1), HOccurs b (r v7), HOccurs b (r v6), HOccurs c (r v5), HOccurs c (r v1), HOccurs c (r v4), HOccurs a (r v3), HOccurs a (r v2), HOccurs a (r v1)) => r v1 -> (a, b, c) Source #
tipyTuple4 :: (HDeleteAtLabel * r b v1 v10, HDeleteAtLabel * r b v13 v'4, HDeleteAtLabel * r b v12 v9, HDeleteAtLabel * r b v11 v8, HDeleteAtLabel * r c v10 v7, HDeleteAtLabel * r c v1 v6, HDeleteAtLabel * r c v9 v'3, HDeleteAtLabel * r c v8 v5, HDeleteAtLabel * r d v7 v4, HDeleteAtLabel * r d v6 v3, HDeleteAtLabel * r d v1 v2, HDeleteAtLabel * r d v5 v'2, HDeleteAtLabel * r a v4 v'1, HDeleteAtLabel * r a v3 v13, HDeleteAtLabel * r a v2 v12, HDeleteAtLabel * r a v1 v11, HOccurs b (r v1), HOccurs b (r v13), HOccurs b (r v12), HOccurs b (r v11), HOccurs c (r v10), HOccurs c (r v1), HOccurs c (r v9), HOccurs c (r v8), HOccurs d (r v7), HOccurs d (r v6), HOccurs d (r v1), HOccurs d (r v5), HOccurs a (r v4), HOccurs a (r v3), HOccurs a (r v2), HOccurs a (r v1)) => r v1 -> (a, b, c, d) Source #
tipyTuple5 :: (HDeleteAtLabel * r b v1 v17, HDeleteAtLabel * r b v21 v'5, HDeleteAtLabel * r b v20 v16, HDeleteAtLabel * r b v19 v15, HDeleteAtLabel * r b v18 v14, HDeleteAtLabel * r c v17 v13, HDeleteAtLabel * r c v1 v12, HDeleteAtLabel * r c v16 v'4, HDeleteAtLabel * r c v15 v11, HDeleteAtLabel * r c v14 v10, HDeleteAtLabel * r d v13 v9, HDeleteAtLabel * r d v12 v8, HDeleteAtLabel * r d v1 v7, HDeleteAtLabel * r d v11 v'3, HDeleteAtLabel * r d v10 v6, HDeleteAtLabel * r e v9 v5, HDeleteAtLabel * r e v8 v4, HDeleteAtLabel * r e v7 v3, HDeleteAtLabel * r e v1 v2, HDeleteAtLabel * r e v6 v'2, HDeleteAtLabel * r a v5 v'1, HDeleteAtLabel * r a v4 v21, HDeleteAtLabel * r a v3 v20, HDeleteAtLabel * r a v2 v19, HDeleteAtLabel * r a v1 v18, HOccurs b (r v1), HOccurs b (r v21), HOccurs b (r v20), HOccurs b (r v19), HOccurs b (r v18), HOccurs c (r v17), HOccurs c (r v1), HOccurs c (r v16), HOccurs c (r v15), HOccurs c (r v14), HOccurs d (r v13), HOccurs d (r v12), HOccurs d (r v1), HOccurs d (r v11), HOccurs d (r v10), HOccurs e (r v9), HOccurs e (r v8), HOccurs e (r v7), HOccurs e (r v1), HOccurs e (r v6), HOccurs a (r v5), HOccurs a (r v4), HOccurs a (r v3), HOccurs a (r v2), HOccurs a (r v1)) => r v1 -> (a, b, c, d, e) Source #
type TagUntag xs = TagUntagFD xs (TagR xs) Source #
class SameLength a ta => TagUntagFD a ta | a -> ta, ta -> a where Source #
TagR
can also be used to avoid redundancy when defining types for TIC and TIP.
type XShort = TagR [A,B,C,D]
type XLong = [Tagged A A, Tagged B B, Tagged C C, Tagged D D]
an equivalent FD version, which is slightly better with respect to simplifying types containing type variables (in ghc-7.8 and 7.6): http://stackoverflow.com/questions/24110410/
With ghc-7.10 (http://ghc.haskell.org/trac/ghc/ticket/10009) the FD version is superior to the TF version:
class (UntagR (TagR a) ~ a) => TagUntag a where type TagR a :: [*] hTagSelf :: HList a -> HList (TagR a) hUntagSelf :: HList (TagR a) -> HList a instance TagUntag '[] where type TagR '[] = '[] hTagSelf _ = HNil hUntagSelf _ = HNil instance TagUntag xs => TagUntag (x ': xs) where type TagR (x ': xs) = Tagged x x ': TagR xs hTagSelf (HCons x xs) = Tagged xHCons
hTagSelf xs hUntagSelf (HCons (Tagged x) xs) = xHCons
hUntagSelf xs type family UntagR (xs :: [*]) :: [*] type instance UntagR '[] = '[] type instance UntagR (x ': xs) = Untag1 x ': UntagR xs
Length information should flow backwards
>>>
let len2 x = x `asTypeOf` (undefined :: HList '[a,b])
>>>
let f = len2 $ hTagSelf (hReplicate Proxy ())
>>>
:t f
f :: HList '[Tagged () (), Tagged () ()]
TagUntagFD ([] *) ([] *) Source # | |
(TagUntagFD xs ys, (~) * txx (Tagged * x x)) => TagUntagFD ((:) * x xs) ((:) * txx ys) Source # | |
TIP transform
class TransTIP op db where Source #
Transforming a TIP: applying to a TIP a (polyvariadic) function that takes arguments from a TIP and updates the TIP with the result.
In more detail: we have a typed-indexed collection TIP and we would like to apply a transformation function to it, whose argument types and the result type are all in the TIP. The function should locate its arguments based on their types, and update the TIP with the result. The function may have any number of arguments, including zero; the order of arguments should not matter.
The problem was posed by Andrew U. Frank on Haskell-Cafe, Sep 10, 2009. http://www.haskell.org/pipermail/haskell-cafe/2009-September/066217.html The problem is an interesting variation of the keyword argument problem.
Examples can be found in examples/TIPTransform.hs
and examples/TIPTransformM.hs
class Monad m => TransTIPM m op db where Source #
In March 2010, Andrew Frank extended the problem for monadic operations.
This is the monadic version of TIPTransform.hs
in the present directory.
This is the TF implementation. When specifying the operation to perform over a TIP, we can leave it polymorphic over the monad. The type checker will instantiate the monad based on the context.
TIC
Public interface of Data.HList.TIC
A datatype for type-indexed co-products. A TIC
is just a Variant
,
where the elements of the type-level list "l"
are in the form
Tagged x x
.
TypeIndexed Variant TIC Source # | |
HMapAux Variant f xs ys => HMapAux TIC f xs ys Source # | |
(TICPrism s t a b, (~) * (Label k x) (Label * a), (~) * a b, (~) [*] s t, SameLength * * s t) => Labelable k x TIC s t a b Source # | hLens' :: Label a -> Prism' (TIC s) a note that a more general function Note: `x :: k` according to the instance head, but the instance body forces the kind variable to be * later on. IE. (k ~ *) |
(HasField * o (TIC l) mo, (~) * mo (Maybe o)) => HOccurs mo (TIC l) Source # | |
((~) * me (Maybe e), HOccursNot * (Tagged * e e) l) => HExtend me (TIC l) Source # | Nothing .*. x = x Just a .*. y = mkTIC a |
Bounded (Variant l) => Bounded (TIC l) Source # | |
Enum (Variant l) => Enum (TIC l) Source # | |
Eq (Variant l) => Eq (TIC l) Source # | |
Ord (Variant l) => Ord (TIC l) Source # | |
(ReadVariant l, HAllTaggedEq l, HRLabelSet l) => Read (TIC l) Source # | |
ShowVariant l => Show (TIC l) Source # | TICs are not opaque |
Ix (Variant l) => Ix (TIC l) Source # | |
Semigroup (Variant l) => Semigroup (TIC l) Source # | |
Monoid (Variant l) => Monoid (TIC l) Source # | |
HasField * o (Variant l) (Maybe o) => HasField * o (TIC l) (Maybe o) Source # | Public destructor (or, open union's projection function) |
type LabelableTy TIC Source # | |
type HExtendR me (TIC l) Source # | |
creating TIC
mkTIC :: (HAllTaggedEq l, HLabelSet [*] (LabelsOf l), HAllTaggedLV l, KnownNat (HNat2Nat n), HasField * i (Record l) i, HFind1 * i (UnLabel * i (LabelsOf l)) (UnLabel * i (LabelsOf l)) n) => i -> TIC l Source #
make a TIC for use in contexts where the result type is fixed
mkTIC1 :: forall i. MkVariant i i '[Tagged i i] => i -> TIC '[Tagged i i] Source #
make a TIC that contains one element
:: (HTypeIndexed l, MkVariant i i l) | |
=> i | |
-> proxy l | the ordering of types in the |
-> TIC l |
Public constructor (or, open union's injection function)
get,set,modify
ticPrism :: (TICPrism s t a b, SameLength s t, Choice p, Applicative f) => (a `p` f b) -> TIC s `p` f (TIC t) Source #
ticPrism' :: forall s t a b. (HPrism a s t a b, a ~ b, s ~ t) => forall f p. (Applicative f, Choice p) => (a `p` f b) -> TIC s `p` f (TIC t) Source #
Prism' (TIC s) a
Variant
Public interface of Data.HList.Variant
data Variant (vs :: [*]) Source #
Variant vs
has an implementation similar to Dynamic
, except the
contained value is one of the elements of the vs
list, rather than
being one particular instance of Typeable
.
>>>
v .!. _right
Nothing
>>>
v .!. _left
Just 'x'
In some cases the pun
quasiquote works with variants,
>>>
let f [pun| left right |] = (left,right)
>>>
f v
(Just 'x',Nothing)
>>>
f w
(Nothing,Just 5)
>>>
let add1 v = hMapV (Fun succ :: Fun '[Enum] '()) v
>>>
f (add1 v)
(Just 'y',Nothing)
>>>
f (add1 w)
(Nothing,Just 6)
Relabeled Variant Source # | |
TypeIndexed Variant TIC Source # | |
(ExtendsVariant b t, ProjectVariant s a, ProjectExtendVariant s t, HLeftUnion b s bs, HRLabelSet bs, HRearrange (LabelsOf t) bs t) => Projected Variant s t a b Source # | Prism (Variant s) (Variant t) (Variant a) (Variant b) |
HUpdateVariantAtLabelCxt k l e v v' n _e => HUpdateAtLabel k Variant l e v v' Source # | hUpdateAtLabel x e' (mkVariant x e proxy) == mkVariant x e' proxy hUpdateAtLabel y e' (mkVariant x e proxy) == mkVariant x e proxy |
(HPrism k x s t a b, (~) (* -> * -> *) to ((->) LiftedRep LiftedRep)) => Labelable k x Variant s t a b Source # | make a |
(HasField k x (Record vs) a, HFindLabel k x vs n, HNat2Integral n) => HasField k x (Variant vs) (Maybe a) Source # | |
(ApplyAB f te te', HMapCxt Variant f ((:) * l ls) ((:) * l' ls')) => HMapAux Variant f ((:) * te ((:) * l ls)) ((:) * te' ((:) * l' ls')) Source # | |
ApplyAB f te te' => HMapAux Variant f ((:) * te ([] *)) ((:) * te' ([] *)) Source # | |
((~) * le (Tagged k l (Maybe e)), HOccursNot * (Label k l) (LabelsOf v)) => HExtend le (Variant v) Source # | Extension for Variants prefers the first value (l .=. Nothing) .*. v = v (l .=. Just e) .*. _ = mkVariant l e Proxy |
(HasField k l (Variant r) (Maybe u), HasFieldPath True ls u (Maybe v)) => HasFieldPath needJust ((:) * (Label k l) ls) (Variant r) (Maybe v) Source # | |
(Unvariant ((:) * txy ([] *)) txy, (~) * tx (Tagged k t x), (~) * ty (Tagged k t y), (~) * txy (Tagged k t (x, y))) => HUnzip Variant ((:) * tx ([] *)) ((:) * ty ([] *)) ((:) * txy ([] *)) Source # | |
(HUnzip Variant ((:) * x2 xs) ((:) * y2 ys) ((:) * xy2 xys), SameLength * * xs ys, SameLength * * ys xys, (~) * tx (Tagged k t x), (~) * ty (Tagged k t y), (~) * txy (Tagged k t (x, y))) => HUnzip Variant ((:) * tx ((:) * x2 xs)) ((:) * ty ((:) * y2 ys)) ((:) * txy ((:) * xy2 xys)) Source # | |
(Bounded x, Bounded z, (~) [*] (HRevAppR * ((:) * (Tagged k2 s x) xs) ([] *)) ((:) * (Tagged k1 t z) sx), MkVariant k1 t z ((:) * (Tagged k2 s x) xs)) => Bounded (Variant ((:) * (Tagged k2 s x) xs)) Source # | |
Enum x => Enum (Variant ((:) * (Tagged k s x) ([] *))) Source # | While the instances could be written Enum (Variant '[])
Eq/Ord which cannot produce values, so they have instances for
empty variants ( |
(Enum x, Bounded x, Enum (Variant ((:) * y z))) => Enum (Variant ((:) * (Tagged k s x) ((:) * y z))) Source # |
The last type in the Variant does not need to be Bounded. This
means that
This is a "feature" because it allows an Another difficult choice is that the lower bound is
|
(Eq (Variant xs), Eq x) => Eq (Variant ((:) * x xs)) Source # | |
Eq (Variant ([] *)) Source # | |
(Typeable * (Variant v), GfoldlVariant v v, GunfoldVariant v v, VariantConstrs v) => Data (Variant v) Source # | |
(Ord x, Ord (Variant xs)) => Ord (Variant ((:) * x xs)) Source # | |
Ord (Variant ([] *)) Source # | |
ReadVariant v => Read (Variant v) Source # | A corresponding read instance |
ShowVariant vs => Show (Variant vs) Source # | Variants are not opaque |
(Semigroup x, Semigroup (Variant ((:) * a b))) => Semigroup (Variant ((:) * (Tagged k t x) ((:) * a b))) Source # | |
(Unvariant ((:) * (Tagged k t x) ([] *)) x, Semigroup x) => Semigroup (Variant ((:) * (Tagged k t x) ([] *))) Source # | |
(Monoid x, Monoid (Variant ((:) * a b))) => Monoid (Variant ((:) * (Tagged k t x) ((:) * a b))) Source # | |
(Unvariant ((:) * (Tagged k t x) ([] *)) x, Monoid x) => Monoid (Variant ((:) * (Tagged k t x) ([] *))) Source # | |
(SameLength * * s a, ExtendsVariant s a, SameLength * * b t, ExtendsVariant b t) => Rearranged [*] Variant s t a b Source # | |
type LabelableTy Variant Source # | |
type HExtendR le (Variant v) Source # | |
castVariant :: (RecordValuesR v ~ RecordValuesR v', SameLength v v') => Variant v -> Variant v' Source #
in ghc>=7.8, coerce
is probably a better choice
Apply a function to all possible elements of the variant
HMapV f |
hMapV :: (SameLength' * * y x, SameLength' * * x y, HMapAux Variant (HFmap f) x y) => f -> Variant x -> Variant y Source #
shortcut for applyAB . HMapV
. hMap
is more general
hMapOutV :: forall x y z f. (SameLength x y, HMapAux Variant (HFmap f) x y, Unvariant y z, HMapOutV_gety x z ~ y) => f -> Variant x -> z Source #
hMapOutV f = unvariant . hMapV f
, except an ambiguous type
variable is resolved by HMapOutV_gety
class ZipVariant x y xy | x y -> xy, xy -> x y where Source #
Applies to variants that have the same labels in the same order. A generalization of
zipEither :: Either a b -> Either a b -> Maybe (Either (a,a) (b,b)) zipEither (Left a) (Left a') = Just (Left (a,a')) zipEither (Right a) (Right a') = Just (Right (a,a')) zipEither _ _ = Nothing
see HZip
for zipping other collections
class (SameLength v v', SameLabels v v') => ZipVR fs v v' | fs v -> v' where Source #
Apply a record of functions to a variant of values. The functions are selected based on those having the same label as the value.
zipVR :: (SameLabels fs v, SameLength fs v, ZipVR fs v v', ZipVRCxt fs v v') => Record fs -> Variant v -> Variant v' Source #
>>>
let xy = x .*. y .*. emptyProxy
>>>
let p = Proxy `asLabelsOf` xy
>>>
let vs = [ mkVariant x 1.0 p, mkVariant y () p ]
>>>
zipVR (hBuild (+1) id) `map` vs
[V{x=2.0},V{y=()}]
projection
many
class (ProjectVariant x yin, ProjectVariant x yout) => SplitVariant x yin yout where Source #
(ProjectVariant x yin, ProjectVariant x yout, H2ProjectByLabels (LabelsOf yin) x xi xo, HRearrange (LabelsOf yin) xi yin, HRearrange (LabelsOf yout) xo yout, HLeftUnion xi xo xixo, HRearrange (LabelsOf x) xixo x, HAllTaggedLV x, HAllTaggedLV yin, HAllTaggedLV yout) => SplitVariant x yin yout Source # | |
class ProjectVariant x y where Source #
convert a variant with more fields into one with fewer (or the same) fields.
>>>
let ty = Proxy :: Proxy [Tagged "left" Int, Tagged "right" Int]
>>>
let l = mkVariant _left 1 ty
>>>
let r = mkVariant _right 2 ty
>>>
map projectVariant [l, r] :: [Maybe (Variant '[Tagged "left" Int])]
[Just V{left=1},Nothing]
is one implementation
of rearrangeVariant
= fromJust
. projectVariant
rearrangeVariant
, since the result can have the same fields with
a different order:
>>>
let yt = Proxy :: Proxy [Tagged "right" Int, Tagged "left" Int]
>>>
map projectVariant [l, r] `asTypeOf` [Just (mkVariant _left 0 yt)]
[Just V{left=1},Just V{right=2}]
ProjectVariant x ([] *) Source # | |
(ProjectVariant x ys, HasField k t (Variant x) (Maybe y), HOccursNot * (Label k t) (LabelsOf ys), (~) * ty (Tagged k t y)) => ProjectVariant x ((:) * ty ys) Source # | |
class (HAllTaggedLV y, HAllTaggedLV x) => ExtendsVariant x y where Source #
projectVariant . extendsVariant = Just
(when the types match up)
extendVariant
is a special case
extendsVariant :: Variant x -> Variant y Source #
class HAllTaggedLV y => ProjectExtendVariant x y where Source #
projectExtendVariant = fmapextendVariant
.projectVariant
where intermediate variant is as large as possible. Used to implement
Data.HList.Labelable.projected
Note that:
>>>
let r = projectExtendVariant (mkVariant1 Label 1 :: Variant '[Tagged "x" Int])
>>>
r :: Maybe (Variant '[Tagged "x" Integer])
Nothing
HAllTaggedLV y => ProjectExtendVariant ([] *) y Source # | |
((~) * lv (Tagged k l v), HMemberM * lv y inY, ProjectExtendVariant' inY lv y, ProjectExtendVariant xs y) => ProjectExtendVariant ((:) * lv xs) y Source # | |
one
class (SameLength s t, SameLabels s t) => HPrism x s t a b | x s -> a, x t -> b, x s b -> t, x t a -> s where Source #
Make a Prism (Variant s) (Variant t) a b
out of a Label.
See Data.HList.Labelable.hLens'
is a more overloaded version.
Few type annotations are necessary because of the restriction
that s
and t
have the same labels in the same order, and to
get "t" the "a" in "s" is replaced with "b".
hPrism :: (Choice p, Applicative f) => Label x -> p a (f b) -> p (Variant s) (f (Variant t)) Source #
(MkVariant k x b t, HasField k x (Variant s) (Maybe a), SameLength * * s t, SameLabels [*] [*] s t, H2ProjectByLabels ((:) * (Label k x) ([] *)) s si so, H2ProjectByLabels ((:) * (Label k x) ([] *)) t ti to, (~) [*] so to, HUpdateAtLabel k Variant x b s t, HUpdateAtLabel k Variant x a t s) => HPrism k x s t a b Source # | |
unvarianted :: (Unvariant' s a, Unvariant' t b, SameLabels s t, SameLength s t, Functor f) => (a -> f b) -> Variant s -> f (Variant t) Source #
Lens (Variant s) (Variant t) a b
Analogue of Control.Lens.chosen :: Lens (Either a a) (Either b b) a b
unvarianted' :: (Functor f, SameLength' * * t t, SameLabels [*] [*] t t, HAllEqVal ((:) * (Tagged * () a) t) b, HAllEqVal t b, HAllEqVal' ((:) * (Tagged * () a) t), Unvariant1 Bool b t a) => (a -> f a) -> Variant t -> f (Variant t) Source #
Lens' (Variant s) a
where we might have s ~ '[Tagged t1 a, Tagged t2 a]
extendVariant :: Variant l -> Variant (e ': l) Source #
implementation
class Unvariant v e | v -> e where Source #
Convert a Variant which has all possibilities having the same type
into a value of that type. Analogous to either id id
.
See also unvariant'
class Unvariant' v e | v -> e where Source #
Similar to unvariant
, except type variables in v
will be made equal to e
if possible. That allows the type
of Nothing
to be inferred as Maybe Char
.
>>>
unvariant' $ x .=. Nothing .*. mkVariant1 y 'y'
'y'
However, this difference leads to more local error messages
(Couldn't match type ‘()’ with ‘Char’
), rather than the following
with unvariant
:
Fail '("Variant", '[Tagged "left" Char, Tagged "right" ()], "must have all values equal to ", e))
unvariant' :: Variant v -> e Source #
(HAllEqVal' ((:) * (Tagged * () e) v), Unvariant v e) => Unvariant' v e Source # | |
Conversions between collections
class TypeIndexed r tr | r -> tr, tr -> r where Source #
Conversion between type indexed collections (TIC
and TIP
)
and the corresponding collection that has other label types (Variant
and Record
respectively)
See typeIndexed'
typeIndexed :: forall p f s t a b. (TypeIndexedCxt s t a b, Profunctor p, Functor f) => p (tr (TagR a)) (f (tr (TagR b))) -> p (r s) (f (r t)) Source #
Iso (r s) (r t) (tr a) (tr b)
typeIndexed' :: ((~#) [*] [*] (RecordValuesR (TagR b)) b, Functor f, Profunctor p, TagUntagFD b (TagR b), HLabelSet [*] (LabelsOf (TagR b)), HAllTaggedLV (TagR b), SameLength' * * b b, SameLength' * * (TagR b) (TagR b), SameLabels [*] [*] (TagR b) (TagR b), RecordValues (TagR b), HMapAux HList TaggedFn b (TagR b), TypeIndexed r tr) => p (tr (TagR b)) (f (tr (TagR b))) -> p (r (TagR b)) (f (r (TagR b))) Source #
HList and Record
HList and TIP
tipHList :: (TagUntagFD a2 l, TagUntagFD a1 ta, Functor f, Profunctor p) => p (HList a1) (f (HList a2)) -> p (TIP ta) (f (TIP l)) Source #
Iso (TIP (TagR a)) (TIP (TagR b)) (HList a) (HList b)
tipHList' :: (Profunctor p, Functor f, TagUntagFD a l) => p (HList a) (f (HList a)) -> p (TIP l) (f (TIP l)) Source #
Iso' (TIP (TagR s)) (HList a)
Record and RecordU
unboxed :: forall x y f p. (Profunctor p, Functor f, RecordToRecordU x, RecordUToRecord y) => (RecordU x `p` f (RecordU y)) -> Record x `p` f (Record y) Source #
Iso (Record x) (Record y) (RecordU x) (RecordU y)
unboxed' :: (HMapAux HList TaggedFn (RecordValuesR y) y, SameLength' * * (HReplicateR * n ()) y, IArray UArray (GetElemTy y), HLengthEq2 HNat y n, HLengthEq1 HNat y n, KnownNat (HNat2Nat n), HList2List (RecordValuesR y) (GetElemTy y), RecordValues y, Functor f, Profunctor p) => p (RecordU y) (f (RecordU y)) -> p (Record y) (f (Record y)) Source #
Iso' (Record x) (RecordU x)
Record and RecordUS
unboxedS :: (HMapAux HList BoxF u1 g1, HMapAux HList UnboxF g2 u2, SameLength' * * g1 u1, SameLength' * * u1 g1, SameLength' * * g2 u2, SameLength' * * u2 g2, HConcatFD g1 x1, Functor f, Profunctor p, HGroupBy * EqTagValue x2 g2, HGroupBy * EqTagValue x1 g1, HMapUnboxF g2 u2, HMapUnboxF g1 u1) => p (RecordUS x2) (f (RecordUS x1)) -> p (Record x2) (f (Record x1)) Source #
Iso (Record x) (Record y) (RecordUS x) (RecordUS y)
unboxedS' :: (HMapAux HList UnboxF g u, HMapAux HList BoxF u g, HGroupBy * EqTagValue x g, Profunctor p, Functor f, HConcatFD g x, SameLength' * * u g, SameLength' * * g u, HMapUnboxF g u) => p (RecordUS x) (f (RecordUS x)) -> p (Record x) (f (Record x)) Source #
Iso' (Record x) (RecordUS x)
Record and Variant
hMaybied :: (Applicative f, Choice p, SameLength' * * x r, SameLength' * * r x, HMapAux HList (HFmap HCastF) x r, VariantToHMaybied v1 x, VariantToHMaybied v2 r, HFoldr HMaybiedToVariantFs [Variant ([] *)] x [Variant v1]) => p (Variant v1) (f (Variant v2)) -> p (Record x) (f (Record r)) Source #
Prism (Record tma) (Record tmb) (Variant ta) (Variant tb)
see hMaybied'
hMaybied' :: (HFoldr HMaybiedToVariantFs [Variant ([] *)] x [Variant v], VariantToHMaybied v x, HMapAux HList (HFmap HCastF) x x, SameLength' * * x x, Choice p, Applicative f) => p (Variant v) (f (Variant v)) -> p (Record x) (f (Record x)) Source #
Prism' (Record tma) (Variant ta)
where tma
and tmb
are lists like
tma ~ '[Tagged x (Maybe a), Tagged y (Maybe b)] ta ~ '[Tagged x a , Tagged y b ]
If one element of the record is Just, the Variant will contain that element. Otherwise, the prism fails.
Note
The types work out to define a prism:
l =prism'
variantToHMaybied
(listToMaybe
.hMaybiedToVariants
)
but the law: s^?l ≡ Just a ==> l # a ≡ s
is not followed,
because we could have:
s, s2 :: Record '[Tagged "x" (Maybe Int), Tagged "y" (Maybe Char)] s = hBuild (Just 1) (Just '2') s2 = hBuild (Just 1) Nothing v :: Variant '[Tagged "x" Int, Tagged "y" Char] v = mkVariant (Label :: Label "x") 1 Proxy
So that s^?l == Just v
. But l#v == s2 /= s
, while the law
requires l#v == s
. hMaybied avoids this problem by only
producing a value when there is only one present.
Newtype wrappers
hListRecord
hListRecord'
are exported under Data.HList.Record
ticVariant :: (Functor f, Profunctor p) => p (Variant l1) (f (Variant l2)) -> p (TIC l1) (f (TIC l2)) Source #
Iso (TIC s) (TIC t) (Variant s) (Variant t)
typeIndexed
may be more appropriate
ticVariant' :: (Profunctor p, Functor f) => p (Variant l) (f (Variant l)) -> p (TIC l) (f (TIC l)) Source #
Iso' (TIC s) (Variant s)
tipRecord :: (Functor f, Profunctor p) => p (Record r) (f (Record l)) -> p (TIP r) (f (TIP l)) Source #
Iso (TIP s) (TIP t) (Record s) (Record t)
typeIndexed
may be more appropriate
tipRecord' :: (Profunctor p, Functor f) => p (Record l) (f (Record l)) -> p (TIP l) (f (TIP l)) Source #
Iso' (TIP (TagR s)) (Record a)
implementation
class VariantToHMaybied v r | v -> r, r -> v where Source #
variantToHMaybied :: Variant v -> Record r Source #
VariantToHMaybied ([] *) ([] *) Source # | |
(VariantToHMaybied v r, HReplicateF nr ConstTaggedNothing () r, (~) * tx (Tagged k t x), (~) * tmx (Tagged k t (Maybe x))) => VariantToHMaybied ((:) * tx v) ((:) * tmx r) Source # | |
data HMaybiedToVariantFs Source #
hMaybiedToVariants :: (HFoldr HMaybiedToVariantFs [Variant '[]] r [Variant v], VariantToHMaybied v r) => Record r -> [Variant v] Source #
Every element of the record that is Just becomes one element
in the resulting list. See hMaybied'
example types that r
and v
can take.
Data.HList.Keyword
the "public" parts. More examples are in the module documentation.
class Kw (fn :: *) (arg_def :: [*]) r where Source #
kw
takes a HList
whose first element is a function, and the rest
of the elements are default values.
A useful trick is to have a final argument ()
which is not
eaten up by a label (A only takes 1 argument). That way when you supply
the () it knows there are no more arguments (?).
>>>
data A = A
>>>
instance IsKeyFN (A -> a -> b) True
>>>
let f A a () = a + 1
>>>
let f' = f .*. A .*. 1 .*. HNil
>>>
kw f' A 0 ()
1
>>>
kw f' ()
2
recToKW :: forall a b. (HMapCxt HList TaggedToKW a b, HConcat b) => Record a -> HList (HConcatR b) Source #
convert a Record
into a list that can supply
default arguments for kw
A bit of setup:
>>>
:set -XQuasiQuotes
>>>
import Data.HList.RecordPuns
>>>
let f (_ :: Label "a") a (_ :: Label "b") b () = a `div` b
>>>
let a = 2; b = 1; f' = f .*. recToKW [pun| a b |]
>>>
kw f' ()
2
>>>
kw f' (Label :: Label "a") 10 ()
10
class IsKeyFN (t :: *) (flag :: Bool) | t -> flag Source #
All our keywords must be registered
(~) Bool False flag => IsKeyFN t flag Source # | overlapping/fallback case |
(~) * r (c -> b) => IsKeyFN (K k s c -> r) True Source # | The purpose of this instance is to be able to use the same Symbol
(type-level string) at different types. If they are supposed to be the same,
then use
therefore the following options works:
But you cannot leave off all |
(~) * r (c -> b) => IsKeyFN (K k s c -> r) True Source # | The purpose of this instance is to be able to use the same Symbol
(type-level string) at different types. If they are supposed to be the same,
then use
therefore the following options works:
But you cannot leave off all |
data ErrReqdArgNotFound x Source #
data ErrUnexpectedKW x Source #
Labels
By labels, we mean either the first argument to Tagged
(in the
type-level lists that are supplied to Record
, RecordU
, TIP
, TIC
),
or the expressions used to specify those types to be able to look up
the correct value in those collections.
Nearly all types can be labels. For example:
r :: Record '[Tagged "x" Int, -- kind GHC.TypeLits.Symbol Tagged () (), -- see Data.HList.Label5 Tagged (Lbl HZero LabelUniverse LabelMember1) () -- Label3 ] r =hBuild
8 () () -- don't need to use.=.
/.==.
and.*.
-- if we have a type signature above
we could define these variables
xLabel = Label :: Label "x" --makeLabels6
["x"] would define x with the same RHS xLens = hLens' xLabel --makeLabelable
"x" would define x with the same RHS
to access the 8
given above:
r .!.
xLabel
r ^. xLens -- alternatively Control.Lens.view
r ^. `x -- with HListPP is used (not in ghci),
-- which avoids the issue of conflicting
-- definitions of x, which mean the same
-- thing
Instances from Data.HList.Label6
>>>
:set -XDataKinds
>>>
(Label :: Label "x") .=. (5::Int) .*. emptyRecord
Record{x=5}
>>>
let x = Label :: Label "x"
>>>
let r = x .=. (5::Int) .*. emptyRecord
>>>
r .!. x
5
module Data.HList.Labelable
Rather than having the x = Label :: Label "x"
, the labels
generated by makeLabelable
also double as lenses for Control.Lens.
Here is an example of how much better that is:
>>>
:set -XNoMonomorphismRestriction -XDataKinds -XPolyKinds
>>>
import Control.Lens
>>>
import Data.HList.Labelable
>>>
let x = hLens' (Label :: Label "x")
>>>
let y = hLens' (Label :: Label "y")
The Label6 method:
>>>
let r = (Label :: Label "x") .=. "5" .*. emptyRecord
The Labelable way:
>>>
let r2 = x .==. "5" .*. emptyRecord
>>>
r ^. x
"5"
>>>
r2 ^. x
"5"
>>>
r & x .~ ()
Record{x=()}
When a field is missing, the error names that field:
>>>
:t r^.y
... ...No instance for (Fail (FieldNotFound "y")) ...
Data.HList.Dredge
lenses
dredge :: (EnsureLabel x (Label k2 l), HSingleton ErrorMessage ErrorMessage [*] (NonUnique * * k2 r v l) (TypesDontMatch * [[*]] [*] * r ns1 vs1 v) ns2 xs, HGuardNonNull ErrorMessage [*] (NamesDontMatch * [[*]] k2 r ns l) ns1, FilterVEq1 [*] v vs1 ns1 ns2, FilterLastEq * * (Label k2 l) ns vs vs1, FilterLastEq * [*] (Label k2 l) ns ns ns1, MapFieldTreeVal r (TryCollectionListTF r) vs, MapFieldTree (TryCollectionListTF r) ns, LabelablePath xs (p v fb) (p r rft), SameLength' [*] * ns vs, SameLength' [*] * ns1 vs1, SameLength' * [*] vs ns, SameLength' * [*] vs1 ns1) => x -> p v fb -> p r rft Source #
Using HListPP syntax for short hand, dredge `foo
expands out to
something like `path . `to . `foo
, with the restriction that
there is only one possible `path . `to
which leads to the
label foo
.
For example, if we have the following definitions,
type BVal a = Record '[Tagged "x" a, Tagged "a" Char] type R a = Record [Tagged "a" Int, Tagged "b" (BVal a)] type V a = Variant [Tagged "a" Int, Tagged "b" (BVal a)] lx = Label :: Label "x"
Then we have:
dredge `x :: Lens (R a) (R b) a b dredge lx :: Lens (R a) (R b) a b
dredge `x :: Traversal (V a) (V b) a b -- there were only variants along the path we'd get a Prism dredge lx :: Traversal (V a) (V b) a b
result-type directed operations are supported
There are two ways to access a field with tag a
in the R type
defined above, but they result in fields with different types
being looked up:
`a :: Lens' (R a) Char `b . `a :: Lens' (R a) Int
so provided that the result type is disambiguated by the context, the following two types can happen
dredge `a :: Lens' (R a) Char dredge `a :: Lens' (R a) Int
TIP & TIC
type indexed collections are allowed along those paths, but
as explained in the Labelable
instances, only simple optics
(Lens' Prism' Traversal' ) are produced. dredgeTI'
works better if the target is a TIP or TIC
dredge' :: (SameLength' * [*] vs1 ns1, SameLength' * [*] vs ns, SameLength' [*] * ns1 vs1, SameLength' [*] * ns vs, LabelablePath xs (p a (f a)) (p s (f s)), MapFieldTree (TryCollectionListTF s) ns, MapFieldTreeVal s (TryCollectionListTF s) vs, FilterLastEq * [*] (Label k l) ns ns ns1, FilterLastEq * * (Label k l) ns vs vs1, FilterVEq1 [*] a vs1 ns1 ns2, HGuardNonNull ErrorMessage [*] (NamesDontMatch * [[*]] k s ns l) ns1, HSingleton ErrorMessage ErrorMessage [*] (NonUnique * * k s a l) (TypesDontMatch * [[*]] [*] * s ns1 vs1 a) ns2 xs, EnsureLabel x (Label k l)) => x -> p a (f a) -> p s (f s) Source #
dredge
except a simple (s ~ t, a ~ b) optic is produced
dredgeND :: (EnsureLabel x (Label k2 l), HSingleton ErrorMessage ErrorMessage [*] (NonUnique' * k2 r l) (NamesDontMatch * [[*]] k2 r ns l) ns' xs, FilterLastEq * [*] (Label k2 l) ns ns ns', MapFieldTree (TryCollectionListTF r) ns, LabelablePath xs (p a fb) (p r rft)) => x -> p a fb -> p r rft Source #
dredgeND (named directed only) is the same as dredge
, except the
result type (a
) is not used when the label would otherwise
be ambiguous. dredgeND might give better type errors, but otherwise
there should be no reason to pick it over dredge
dredgeND' :: (LabelablePath xs (p a (f a)) (p s (f s)), MapFieldTree (TryCollectionListTF s) ns, FilterLastEq * [*] (Label k l) ns ns ns', HSingleton ErrorMessage ErrorMessage [*] (NonUnique' * k s l) (NamesDontMatch * [[*]] k s ns l) ns' xs, EnsureLabel x (Label k l)) => x -> p a (f a) -> p s (f s) Source #
dredgeND
except a simple (s ~ t, a ~ b) optic is produced
dredgeTI' :: (HSingleton ErrorMessage ErrorMessage [*] (NonUnique' * * s a) (NamesDontMatch * [[*]] * s ns a) ns' xs, FilterLastEq * [*] (Label * a) ns ns ns', MapFieldTree (TryCollectionListTF s) ns, LabelablePath xs (p a (f a)) (p s (f s))) => q a -> p a (f a) -> p s (f s) Source #
The same as dredgeND', except intended for TIP/TICs because
the assumption is made that l ~ v
for the Tagged l v
elements.
In other words, ticPrism' and tipyLens'
could usually
be replaced by
dredgeTI' :: _ => Label a -> Lens' (TIP s) a dredgeTI' :: _ => Label a -> Prism' (TIC s) a
where we might have s ~ '[Tagged a a, Tagged b b]
plain lookup
hLookupByLabelDredge :: (HSingleton ErrorMessage ErrorMessage [*] (NonUnique' * k r2 l) (NamesDontMatch * [[*]] k r2 ns l) ns' ls, FilterLastEq * [*] (Label k l) ns ns ns', MapFieldTree (TryCollectionListTF r2) ns, HasFieldPath False ls (r1 r2) v) => Label k l -> r1 r2 -> v Source #
class HasFieldPath (needJust :: Bool) (ls :: [*]) r v | needJust ls r -> v Source #
HasFieldPath False ([] *) v v Source # | |
HasFieldPath True ([] *) v (Maybe v) Source # | |
(HasField k l (Record r) u, HasFieldPath needJust ls u v) => HasFieldPath needJust ((:) * (Label k l) ls) (Record r) v Source # | |
(HasField k l (Variant r) (Maybe u), HasFieldPath True ls u (Maybe v)) => HasFieldPath needJust ((:) * (Label k l) ls) (Variant r) (Maybe v) Source # | |
namespaced labels
module Data.HList.Label3
labels as any instance of Typeable
template haskell
module Data.HList.MakeLabels
Data.HList.Data
This modules provide useful instances. A useful application can be
found in examples/cmdargs.hs
Overlapping instances are restricted to here
module Data.HList.TypeEqO
Internals
internals exported for type signature purposes
class HAllTaggedEq (l :: [*]) Source #
HAllTaggedEq ([] *) Source # | |
(HAllTaggedEq l, (~) * tee (Tagged k e e')) => HAllTaggedEq ((:) * tee l) Source # | |