2009-11-26 14 views

risposta

19

Si dovrebbe usare la sintassi di registrazione in due situazioni:

  1. Il tipo ha molti campi
  2. La dichiarazione del tipo dà alcun indizio circa il suo layout destinato

Per esempio un tipo di punto può essere semplicemente dichiarato come:

data Point = Point Int Int deriving (Show) 

È ovvio che il primo t indica la coordinata x e la seconda sta per y. Ma il caso con la seguente dichiarazione di tipo diverso (tratto da Learn You a Haskell for Great Good):

data Person = Person String String Int Float String String deriving (Show) 

Il layout tipo previsto è: nome, cognome, età, altezza, numero di telefono, e favorito il sapore di gelato. Ma questo non è evidente nella dichiarazione di cui sopra. sintassi Record viene portata di mano qui:

data Person = Person { firstName :: String 
        , lastName :: String 
        , age :: Int 
        , height :: Float 
        , phoneNumber :: String 
        , flavor :: String 
        } deriving (Show) 

La sintassi verbale reso il codice più leggibile, e salvato una grande quantità di battitura definendo automaticamente tutte le funzioni di accesso per noi!

+2

Hai anche un uso interessante della sintassi del record nella monade 'State', dove' runState' è usato come un po 'di intelligenza sintattica. – jberryman

+1

Si potrebbe sfruttare il sistema dei tipi e l'uso di tipo aliasing come 'tipo FirstName = Stringa Tipo Cognome = Stringa tipo Età = Int tipo Altezza = Float tipo PhoneNumber = Stringa tipo Sapore = Stringa persona dati = persona FirstName LastName Età Altezza PhoneNumber Sapore derivante (mostra) ' Pertanto il tuo argomento non è valido. – yaccz

6

Oltre ai dati complessi a più campi, i valori di newtype vengono spesso definiti con la sintassi del record. In nessuno di questi casi, non ci sono davvero dei lati negativi nell'usare la sintassi dei record, ma nel caso dei tipi di somma, i metodi di accesso ai record di solito non hanno senso. Ad esempio:

data Either a b = Left { getLeft :: a } | Right { getRight :: b } 

è valido, ma le funzioni di accesso sono parziale - è un errore di scrivere getLeft (Right "banana"). Per questo motivo, tali utenti sono generalmente scoraggiati; qualcosa come getLeft :: Either a b -> Maybe a sarebbe più comune e dovrebbe essere definito manualmente. Si noti tuttavia che di accesso possono condividere nomi:

data Item = Food { description :: String, tastiness :: Integer } 
    | Wand { description :: String, magic :: Integer } 

Ora description è totale, anche se tastiness e magic entrambi ancora non lo sono.

Problemi correlati