module Data.HList.HZip where
import Data.HList.HList
import Data.HList.FakePrelude
class HZipR (MapFst z) (MapSnd z) ~ z => HUnZip z where
type MapFst z :: [*]
type MapSnd z :: [*]
hZip2 :: HList (MapFst z) -> HList (MapSnd z) -> HList z
hUnzip2 :: HList z -> (HList (MapFst z), HList (MapSnd z))
instance HUnZip '[] where
type MapFst '[] = '[]
type MapSnd '[] = '[]
hZip2 _ _ = HNil
hUnzip2 _ = (HNil, HNil)
instance (z ~ (x,y), HUnZip zs) => HUnZip (z ': zs) where
type MapFst (z ': zs) = ( Fst z ': MapFst zs )
type MapSnd (z ': zs) = ( Snd z ': MapSnd zs )
hZip2 (HCons x xs) (HCons y ys) = HCons (x,y) (hZip2 xs ys)
hUnzip2 (HCons ~(x,y) zs) = let ~(xs,ys) = hUnzip2 zs in (x `HCons` xs, y `HCons` ys)
type family HZipR (x::[*]) (y::[*]) :: [*]
type instance HZipR '[] '[] = '[]
type instance HZipR (x ': xs) (y ': ys) = (x,y) ': HZipR xs ys
type family Fst a
type instance Fst (a,b) = a
type family Snd a
type instance Snd (a,b) = b
hTranspose x = hFoldr HZipF (hReplicate (hLength (hHead x)) HNil) x
class HZip3 x y l | x y -> l, l -> x y where
hZip3 :: HList x -> HList y -> HList l
instance HZip3 '[] '[] '[] where
hZip3 _ _ = HNil
instance (HList (x ': y) ~z, HZip3 xs ys zs) => HZip3 (x ': xs) (HList y ': ys) (z ': zs) where
hZip3 (HCons x xs) (HCons y ys) = HCons x y `HCons` hZip3 xs ys
data HZipF = HZipF
instance (
HZip3 a b c,
x ~ (HList a, HList b),
y ~ HList c) => ApplyAB HZipF x y
where applyAB _ (x,y) = hZip3 x y