{-# language AllowAmbiguousTypes, DataKinds, TypeFamilies #-} import Data.Kind (Constraint, Type) import Data.Tagged import GHC.TypeLits (Symbol) type HList :: [Type] -> Type data family HList xs where HList '[] = HNil HList (x ': xs) = x `HCons` HList xs type ZipTagged :: [Symbol] -> [Type] -> [Type] type family ZipTagged ls ts where ZipTagged (l ': ls) (t ': ts) = Tagged l t ': ZipTagged ls ts ZipTagged '[] '[] = '[] type Merge :: [Symbol] -> [Type] -> Constraint class Merge ls ts where merge :: HList ts -> HList (ZipTagged ls ts) instance Merge ls ts => Merge (l : ls) (t : ts) where merge (HCons t ts) = HCons (Tagged @l t) (merge @ls ts) instance Merge '[] '[] where merge HNil = HNil