Je travaille sur des données pour le flux de contrôle qui a une valeur (polymorphe, peut être n'importe quoi), et il pourrait également avoir une fonction de validation qui vérifie si la valeur est toujours bonne, et pourrait avoir une fonction qui "rafraîchit la valeur" (retourne de nouvelles données avec une nouvelle valeur).
En Haskell vanille, cela peut ressembler à ceci :
data MyData a = MyData
{value :: a
,validator :: Maybe (a -> Bool)
,refresher :: Maybe (MyData a -> MyData a)}
Ce que je veux en réalité, ce sont ces types :
data Refreshable = Refreshable | NotRefreshable
data Validatable = Validatable | NotValidatable
MyData (r :: Refreshable) (v :: Validatable)
Je l'ai fait pour Refreshable
mais seulement avec Refreshable
. Je veux le faire aussi avec Validatable
mais je rencontre un problème avec les constructeurs. Juste pour Refreshable
, j'ai besoin d'avoir deux constructeurs, un pour des données rafraîchissables et un autre pour des données non rafraîchissables. Avec la validation, je devrai avoir 4 constructeurs ! (pour les rafraîchissables et validables, pour les non rafraîchissables et validables, pour les validables et non rafraîchissables, et pour les non rafraîchissables et non validables). Et imaginez si j'ai besoin d'un autre champ facultatif plus tard. Encore pire : presque tous les champs sont les mêmes sauf ceux qui changent, il y a donc beaucoup de duplication.
J'ai également essayé de résoudre le problème avec des classes de types / familles de types.
Par exemple, MyData 'Refreshable 'NotValidatable
devient simplement Refreshable data => data
et je pourrais instancer MyData
ou simplement le supprimer pour des données plus spécifiques qui peuvent être une instance.
C'est également problématique, car ce ne sont plus vraiment des champs ; c'est-à-dire que je ne peux pas prendre une donnée sans validateur et la changer en la même donnée avec un validateur (pas au niveau du type).
C'est probablement un problème XY ; je pense qu'une approche plus propre serait de créer des types de données comme Refreshable a
et Validatable a
et de les composer dans MyData
mais je ne sais pas comment faire cela. Je ne peux pas les envelopper car l'ordre changerait tout.
Y a-t-il un moyen propre de faire cela ? ou devrais-je juste me contenter des 4 constructeurs ? ou peut-être que Haskell n'est pas encore prêt pour ce type de choses ? (sans jeu de mots :P).