La syntaxe d'enregistrement semble extrêmement pratique par rapport à l'écriture de vos propres fonctions d'accès. Je n'ai jamais vu qui que ce soit donner des directives quant à la meilleure utilisation de la syntaxe d'enregistrement par rapport à la syntaxe normale de la déclaration de données. Je vais donc demander ici.Quand dois-je utiliser la syntaxe d'enregistrement pour les déclarations de données dans Haskell?
Répondre
Vous devez utiliser la syntaxe d'enregistrement dans deux situations:
- Le type a beaucoup de champs
- La déclaration de type donne aucune indication sur sa mise en page destiné
Par exemple, un type de point peut être simplement déclaré comme:
data Point = Point Int Int deriving (Show)
Il est évident que le premier t désigne la coordonnée x et la seconde représente et. Mais le cas de la déclaration de type suivante est différent (tiré de Learn You a Haskell for Great Good):
data Person = Person String String Int Float String String deriving (Show)
La mise en page de type prévu est: prénom, nom, âge, taille, numéro de téléphone, et la saveur de crème glacée préférée. Mais ce n'est pas évident dans la déclaration ci-dessus. la syntaxe des enregistrements est à portée de main ici:
data Person = Person { firstName :: String
, lastName :: String
, age :: Int
, height :: Float
, phoneNumber :: String
, flavor :: String
} deriving (Show)
La syntaxe d'enregistrement rend le code plus lisible, et enregistré beaucoup de frappe en définissant automatiquement toutes les fonctions accesseurs pour nous!
En plus des données complexes multi-champs, newtype
sont souvent définis avec la syntaxe d'enregistrement. Dans l'un ou l'autre de ces cas, il n'y a pas vraiment d'inconvénients à utiliser la syntaxe d'enregistrement, mais dans le cas des types de somme, les accesseurs d'enregistrement n'ont généralement pas de sens. Par exemple:
data Either a b = Left { getLeft :: a } | Right { getRight :: b }
est valide, mais les fonctions accesseurs sont partielle - il est une erreur d'écrire getLeft (Right "banana")
. Pour cette raison, de tels accesseurs sont généralement découragés; quelque chose comme getLeft :: Either a b -> Maybe a
serait plus commun, et cela devrait être défini manuellement. Toutefois, notez que accesseurs peuvent partager les noms:
data Item = Food { description :: String, tastiness :: Integer }
| Wand { description :: String, magic :: Integer }
Maintenant description
est totale, bien que tastiness
et magic
les deux sont toujours pas.
Vous avez également une utilisation intéressante de la syntaxe d'enregistrement dans la monade 'State', où' runState' est utilisé comme un peu d'habileté syntaxique. – jberryman
Vous pouvez tirer parti de la typesystem et l'utilisation de type aliasing comme 'Type FirstName = Chaîne Type LastName = type String Âge = Int Type Hauteur = flotteur Type PhoneNumber = Chaîne Type Flavor = Chaîne données Personne = Personne FirstName Nom Age Taille PhoneNumber Flavor deriving (afficher) ' Par conséquent votre argument est invalide. – yaccz