Le type (a,b,c,d)
a un profil de performance différent de celui de (a,(b,(c,(d,()))))
. En général, l'indexation dans un n-tuple prend O(1)
alors que l'indexation d'une "hlist" de n nuples imbriqués nécessite O(n)
.
Ceci étant dit, vous devriez consulter le travail classique d'Oleg sur HLists . L'utilisation de HLists nécessite une utilisation extensive, et quelque peu sommaire, de la programmation au niveau des types. Beaucoup de gens trouvent cela inacceptable, et ce n'était pas disponible dans les premiers temps de Haskell. La meilleure façon de représenter une HList aujourd'hui est probablement d'utiliser des GADTs et des DataKinds.
data HList ls where
Nil :: HList '[]
Cons :: x -> HList xs -> HList (x ': xs)
Cela donne une imbrication canonique, et vous permet d'écrire des fonctions qui fonctionnent pour toutes les instances de ce type. Vous pourriez implémenter votre méthode multi zipWith
en utilisant les mêmes techniques que celles utilisées dans printf . Un casse-tête plus intéressant consiste à générer les lentilles appropriées pour ce type (conseil : utilisez les naturelles de niveau type et les familles de types pour l'indexation).
J'ai envisagé d'écrire une bibliothèque de type HList utilisant des tableaux et des unsafeCoerce
sous le capot pour obtenir des performances similaires à celles des tuple tout en restant dans une interface générique. Je ne l'ai pas fait, mais cela ne devrait pas être trop difficile.
EDIT : plus j'y pense, plus je suis enclin à bricoler quelque chose quand j'aurai le temps. Le problème de copie répétée mentionné par Andreas Rossberg peut probablement être éliminé en utilisant la fusion de flux ou des techniques similaires.