Safe Haskell | None |
---|---|
Language | Haskell2010 |
The public interface is exported from RecordU
- newtype RecordUS (x :: [*]) = RecordUS Any
- class RecordUSCxt (x :: [*]) (u :: [*]) | x -> u, u -> x where
- 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
- class HLookupByHNatUS (n :: HNat) (us :: [*]) (e :: *) | n us -> e where
- class HLookupByHNatUS1 (r :: Either HNat HNat) (n :: HNat) (u :: [*]) (us :: [*]) (e :: *) | r n u us -> e where
- type family HSubtract (n1 :: HNat) (n2 :: HNat) :: Either HNat HNat
- recordUS :: (HMapUnboxF g2 u2, HMapUnboxF g1 u1, HGroupBy * EqTagValue x2 g2, HGroupBy * EqTagValue x1 g1, Functor f, Profunctor p) => p (RecordUS x1) (f (RecordUS x2)) -> p (HList u1) (f (HList u2))
- recordUS' :: (Profunctor p, Functor f, HGroupBy * EqTagValue x g, HMapUnboxF g u) => 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 :: (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))
- class ElemTyEq (xs :: [*])
- class HUpdateMany lv rx where
- class HFindMany (ls :: [k]) (r :: [k]) (ns :: [HNat]) | 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' :: (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))
- class RecordToRecordU x where
- class RecordUToRecord x where
- 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
newtype 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.
RecordUS Any | Any here is the |
(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 RecordUSCxt (x :: [*]) (u :: [*]) | x -> u, u -> x where Source #
connect the unpacked x
representation with the
corresponding list of RecordU u
representation.
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
(HGroupBy * EqTagValue x g, HMapUnboxF g u) => RecordUSCxt x u Source # | the only instance |
data EqTagValue Source #
class HMapUnboxF (xs :: [*]) (us :: [*]) | xs -> us, us -> xs Source #
HMapUnboxF ([] *) ([] *) Source # | |
HMapUnboxF xs us => HMapUnboxF ((:) * (HList x) xs) ((:) * (RecordU x) us) Source # | |
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.
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 # | |
Lookup
class HLookupByHNatUS (n :: HNat) (us :: [*]) (e :: *) | n us -> e where Source #
hLookupByHNatUS :: Proxy n -> HList us -> e Source #
class HLookupByHNatUS1 (r :: Either HNat HNat) (n :: HNat) (u :: [*]) (us :: [*]) (e :: *) | r n u us -> e where 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
Conversion of RecordUS
with the actual representation
recordUS :: (HMapUnboxF g2 u2, HMapUnboxF g1 u1, HGroupBy * EqTagValue x2 g2, HGroupBy * EqTagValue x1 g1, Functor f, Profunctor p) => p (RecordUS x1) (f (RecordUS x2)) -> p (HList u1) (f (HList u2)) Source #
Iso (HList s) (HList t) (RecordUS a) (RecordUS b)
recordUS' :: (Profunctor p, Functor f, HGroupBy * EqTagValue x g, HMapUnboxF g u) => 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 :: (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)
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 # | |
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)
class RecordToRecordU x where Source #
recordToRecordU :: Record x -> RecordU x Source #
(RecordValues x, HList2List (RecordValuesR x) (GetElemTy x), HNat2Integral n, HLengthEq x n, IArray UArray (GetElemTy x)) => RecordToRecordU x Source # | |
class RecordUToRecord x where Source #
recordUToRecord :: RecordU x -> Record x Source #
(HMapCxt HList TaggedFn (RecordValuesR x) x, IArray UArray (GetElemTy x), HList2List (RecordValuesR x) (GetElemTy x)) => RecordUToRecord x Source # | |
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 .!. x
3.0