HList-0.5.0.0: Heterogeneous lists

Safe HaskellNone
LanguageHaskell2010

Data.HList.RecordU

Contents

Description

The public interface is exported from RecordU

Synopsis

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.

Constructors

RecordUS Any

Any here is the HList u given RecordUSCxt x u

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 Source #

works expected. See examples attached to bad.

Methods

hLookupByLabel :: Label l (RecordUS r) -> v -> v Source #

(RecordUSCxt x u, Show (HList u)) => Show (RecordUS x) Source # 

Methods

showsPrec :: Int -> RecordUS x -> ShowS #

show :: RecordUS x -> String #

showList :: [RecordUS x] -> ShowS #

class RecordUSCxt (x :: [*]) (u :: [*]) | x -> u, u -> x where Source #

connect the unpacked x representation with the corresponding list of RecordU u representation.

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

data EqTagValue Source #

Instances

HEqByFn * EqTagValue Source # 
((~) * txv (Tagged k2 x v), (~) * tyw (Tagged k1 y w), HEq * v w b) => HEqBy * * EqTagValue txv tyw b Source # 

class HMapUnboxF (xs :: [*]) (us :: [*]) | xs -> us, us -> xs Source #

proof that hMap UnboxF :: r xs -> r us can determine xs from us and us from xs

Instances

HMapUnboxF ([] *) ([] *) Source # 
HMapUnboxF xs us => HMapUnboxF ((:) * (HList x) xs) ((:) * (RecordU x) us) Source # 

RecordU

newtype RecordU l Source #

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.

Constructors

RecordU (UArray Int (GetElemTy l)) 

Instances

(ApplyAB f (GetElemTy x) (GetElemTy y), IArray UArray (GetElemTy y), IArray UArray (GetElemTy x)) => HMapAux RecordU f x y Source # 

Methods

hMapAux :: f -> RecordU x -> RecordU y Source #

((~) [*] r r', (~) * v (GetElemTy r), HFindLabel k l r n, HNat2Integral n, IArray UArray v, HasField k l (Record r') v) => HUpdateAtLabel k RecordU l v r r' Source # 

Methods

hUpdateAtLabel :: Label RecordU v -> r -> l r' -> l r' Source #

((~) [*] s t, (~) * a b, IArray UArray a, (~) * a (GetElemTy s), HLensCxt k x RecordU s t a b) => Labelable k x RecordU s t a b Source #

make a Lens' (RecordU s) a

Associated Types

type LabelableTy (s :: [*] -> *) :: LabeledOpticType Source #

Methods

hLens' :: Label x RecordU -> LabeledOptic x RecordU s t a b b Source #

(IArray UArray v, (~) * v (GetElemTy ls), HFindLabel k l ls n, HNat2Integral n) => HasField k l (RecordU ls) v Source # 

Methods

hLookupByLabel :: Label l (RecordU ls) -> v -> v Source #

(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 # 

Methods

hUpdateMany :: Record lv -> RecordU r -> RecordU r Source #

Eq (UArray Int (GetElemTy l)) => Eq (RecordU l) Source # 

Methods

(==) :: RecordU l -> RecordU l -> Bool #

(/=) :: RecordU l -> RecordU l -> Bool #

Ord (UArray Int (GetElemTy l)) => Ord (RecordU l) Source # 

Methods

compare :: RecordU l -> RecordU l -> Ordering #

(<) :: RecordU l -> RecordU l -> Bool #

(<=) :: RecordU l -> RecordU l -> Bool #

(>) :: RecordU l -> RecordU l -> Bool #

(>=) :: RecordU l -> RecordU l -> Bool #

max :: RecordU l -> RecordU l -> RecordU l #

min :: RecordU l -> RecordU l -> RecordU l #

Read (UArray Int (GetElemTy l)) => Read (RecordU l) Source # 
Show (UArray Int (GetElemTy l)) => Show (RecordU l) Source # 

Methods

showsPrec :: Int -> RecordU l -> ShowS #

show :: RecordU l -> String #

showList :: [RecordU l] -> ShowS #

HMapUnboxF xs us => HMapUnboxF ((:) * (HList x) xs) ((:) * (RecordU x) us) Source # 
type LabelableTy RecordU Source # 

type family GetElemTy (x :: [*]) :: * Source #

Instances

type GetElemTy ((:) * (Tagged k label v) rest) Source # 
type GetElemTy ((:) * (Tagged k label v) rest) = v

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)])]

Minimal complete definition

sortForRecordUS

Instances

SortForRecordUS ([] *) ([] *) Source # 
(HPartitionEq * * EqTagValue x ((:) * x xs) xi xo, SortForRecordUS xo xo', (~) [*] sorted (HAppendListR * xi xo'), HAppendList xi xo') => SortForRecordUS ((:) * x xs) sorted Source # 

Methods

sortForRecordUS :: Record ((* ': x) xs) -> Record sorted Source #

Lookup

class HLookupByHNatUS (n :: HNat) (us :: [*]) (e :: *) | n us -> e where Source #

Minimal complete definition

hLookupByHNatUS

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 Source # 

Methods

hLookupByHNatUS :: Proxy HNat n -> HList ((* ': ru) us) -> e Source #

class HLookupByHNatUS1 (r :: Either HNat HNat) (n :: HNat) (u :: [*]) (us :: [*]) (e :: *) | r n u us -> e where Source #

Minimal complete definition

hLookupByHNatUS1

Methods

hLookupByHNatUS1 :: Proxy r -> Proxy n -> RecordU u -> HList us -> e 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 Source # 

Methods

hLookupByHNatUS1 :: Proxy (Either HNat HNat) (Left HNat HNat t) -> Proxy HNat n -> RecordU u -> HList 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 ElemTyEq (xs :: [*]) Source #

all elements of the list have the same type

Instances

ElemTyEq ([] *) Source # 
(~) * t1v (Tagged k t v) => ElemTyEq ((:) * t1v rest) Source # 
((~) * t1v (Tagged k2 t1 v), (~) * t2v (Tagged k1 t2 v), ElemTyEq ((:) * tv2 rest)) => ElemTyEq ((:) * tv1 ((:) * tv2 rest)) 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.

Minimal complete definition

hUpdateMany

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) Source #

implementation in terms of .<++.

Methods

hUpdateMany :: Record lv -> Record x -> Record x Source #

(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 # 

Methods

hUpdateMany :: Record lv -> RecordU r -> RecordU r Source #

class HFindMany (ls :: [k]) (r :: [k]) (ns :: [HNat]) | ls r -> ns Source #

behaves like map HFind

Instances

HFindMany k ([] k) r ([] HNat) Source # 
(HFind k l r n, HFindMany k ls r ns) => HFindMany k ((:) k l ls) r ((:) HNat n ns) Source # 

hMapRU :: HMapCxt RecordU f x y => f -> RecordU x -> RecordU y Source #

hMap specialized to 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)

definitions for doctest examples

type Bad = [Tagged "x" Double, Tagged "i" Int, Tagged "y" Double, Tagged "j" Int] Source #

bad :: Record Bad Source #

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

Implementation Details

data UnboxF Source #

Constructors

UnboxF 

Instances

((~) * hx (HList x), (~) * ux (RecordU x), RecordToRecordU x) => ApplyAB UnboxF hx ux Source # 

Methods

applyAB :: UnboxF -> hx -> ux Source #

data BoxF Source #

Constructors

BoxF 

Instances

((~) * ux (RecordU x), (~) * hx (HList x), RecordUToRecord x) => ApplyAB BoxF ux hx Source # 

Methods

applyAB :: BoxF -> ux -> hx Source #