Digamos que tengo el siguiente registro ADT:
data Foo = Bar { a :: Integer, b :: String, c :: String }
Quiero una función que tome un registro y devuelva un registro (del mismo tipo) donde todos menos uno de los campos tienen valores idénticos al que se pasó como argumento, así:
walkDuck x = Bar { a = a x, b = b x, c = lemonadeStand (a x) (b x) }
Lo anterior funciona, pero para un registro con más campos (digamos 10
), crear una función de este tipo implicaría una gran cantidad de escritura que creo que es bastante innecesaria.
¿Hay formas menos tediosas de hacer lo mismo?
Respuestas:
Sí, existe una buena forma de actualizar los campos de registro. En GHCi puedes hacer -
fuente
RecordWildCards
extensión también puede ser buena para "descomprimir" campos en un ámbito. Sin embargo, para las actualizaciones no es tan agradable:incrementA x@Foo{..} = x { a = succ a }
updateFoo x = x.{ c = "Goodbye" }
(observe el.
operador).Este es un buen trabajo para lentes :
Luego:
actualizaría el campo 'c' de 'prueba' a su cadena.
fuente
test $ c .~ "Goodbye"
es cómolens
lo haría iirc. No estoy diciendo que esto sea intuitivo, pero una vez que conozca los operadores, espero que sea tan fácil como$
.No es necesario definir funciones auxiliares ni emplear lentes. Haskell estándar ya tiene lo que necesitas. Tomemos el ejemplo de Don Stewart:
Entonces puede simplemente decir
test { c = "Goodbye" }
que obtenga un registro actualizado.fuente