| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
Data.HList.RecordU
Contents
Description
The public interface is exported from RecordU
- newtype RecordUS x = RecordUS Any
- class RecordUSCxt x u | x -> u, u -> x where
- recordUSToHList :: RecordUS x -> HList u
- hListToRecordUS :: HList u -> RecordUS x
- data EqTagValue
- class HMapUnboxF xs us | xs -> us, us -> xs
- newtype RecordU l = RecordU (UArray Int (GetElemTy l))
- type family GetElemTy x :: *
- class SortForRecordUS x x' | x -> x' where
- sortForRecordUS :: Record x -> Record x'
- class HLookupByHNatUS n us e | n us -> e where
- hLookupByHNatUS :: Proxy n -> HList us -> e
- class HLookupByHNatUS1 r n u us e | r n u us -> e where
- hLookupByHNatUS1 :: Proxy r -> Proxy n -> RecordU u -> HList us -> e
- type family HSubtract n1 n2 :: Either HNat HNat
- recordUS :: (HMapUnboxF g1 u1, HMapUnboxF g u, HGroupBy * EqTagValue x1 g1, HGroupBy * EqTagValue x g, Profunctor p, Functor f) => p (RecordUS x) (f (RecordUS x1)) -> p (HList u) (f (HList u1))
- recordUS' :: (HMapUnboxF g u, HGroupBy * EqTagValue x g, Profunctor p, Functor f) => p (RecordUS x) (f (RecordUS x)) -> p (HList u) (f (HList u))
- recordToRecordUS :: forall x g u. (HMapCxt HList UnboxF g u, HMapUnboxF g u, HGroupBy EqTagValue x g, RecordUSCxt x u) => Record x -> RecordUS x
- recordUSToRecord :: forall u g x. (HConcatFD g x, HMapCxt HList BoxF u g, HMapUnboxF g u, RecordUSCxt x u) => RecordUS x -> Record x
- unboxedS :: (HMapUnboxF g1 u1, HMapUnboxF g u, HConcatFD g1 x1, HMapAux HList UnboxF g u, HMapAux HList BoxF u1 g1, HGroupBy * EqTagValue x1 g1, HGroupBy * EqTagValue x g, SameLength' * * g1 u1, SameLength' * * g u, SameLength' * * u1 g1, SameLength' * * u g, Profunctor p, Functor f) => p (RecordUS x) (f (RecordUS x1)) -> p (Record x) (f (Record x1))
- unboxedS' :: (HMapUnboxF g u, HConcatFD g x, HMapAux HList UnboxF g u, HMapAux HList BoxF u g, HGroupBy * EqTagValue x g, SameLength' * * g u, SameLength' * * u g, Profunctor p, Functor f) => p (RecordUS x) (f (RecordUS x)) -> p (Record x) (f (Record x))
- class ElemTyEq xs
- class HUpdateMany lv rx where
- hUpdateMany :: Record lv -> rx -> rx
- class HFindMany ls r ns | ls r -> ns
- hMapRU :: HMapCxt RecordU f x y => f -> RecordU x -> RecordU y
- 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' :: (RecordValues x, HMapAux HList TaggedFn (RecordValuesR x) x, HList2List (RecordValuesR x) (GetElemTy x), HLengthEq1 HNat x n, HLengthEq2 HNat x n, SameLength' * * (HReplicateR * n ()) x, Profunctor p, IArray UArray (GetElemTy x), KnownNat (HNat2Nat n), Functor f) => p (RecordU x) (f (RecordU x)) -> p (Record x) (f (Record x))
- class RecordToRecordU x where
- recordToRecordU :: Record x -> RecordU x
- class RecordUToRecord x where
- recordUToRecord :: RecordU x -> Record x
- type Bad = `[Tagged "x" Double, Tagged "i" Int, Tagged "y" Double, Tagged "j" Int]`
- bad :: Record Bad
- bad1 :: Record `[Tagged "x" Double, Tagged "y" Double]`
- data UnboxF = UnboxF
- data BoxF = BoxF
Type definitions
RecordUS
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.
Constructors
| RecordUS Any | Any here is the |
Instances
| (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 | works expected. See examples attached to |
| (RecordUSCxt x u, Show (HList u)) => Show (RecordUS x) |
class RecordUSCxt x u | x -> u, u -> x where Source
connect the unpacked x representation with the
corresponding list of RecordU u representation.
Minimal complete definition
Nothing
Methods
recordUSToHList :: RecordUS x -> HList u Source
O(1) should be possible to implement this without
unsafeCoerce, but we want to hide the u parameter _and_
keep the RecordUSCxt as a class (instead of a type
family) because of HEq. In some cases it is possible
to have instances that do not actually respect the functional
dependency, but this should be safe if the check is not
disabled (by using -XDysfunctionalDependencies
https://phabricator.haskell.org/D69, or ghc-7.6)
hListToRecordUS :: HList u -> RecordUS x Source
O(1) should be possible to implement this without
unsafeCoerce
Instances
| (HGroupBy * EqTagValue x g, HMapUnboxF g u) => RecordUSCxt x u | the only instance |
data EqTagValue Source
Instances
| HEqByFn * EqTagValue | |
| ((~) * txv (Tagged k x v), (~) * tyw (Tagged k1 y w), HEq * v w b) => HEqBy * * EqTagValue txv tyw b |
class HMapUnboxF xs us | xs -> us, us -> xs Source
Instances
| HMapUnboxF ([] *) ([] *) | |
| HMapUnboxF xs us => HMapUnboxF ((:) * (HList x) xs) ((:) * (RecordU x) us) |
RecordU
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.
Instances
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
>>>badRecord{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 badRecordUS 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 badRecord{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)])]
Methods
sortForRecordUS :: Record x -> Record x' Source
Instances
| SortForRecordUS ([] *) ([] *) | |
| (HPartitionEq * * EqTagValue x ((:) * x xs) xi xo, SortForRecordUS xo xo', (~) [*] sorted (HAppendListR * xi xo'), HAppendList xi xo') => SortForRecordUS ((:) * x xs) sorted |
Lookup
class HLookupByHNatUS n us e | n us -> e where Source
Methods
hLookupByHNatUS :: Proxy n -> HList us -> e Source
Instances
| ((~) (Either HNat HNat) r (HSubtract (HLength * u) n), (~) * (RecordU u) ru, HLookupByHNatUS1 r n u us e) => HLookupByHNatUS n ((:) * ru us) e |
class HLookupByHNatUS1 r n u us e | r n u us -> e where Source
Instances
| (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 | |
| HLookupByHNatUS t us e => HLookupByHNatUS1 (Right HNat HNat t) n u us e |
type family HSubtract n1 n2 :: Either HNat HNat Source
HSubtract a b is Left (a-b), Right (b-a) or Right HZero
Conversion of RecordUS
with the actual representation
recordUS :: (HMapUnboxF g1 u1, HMapUnboxF g u, HGroupBy * EqTagValue x1 g1, HGroupBy * EqTagValue x g, Profunctor p, Functor f) => p (RecordUS x) (f (RecordUS x1)) -> p (HList u) (f (HList u1)) Source
Iso (HList s) (HList t) (RecordUS a) (Record b)
recordUS' :: (HMapUnboxF g u, HGroupBy * EqTagValue x g, Profunctor p, Functor f) => p (RecordUS x) (f (RecordUS x)) -> p (HList u) (f (HList u)) Source
Iso (HList s) (RecordUS a)
s is a HList of RecordU while a :: [*]
is list of Tagged label value
with Record
recordToRecordUS :: forall x g u. (HMapCxt HList UnboxF g u, HMapUnboxF g u, HGroupBy EqTagValue x g, RecordUSCxt x u) => Record x -> RecordUS x Source
view unboxedS or ^. unboxedS are preferred
recordUSToRecord :: forall u g x. (HConcatFD g x, HMapCxt HList BoxF u g, HMapUnboxF g u, RecordUSCxt x u) => RecordUS x -> Record x Source
^. from unboxedS is preferred
unboxedS :: (HMapUnboxF g1 u1, HMapUnboxF g u, HConcatFD g1 x1, HMapAux HList UnboxF g u, HMapAux HList BoxF u1 g1, HGroupBy * EqTagValue x1 g1, HGroupBy * EqTagValue x g, SameLength' * * g1 u1, SameLength' * * g u, SameLength' * * u1 g1, SameLength' * * u g, Profunctor p, Functor f) => p (RecordUS x) (f (RecordUS x1)) -> p (Record x) (f (Record x1)) Source
Iso (Record x) (Record y) (RecordUS x) (RecordUS y)
unboxedS' :: (HMapUnboxF g u, HConcatFD g x, HMapAux HList UnboxF g u, HMapAux HList BoxF u g, HGroupBy * EqTagValue x g, SameLength' * * g u, SameLength' * * u g, Profunctor p, Functor f) => p (RecordUS x) (f (RecordUS x)) -> p (Record x) (f (Record x)) Source
Iso' (Record x) (RecordUS x)
all elements of the list have the same type
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.
Methods
hUpdateMany :: Record lv -> rx -> rx Source
Instances
| (HLeftUnion lv x lvx, HRLabelSet x, HLabelSet [*] (LabelsOf x), HRearrange (LabelsOf x) lvx x) => HUpdateMany lv (Record x) | 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) |
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' :: (RecordValues x, HMapAux HList TaggedFn (RecordValuesR x) x, HList2List (RecordValuesR x) (GetElemTy x), HLengthEq1 HNat x n, HLengthEq2 HNat x n, SameLength' * * (HReplicateR * n ()) x, Profunctor p, IArray UArray (GetElemTy x), KnownNat (HNat2Nat n), Functor f) => p (RecordU x) (f (RecordU x)) -> p (Record x) (f (Record x)) Source
Iso' (Record x) (RecordU x)
class RecordToRecordU x where Source
Methods
recordToRecordU :: Record x -> RecordU x Source
Instances
| (RecordValues x, HList2List (RecordValuesR x) (GetElemTy x), HNat2Integral n, HLengthEq x n, IArray UArray (GetElemTy x)) => RecordToRecordU x |
class RecordUToRecord x where Source
Methods
recordUToRecord :: RecordU x -> Record x Source
Instances
| (HMapCxt HList TaggedFn (RecordValuesR x) x, IArray UArray (GetElemTy x), HList2List (RecordValuesR x) (GetElemTy x)) => RecordUToRecord x |
definitions for doctest examples
HasField instances
RecordUS
>>>let r = recordToRecordUS (sortForRecordUS bad)>>>let s = recordToRecordUS bad
>>>let x = Label :: Label "x">>>let y = Label :: Label "y">>>let i = Label :: Label "i">>>let j = Label :: Label "j"
>>>(r .!. x, r .!. i, r .!. y, r .!. j)(1.0,2,3.0,4)
>>>(s .!. x, s .!. i, s .!. y, s .!. j)(1.0,2,3.0,4)
RecordU
>>>let t = recordToRecordU bad1>>>(t .!. x, t .!. y)(1.0,2.0)
>>>hUpdateAtLabel x 3 t .!. x3.0