2009-11-26 3 views

Répondre

19

Vous devez utiliser la syntaxe d'enregistrement dans deux situations:

  1. Le type a beaucoup de champs
  2. 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!

+2

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

+1

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

6

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.

Questions connexes