Qu'est-ce que vous voulez vraiment est
data HKList :: (k -> *) -> [k] -> * where
Nil :: HKList f '[]
(:*) :: f x -> HKList f xs -> HKList f (x ': xs)
que vous pouvez utiliser soit comme une liste hétérogène ordinaire
type HList = HKList Identity
Ou avec des informations supplémentaires d'un certain type constant e
attaché à chaque valeur (ou un autre intéressant foncteurs)
HKList ((,) e)
Ou avec des informati sur capturé dans un dictionnaire
data Has c a where
Has :: c a => a -> Has c a
type ConstrainedList c = HKList (Has c)
Ou garder des listes de ne capturées contraintes
data Dict1 :: (k -> Constraint) -> k -> * where
Dict1 :: c k => Dict1 c k
que vous pouvez utiliser pour définir l'idée de tous une liste de types satisfaisant une contrainte
class All c xs where
dicts :: HKList (Dict1 c) xs
instance All c '[] where
dicts = Nil
instance (All c xs, c x) => All c (x ': xs) where
dicts = Dict1 :* dicts
Ou toute autre chose que vous pouvez faire avec un type k -> *
Vous pouvez fre ely convertir entre le travail avec All c xs => HList xs
et HKList (Has c) xs
zipHKList :: (forall k. f k -> g k -> h k) -> HKList f xs -> HKList g xs -> HKList h xs
zipHKList _ Nil Nil = Nil
zipHKList f (x :* xs) (y :* ys) = f x y :* zipHKList f xs ys
allToHas :: All c xs => HKList Identity xs -> HKList (Has c) xs
allToHas xs = zipHKList f dicts xs
where
f :: Dict1 c k -> Identity k -> Has c k
f Dict1 (Identity x) = Has x
hasToAll :: HKList (Has c) xs -> Dict (All c xs)
hasToAll Nil = Dict
hasToAll (Has x :* xs) =
case hasToAll xs of
Dict -> Dict
full code
Je l'ai écrit plusieurs fois avant pour divers projets, mais je ne savais pas qu'il était dans une bibliothèque nulle part tant que Kosmikus pointed out that it's in generics-sop
.
Je n'en ai pas vu non plus. J'ai travaillé sur quelque chose comme ça il y a quelque temps, mais je ne l'ai jamais eu sous une forme où je me sentais comme si elle devait être téléchargée. [De plus, vous pouvez rencontrer des coins étranges du système de types explorant ceci] (https://github.com/roboguy13/existentialist/blob/master/src/Data/Existentialist.hs#L67). –