Como estaba writing up an answer hace un momento, me encontré con un problema interesante:Registro valor predeterminado sintaxis de descriptor de acceso
data Gender = Male | Female
deriving (Eq, Show)
data Age = Baby | Child | PreTeen | Adult
deriving (Eq, Show, Ord)
data Clothing = Pants Gender Age
| Shirt Gender Age
| Skirt Age -- assumed to be Female
deriving (Show, Eq)
Supongamos que desea escribir el tipo de datos final con la sintaxis de registro:
data Clothing = Pants {gender :: Gender, age :: Age}
| Shirt {gender :: Gender, age :: Age}
| Skirt {age :: Age}
deriving (Show, Eq)
El problema es que quiero gender $ Skirt foo
para evaluar siempre a Female
(independientemente de foo
, que es un Age
). Puedo pensar en algunas maneras de lograr esto, pero requieren que sea
- uso constructores inteligentes, teóricamente permitiendo
Skirt Male foo
pero no exponer constructores - definir mi propia
gender
función
Con # 1, al no exponer el constructor en el módulo, evito efectivamente que los usuarios del módulo aprovechen la sintaxis del registro. Con el n. ° 2, debo renunciar por completo a la sintaxis del registro o definir una función adicional gender'
, que de nuevo vence la sintaxis del registro.
¿Hay alguna manera de aprovechar la sintaxis del registro y también proporcionar un valor "predeterminado" e inmutable para uno de mis constructores? También estoy abierto a soluciones sin sintaxis de registro (¿lentes, quizás?) Siempre y cuando sean igual de elegantes (o más).
Una lente normal no funcionaría, ya que puede asignar el campo 'gender' con dos de los constructores, pero no con el otro. Creo que hacer esto es una mala idea; si 'foo' es un descriptor de acceso de registro, y' foo x' funciona, entonces 'x {foo = y}' también debería. – ehird
Suele ir con 2. – augustss
¿Cómo se ve la adición de una función 'gender'' (o podría llamarlo' totalGender' o 'safeGender' más o menos) ¿derrota la sintaxis del registro? –