2009-11-26 13 views

Respuesta

19

Se debe utilizar la sintaxis de registro en dos situaciones:

  1. El tipo tiene muchos campos
  2. La declaración de tipo no da ninguna pista sobre su trazado previsto

Por ejemplo, un tipo de punto se pueden simplemente declarado como:

data Point = Point Int Int deriving (Show) 

Es obvio que el primero En t denota la coordenada x y la segunda significa y. Pero el caso con la siguiente declaración de tipo es diferente (tomado de Learn You a Haskell for Great Good):

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

El diseño tipo previsto es: nombre, apellido, edad, altura, número de teléfono, y el sabor favorito de helado. Pero esto no es evidente en la declaración anterior. la sintaxis de registro es muy útil aquí:

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

La sintaxis de registro hizo que el código sea más legible, y se guarda una gran cantidad de tipificación definiendo automáticamente todas las funciones de acceso para nosotros!

+2

También tiene un uso interesante de la sintaxis de registros en la mónada 'State', donde' runState' se usa como un poco de astucia sintáctica. – jberryman

+1

Se podría aprovechar el sistema de tipos y el uso de tipo aliasing como 'Tipo Nombre = Cadena tipo Apellido = cadena tipo Edad = Int tipo Altura = Float tipo Fax = cadena tipo Sabor = cadena Persona datos = Persona FirstName LastName Edad Altura PhoneNumber Flavor deriving (mostrar) ' Por lo tanto, su argumento no es válido. – yaccz

6

Además de los datos complejos de múltiples campos, newtype s a menudo se definen con sintaxis de registro. En cualquiera de estos casos, no hay inconvenientes en el uso de la sintaxis de registros, pero en el caso de los tipos de suma, los accesadores de registros generalmente no tienen sentido. Por ejemplo:

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

es válida, pero las funciones de acceso son parcial - es un error de escribir getLeft (Right "banana"). Por esa razón, en general se desaconseja dicho acceso; algo como getLeft :: Either a b -> Maybe a sería más común, y eso tendría que definirse manualmente. Sin embargo, tenga en cuenta que descriptores de acceso pueden compartir nombres:

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

Ahora description es total, aunque tastiness y magic ambos todavía no lo son.

Cuestiones relacionadas