module Data.HList.Record
(
module Data.Tagged,
(.=.),
Record(..),
mkRecord,
emptyRecord,
hEndR,
hEndP,
hListRecord, hListRecord',
LabelsOf,
labelsOf,
asLabelsOf,
RecordValues(..),
recordValues,
hMapTaggedFn,
unlabeled0,
Unlabeled,
unlabeled,
Unlabeled',
unlabeled',
ShowComponents(..),
ShowLabel(..),
(.*.),
(.-.),
HDeleteLabels(..),
HLens(hLens),
HasField(..),
HasFieldM(..),
(.!.),
(.@.),
HUpdateAtLabel(hUpdateAtLabel),
(.<.),
HTPupdateAtLabel,
hTPupdateAtLabel,
hRenameLabel,
Labels,
hProjectByLabels,
hProjectByLabels',
hProjectByLabels2,
HLeftUnion(hLeftUnion),
(.<++.),
UnionSymRec(unionSR),
hRearrange,
hRearrange',
Rearranged(rearranged), rearranged',
hMapR, HMapR(..),
Relabeled(relabeled),
relabeled',
DuplicatedLabel,
ExtraField,
FieldNotFound,
#if __GLASGOW_HASKELL__ != 706
zipTagged,
#endif
HasField'(..),
DemoteMaybe,
HasFieldM1(..),
H2ProjectByLabels(h2projectByLabels),
H2ProjectByLabels'(h2projectByLabels'),
HLabelSet,
HLabelSet',
HRLabelSet,
HAllTaggedLV,
HRearrange(hRearrange2),
HRearrange3(hRearrange3),
HRearrange4(hRearrange4),
UnionSymRec'(..),
HFindLabel,
labelLVPair,
newLVPair,
UnLabel,
HMemberLabel,
TaggedFn(..),
ReadComponent,
HMapTaggedFn,
HLensCxt,
HZipRecord(..),
hZipRecord2, hUnzipRecord2
) where
import Data.HList.FakePrelude
import Data.HList.HListPrelude
import Data.HList.HList
import Data.HList.Label3 (MapLabel)
import Data.Tagged
import Control.Monad
import Text.ParserCombinators.ReadP
import LensDefs
import Data.Array (Ix)
import Data.Semigroup (Semigroup)
import Data.HList.Label6 ()
import Data.HList.TypeEqO ()
labelLVPair :: Tagged l v -> Label l
labelLVPair _ = Label
newLVPair :: Label l -> v -> Tagged l v
newLVPair _ = Tagged
infixr 4 .=.
(.=.) :: Label l -> v -> Tagged l v
l .=. v = newLVPair l v
newtype Record (r :: [*]) = Record (HList r)
deriving instance Semigroup (HList r) => Semigroup (Record r)
deriving instance Monoid (HList r) => Monoid (Record r)
deriving instance (Eq (HList r)) => Eq (Record r)
deriving instance (Ord (HList r)) => Ord (Record r)
deriving instance (Ix (HList r)) => Ix (Record r)
deriving instance (Bounded (HList r)) => Bounded (Record r)
mkRecord :: HRLabelSet r => HList r -> Record r
mkRecord = Record
hListRecord x = isoNewtype mkRecord (\(Record r) -> r) x
hListRecord' x = isSimple hListRecord x
emptyRecord :: Record '[]
emptyRecord = mkRecord HNil
unlabeled0 x = sameLabels (iso recordValues hMapTaggedFn x)
unlabeled :: (Unlabeled x y, Profunctor p, Functor f) =>
(HList (RecordValuesR x) `p` f (HList (RecordValuesR y))) ->
(Record x `p` f (Record y))
unlabeled x = sameLength (unlabeled0 (sameLength x))
type Unlabeled x y =
(HMapCxt HList TaggedFn (RecordValuesR y) y,
RecordValues x, RecordValues y,
SameLength (RecordValuesR x) (RecordValuesR y),
SameLength x y, SameLabels x y,
HAllTaggedLV x, HAllTaggedLV y)
type Unlabeled' x = Unlabeled x x
unlabeled' :: (Unlabeled' x, Profunctor p, Functor f) =>
(HList (RecordValuesR x) `p` f (HList (RecordValuesR x))) ->
(Record x `p` f (Record x))
unlabeled' = unlabeled
class Relabeled r where
relabeled :: forall p f s t a b.
(HMapTaggedFn (RecordValuesR s) a,
HMapTaggedFn (RecordValuesR b) t,
SameLengths '[s,a,t,b],
RecordValuesR t ~ RecordValuesR b,
RecordValuesR s ~ RecordValuesR a,
RecordValues b, RecordValues s,
Profunctor p,
Functor f
) => r a `p` f (r b) -> r s `p` f (r t)
instance Relabeled Record where
relabeled = iso
(\ s -> hMapTaggedFn (recordValues s))
(\ b -> hMapTaggedFn (recordValues b))
relabeled' x = isSimple relabeled x
data TaggedFn = TaggedFn
instance (tx ~ Tagged t x) => ApplyAB TaggedFn x tx where
applyAB _ = Tagged
type HMapTaggedFn l r =
(HMapCxt HList TaggedFn l r,
RecordValuesR r ~ l,
RecordValues r)
hMapTaggedFn :: HMapTaggedFn a b => HList a -> Record b
hMapTaggedFn = Record . hMap TaggedFn
data DuplicatedLabel l
class (HLabelSet (LabelsOf ps), HAllTaggedLV ps) => HRLabelSet (ps :: [*])
instance (HLabelSet (LabelsOf ps), HAllTaggedLV ps) => HRLabelSet (ps :: [*])
class HLabelSet ls
instance HLabelSet '[]
instance HLabelSet '[x]
instance ( HEqK l1 l2 leq
, HLabelSet' l1 l2 leq r
) => HLabelSet (l1 ': l2 ': r)
class HLabelSet' l1 l2 (leq::Bool) r
instance ( HLabelSet (l2 ': r)
, HLabelSet (l1 ': r)
) => HLabelSet' l1 l2 False r
instance ( Fail (DuplicatedLabel l1) ) => HLabelSet' l1 l2 True r
type family LabelsOf (ls :: [*]) :: [*]
type instance LabelsOf '[] = '[]
type instance LabelsOf (Label l ': r) = Label l ': LabelsOf r
type instance LabelsOf (Tagged l v ': r) = Label l ': LabelsOf r
labelsOf :: hlistOrRecord l -> Proxy (LabelsOf l)
labelsOf _ = Proxy
type family UnLabel (proxy :: k) (ls :: [*]) :: [k]
type instance UnLabel proxy (Label x ': xs) = x ': UnLabel proxy xs
type instance UnLabel proxy '[] = '[]
type HFindLabel (l :: k) (ls :: [*]) (n :: HNat) = HFind l (UnLabel l (LabelsOf ls)) n
class SameLength r (RecordValuesR r)
=> RecordValues (r :: [*]) where
type RecordValuesR r :: [*]
recordValues' :: HList r -> HList (RecordValuesR r)
instance RecordValues '[] where
type RecordValuesR '[] = '[]
recordValues' _ = HNil
instance (SameLength' r (RecordValuesR r),
SameLength' (RecordValuesR r) r, RecordValues r) => RecordValues (Tagged l v ': r) where
type RecordValuesR (Tagged l v ': r) = v ': RecordValuesR r
recordValues' (HCons (Tagged v) r) = HCons v (recordValues' r)
recordValues :: RecordValues r => Record r -> HList (RecordValuesR r)
recordValues (Record r) = recordValues' r
instance ShowComponents r => Show (Record r) where
show (Record r) = "Record{"
++ showComponents "" r
++ "}"
class ShowComponents l where
showComponents :: String -> HList l -> String
instance ShowComponents '[] where
showComponents _ _ = ""
instance ( ShowLabel l
, Show v
, ShowComponents r
)
=> ShowComponents (Tagged l v ': r) where
showComponents comma (HCons f@(Tagged v) r)
= comma
++ showLabel ((labelLVPair f) :: Label l)
++ "="
++ show v
++ showComponents "," r
data ReadComponent = ReadComponent Bool
instance (Read v, ShowLabel l,
x ~ Tagged l v,
ReadP x ~ y) =>
ApplyAB ReadComponent (Proxy x) y where
applyAB (ReadComponent comma) _ = do
when comma (() <$ string ",")
_ <- string (showLabel (Label :: Label l))
_ <- string "="
v <- readS_to_P reads
return (Tagged v)
instance (HMapCxt HList ReadComponent (AddProxy rs) bs,
ApplyAB ReadComponent (Proxy r) readP_r,
HProxies rs,
HSequence ReadP (readP_r ': bs) (r ': rs),
r ~ Tagged l v,
ShowLabel l,
Read v,
HSequence ReadP bs rs
) => Read (Record (r ': rs)) where
readsPrec _ = readP_to_S $ do
_ <- string "Record{"
content <- hSequence parsers
_ <- string "}"
return (Record content)
where
rs :: HList (AddProxy rs)
rs = hProxies
readP_r :: readP_r
readP_r = applyAB
(ReadComponent False)
(Proxy :: Proxy r)
parsers = readP_r `HCons` (hMap (ReadComponent True) rs :: HList bs)
instance HRLabelSet (t ': r)
=> HExtend t (Record r) where
type HExtendR t (Record r) = Record (t ': r)
f .*. (Record r) = mkRecord (HCons f r)
instance (HRLabelSet (HAppendListR r1 r2), HAppend (HList r1) (HList r2))
=> HAppend (Record r1) (Record r2) where
hAppend (Record r) (Record r') = mkRecord (hAppend r r')
type instance HAppendR (Record r1) (Record r2) = Record (HAppendListR r1 r2)
class HasField (l::k) r v | l r -> v where
hLookupByLabel:: Label l -> r -> v
class HasFieldM (l :: k) r (v :: Maybe *) | l r -> v where
hLookupByLabelM :: Label l
-> r
-> t
-> DemoteMaybe t v
type family DemoteMaybe (d :: *) (v :: Maybe *) :: *
type instance DemoteMaybe d (Just a) = a
type instance DemoteMaybe d Nothing = d
class HasFieldM1 (b :: Maybe [*]) (l :: k) r v | b l r -> v where
hLookupByLabelM1 :: Proxy b -> Label l -> r -> t -> DemoteMaybe t v
instance (HMemberM (Label l) (LabelsOf xs) b,
HasFieldM1 b l (r xs) v) => HasFieldM l (r xs) v where
hLookupByLabelM = hLookupByLabelM1 (Proxy :: Proxy b)
instance HasFieldM1 Nothing l r Nothing where
hLookupByLabelM1 _ _ _ t = t
instance HasField l r v => HasFieldM1 (Just b) l r (Just v) where
hLookupByLabelM1 _ l r _t = hLookupByLabel l r
instance (HEqK l l1 b, HasField' b l (Tagged l1 v1 ': r) v)
=> HasField l (Record (Tagged l1 v1 ': r)) v where
hLookupByLabel l (Record r) =
hLookupByLabel' (Proxy::Proxy b) l r
instance (t ~ Any, Fail (FieldNotFound l ())) => HasField l (Record '[]) t where
hLookupByLabel _ _ = error "Data.HList.Record.HasField: Fail instances should not exist"
class HasField' (b::Bool) (l :: k) (r::[*]) v | b l r -> v where
hLookupByLabel':: Proxy b -> Label l -> HList r -> v
instance HasField' True l (Tagged l v ': r) v where
hLookupByLabel' _ _ (HCons (Tagged v) _) = v
instance HasField l (Record r) v => HasField' False l (fld ': r) v where
hLookupByLabel' _ l (HCons _ r) = hLookupByLabel l (Record r)
infixr 9 .!.
(.!.) :: (HasField l r v) => r -> Label l -> v
r .!. l = hLookupByLabel l r
instance (H2ProjectByLabels '[Label l] v t1 v')
=> HDeleteAtLabel Record l v v' where
hDeleteAtLabel _ (Record r) =
Record $ snd $ h2projectByLabels (Proxy::Proxy '[Label l]) r
infixl 2 .-.
(.-.) :: (HDeleteAtLabel r l xs xs') =>
r xs -> Label l -> r xs'
r .-. l = hDeleteAtLabel l r
class
HUpdateAtLabel record (l :: k) (v :: *) (r :: [*]) (r' :: [*])
| l v r -> r', l r' -> v where
hUpdateAtLabel :: SameLength r r' => Label l -> v -> record r -> record r'
instance (HUpdateAtLabel2 l v r r',
HasField l (Record r') v) =>
HUpdateAtLabel Record l v r r' where
hUpdateAtLabel = hUpdateAtLabel2
class HUpdateAtLabel2 (l :: k) (v :: *) (r :: [*]) (r' :: [*])
| l r v -> r' where
hUpdateAtLabel2 :: Label l -> v -> Record r -> Record r'
class HUpdateAtLabel1 (b :: Bool) (l :: k) (v :: *) (r :: [*]) (r' :: [*])
| b l v r -> r' where
hUpdateAtLabel1 :: Proxy b -> Label l -> v -> Record r -> Record r'
instance HUpdateAtLabel1 True l v (Tagged l e ': xs) (Tagged l v ': xs) where
hUpdateAtLabel1 _b _l v (Record (e `HCons` xs)) = Record (e{ unTagged = v } `HCons` xs)
instance HUpdateAtLabel2 l v xs xs' => HUpdateAtLabel1 False l v (x ': xs) (x ': xs') where
hUpdateAtLabel1 _b l v (Record (x `HCons` xs)) = case hUpdateAtLabel2 l v (Record xs) of
Record xs' -> Record (x `HCons` xs')
instance (HEqK l l' b, HUpdateAtLabel1 b l v (Tagged l' e ': xs) xs')
=> HUpdateAtLabel2 l v (Tagged l' e ': xs) xs' where
hUpdateAtLabel2 = hUpdateAtLabel1 (Proxy :: Proxy b)
instance Fail (FieldNotFound l ()) => HUpdateAtLabel2 l v '[] '[] where
hUpdateAtLabel2 _ _ r = r
infixr 2 .@.
f@(Tagged v) .@. r = hUpdateAtLabel (labelLVPair f) v r
hProjectByLabels :: (HRLabelSet a, H2ProjectByLabels ls t a b) =>
proxy ls -> Record t -> Record a
hProjectByLabels ls (Record r) = mkRecord (fst $ h2projectByLabels ls r)
hProjectByLabels2 ::
(H2ProjectByLabels ls t t1 t2, HRLabelSet t1, HRLabelSet t2) =>
Proxy ls -> Record t -> (Record t1, Record t2)
hProjectByLabels2 ls (Record r) = (mkRecord rin, mkRecord rout)
where (rin,rout) = h2projectByLabels ls r
hProjectByLabels' r =
let r' = hRearrange' (hProjectByLabels (labelsOf r') r)
in r'
type family Labels (xs :: [k]) :: *
type instance Labels xs = Proxy (Labels1 xs)
type family Labels1 (xs :: [k]) :: [*]
type instance Labels1 '[] = '[]
type instance Labels1 (x ': xs) = Label x ': Labels1 xs
class H2ProjectByLabels (ls::[*]) r rin rout | ls r -> rin rout where
h2projectByLabels :: proxy ls -> HList r -> (HList rin,HList rout)
instance H2ProjectByLabels '[] r '[] r where
h2projectByLabels _ r = (HNil,r)
instance H2ProjectByLabels (l ': ls) '[] '[] '[] where
h2projectByLabels _ _ = (HNil,HNil)
instance (HMemberM (Label l1) ((l :: *) ': ls) (b :: Maybe [*]),
H2ProjectByLabels' b (l ': ls) (Tagged l1 v1 ': r1) rin rout)
=> H2ProjectByLabels (l ': ls) (Tagged l1 v1 ': r1) rin rout where
h2projectByLabels = h2projectByLabels' (Proxy::Proxy b)
class H2ProjectByLabels' (b::Maybe [*]) (ls::[*]) r rin rout
| b ls r -> rin rout where
h2projectByLabels' :: Proxy b -> proxy ls ->
HList r -> (HList rin,HList rout)
instance H2ProjectByLabels ls1 r rin rout =>
H2ProjectByLabels' ('Just ls1) ls (f ': r) (f ': rin) rout where
h2projectByLabels' _ _ (HCons x r) = (HCons x rin, rout)
where (rin,rout) = h2projectByLabels (Proxy::Proxy ls1) r
instance H2ProjectByLabels ls r rin rout =>
H2ProjectByLabels' 'Nothing ls (f ': r) rin (f ': rout) where
h2projectByLabels' _ ls (HCons x r) = (rin, HCons x rout)
where (rin,rout) = h2projectByLabels ls r
hRenameLabel l l' r = r''
where
v = hLookupByLabel l r
r' = hDeleteAtLabel l r
r'' = newLVPair l' v .*. r'
type HTPupdateAtLabel record l v r = (HUpdateAtLabel record l v r r, SameLength' r r)
hTPupdateAtLabel :: HTPupdateAtLabel record l v r => Label l -> v -> record r -> record r
hTPupdateAtLabel l v r = hUpdateAtLabel l v r
infixr 2 .<.
f@(Tagged v) .<. r = hTPupdateAtLabel (labelLVPair f) v r
instance H2ProjectByLabels (LabelsOf r2) r1 r2 rout
=> SubType (Record r1) (Record r2)
type HMemberLabel l r b = HMember l (UnLabel l (LabelsOf r)) b
class HDeleteLabels ks r r' | ks r -> r'
where hDeleteLabels :: proxy (ks :: [*])
-> Record r -> Record r'
instance (HMember (Label l) ks b,
HCond b (Record r2) (Record (Tagged l v ': r2)) (Record r3),
HDeleteLabels ks r1 r2) =>
HDeleteLabels ks (Tagged l v ': r1) r3 where
hDeleteLabels ks (Record (HCons lv r1)) =
case hDeleteLabels ks (Record r1) of
Record r2 -> hCond (Proxy :: Proxy b)
(Record r2)
(Record (HCons lv r2))
instance HDeleteLabels ks '[] '[] where
hDeleteLabels _ _ = emptyRecord
class HLeftUnion r r' r'' | r r' -> r''
where hLeftUnion :: Record r -> Record r' -> Record r''
instance (HDeleteLabels (LabelsOf l) r r',
HAppend (Record l) (Record r'),
HAppendR (Record l) (Record r') ~ (Record lr)) => HLeftUnion l r lr
where hLeftUnion l r = l `hAppend` hDeleteLabels (labelsOf l) r
infixl 1 .<++.
(.<++.) :: (HLeftUnion r r' r'') => Record r -> Record r' -> Record r''
r .<++. r' = hLeftUnion r r'
class UnionSymRec r1 r2 ru | r1 r2 -> ru where
unionSR :: Record r1 -> Record r2 -> (Record ru, Record ru)
instance (r1 ~ r1') => UnionSymRec r1 '[] r1' where
unionSR r1 _ = (r1, r1)
instance ( HMemberLabel l r1 b
, UnionSymRec' b r1 (Tagged l v) r2' ru
)
=> UnionSymRec r1 (Tagged l v ': r2') ru
where
unionSR r1 (Record (HCons f r2')) =
unionSR' (Proxy::Proxy b) r1 f (Record r2')
class UnionSymRec' (b :: Bool) r1 f2 r2' ru | b r1 f2 r2' -> ru where
unionSR' :: Proxy b -> Record r1 -> f2 -> Record r2' -> (Record ru, Record ru)
instance (UnionSymRec r1 r2' ru,
HTPupdateAtLabel Record l2 v2 ru,
f2 ~ Tagged l2 v2)
=> UnionSymRec' True r1 f2 r2' ru where
unionSR' _ r1 (Tagged v2) r2' =
case unionSR r1 r2'
of (ul,ur) -> (ul, hTPupdateAtLabel (Label :: Label l2) v2 ur)
instance (UnionSymRec r1 r2' ru,
HExtend f2 (Record ru),
Record f2ru ~ HExtendR f2 (Record ru)
)
=> UnionSymRec' False r1 f2 r2' f2ru where
unionSR' _ r1 f2 r2' = (ul', ur')
where (ul,ur) = unionSR r1 r2'
ul' = f2 .*. ul
ur' = f2 .*. ur
hRearrange :: (HLabelSet ls, HRearrange ls r r') => Proxy ls -> Record r -> Record r'
hRearrange ls (Record r) = Record (hRearrange2 ls r)
hRearrange' r =
let r' = hRearrange (labelsOf r') r
in r'
class Rearranged r s t a b where
rearranged :: (Profunctor p, Functor f) => r a `p` f (r b) -> r s `p` f (r t)
instance (la ~ LabelsOf a, lt ~ LabelsOf t,
HRearrange la s a,
HRearrange lt b t,
HLabelSet la,
HLabelSet lt)
=> Rearranged Record s t a b where
rearranged = iso (hRearrange (Proxy :: Proxy la))
(hRearrange (Proxy :: Proxy lt))
rearranged' x = isSimple rearranged x
class (HRearrange3 ls r r', LabelsOf r' ~ ls,
SameLength ls r, SameLength r r')
=> HRearrange (ls :: [*]) r r' | ls r -> r', r' -> ls where
hRearrange2 :: proxy ls -> HList r -> HList r'
instance (HRearrange3 ls r r', LabelsOf r' ~ ls,
SameLength ls r, SameLength r r') => HRearrange ls r r' where
hRearrange2 = hRearrange3
class HRearrange3 (ls :: [*]) r r' | ls r -> r' where
hRearrange3 :: proxy ls -> HList r -> HList r'
instance HRearrange3 '[] '[] '[] where
hRearrange3 _ _ = HNil
instance (H2ProjectByLabels '[l] r rin rout,
HRearrange4 l ls rin rout r',
l ~ Label ll) =>
HRearrange3 (l ': ls) r r' where
hRearrange3 _ r = hRearrange4 (Proxy :: Proxy l) (Proxy :: Proxy ls) rin rout
where (rin, rout) = h2projectByLabels (Proxy :: Proxy '[l]) r
class HRearrange4 (l :: *) (ls :: [*]) rin rout r' | l ls rin rout -> r' where
hRearrange4 :: proxy l -> Proxy ls -> HList rin -> HList rout -> HList r'
instance (HRearrange3 ls rout r',
r'' ~ (Tagged l v ': r'),
ll ~ Label l) =>
HRearrange4 ll ls '[Tagged l v] rout r'' where
hRearrange4 _ ls (HCons lv@(Tagged v) _HNil) rout
= HCons (Tagged v `asTypeOf` lv) (hRearrange3 ls rout)
instance Fail (FieldNotFound l ()) =>
HRearrange4 l ls '[] rout '[] where
hRearrange4 _ _ _ _ = error "Fail has no instances"
instance Fail (ExtraField l) =>
HRearrange3 '[] (Tagged l v ': a) '[] where
hRearrange3 _ _ = error "Fail has no instances"
type HLensCxt x r s t a b =
(HasField x (r s) a,
HUpdateAtLabel r x b s t,
HasField x (r t) b,
HUpdateAtLabel r x a t s,
SameLength s t,
SameLabels s t)
class HLensCxt x r s t a b => HLens x r s t a b
| x s b -> t, x t a -> s,
x s -> a, x t -> b where
hLens :: Label x -> (forall f. Functor f => (a -> f b) -> (r s -> f (r t)))
instance HLensCxt r x s t a b => HLens r x s t a b where
hLens lab f rec = fmap (\v -> hUpdateAtLabel lab v rec) (f (rec .!. lab))
hMapR f r = applyAB (HMapR f) r
newtype HMapR f = HMapR f
instance (HMapCxt Record f x y, rx ~ Record x, ry ~ Record y)
=> ApplyAB (HMapR f) rx ry where
applyAB (HMapR f) = hMapAux f
instance HMapAux HList (HFmap f) x y =>
HMapAux Record f x y where
hMapAux f (Record x) = Record (hMapAux (HFmap f) x)
instance (HReverse l lRev,
HMapTaggedFn lRev l') => HBuild' l (Record l') where
hBuild' l = hMapTaggedFn (hReverse l)
hEndR :: Record a -> Record a
hEndR = id
instance (HRevAppR l '[] ~ lRev,
HExtendRs lRev (Proxy ('[] :: [*])) ~ Proxy l1,
l' ~ l1) => HBuild' l (Proxy l') where
hBuild' _ = Proxy
hEndP :: Proxy (xs :: [k]) -> Proxy xs
hEndP = id
type family HExtendRs (ls :: [*]) (z :: k) :: k
type instance HExtendRs (l ': ls) z = HExtendR l (HExtendRs ls z)
type instance HExtendRs '[] z = z
instance (HZipRecord x y xy, SameLengths [x,y,xy])
=> HZip Record x y xy where
hZip = hZipRecord
instance (HZipRecord x y xy, SameLengths [x,y,xy])
=> HUnzip Record x y xy where
hUnzip = hUnzipRecord
#if __GLASGOW_HASKELL__ != 706
zipTagged :: (MapLabel ts ~ lts,
HZip Proxy lts vs tvs)
=> Proxy ts -> proxy vs -> Proxy tvs
zipTagged _ _ = Proxy
#endif
class HZipRecord x y xy | x y -> xy, xy -> x y where
hZipRecord :: Record x -> Record y -> Record xy
hUnzipRecord :: Record xy -> (Record x,Record y)
instance HZipRecord '[] '[] '[] where
hZipRecord _ _ = emptyRecord
hUnzipRecord _ = (emptyRecord, emptyRecord)
instance HZipRecord as bs abss
=> HZipRecord (Tagged x a ': as) (Tagged x b ': bs) (Tagged x (a,b) ': abss) where
hZipRecord (Record (Tagged a `HCons` as)) (Record (Tagged b `HCons` bs)) =
let Record abss = hZipRecord (Record as) (Record bs)
in Record (Tagged (a,b) `HCons` abss)
hUnzipRecord (Record (Tagged (a,b) `HCons` abss)) =
let (Record as, Record bs) = hUnzipRecord (Record abss)
in (Record (Tagged a `HCons` as), Record (Tagged b `HCons` bs))
hZipRecord2 x y = hMapTaggedFn (hZipList (recordValues x) (recordValues y))
`asLabelsOf` x `asLabelsOf` y
hUnzipRecord2 xy = let (x,y) = hUnzipList (recordValues xy)
in (hMapTaggedFn x `asLabelsOf` xy, hMapTaggedFn y `asLabelsOf` xy)
asLabelsOf :: (HAllTaggedLV x, SameLabels x y, SameLength x y) => r x -> s y -> r x
asLabelsOf = const