Disons que j'ai le record ADT suivant:
data Foo = Bar { a :: Integer, b :: String, c :: String }
Je veux une fonction qui prend un enregistrement et renvoie un enregistrement (du même type) où tous les champs sauf un ont des valeurs identiques à celle passée en argument, comme ceci:
walkDuck x = Bar { a = a x, b = b x, c = lemonadeStand (a x) (b x) }
Ce qui précède fonctionne, mais pour un enregistrement avec plus de champs (disons 10
), la création d'une telle fonction impliquerait beaucoup de saisie que je trouve tout à fait inutile.
Existe-t-il des moyens moins fastidieux de faire de même?
Oui, il existe une bonne façon de mettre à jour les champs d'enregistrement. Dans GHCi, vous pouvez faire -
> data Foo = Foo { a :: Int, b :: Int, c :: String } -- define a Foo
> let foo = Foo { a = 1, b = 2, c = "Hello" } -- create a Foo
> let updateFoo x = x { c = "Goodbye" } -- function to update Foos
> updateFoo foo -- update the Foo
Foo {a = 1, b = 2, c = "Goodbye" }
C'est un bon travail pour lentilles :
data Foo = Foo { a :: Int, b :: Int , c :: String }
test = Foo 1 2 "Hello"
Ensuite:
setL c "Goodbye" test
mettrait à jour le champ "c" de "test" dans votre chaîne.
Vous n'avez pas besoin de définir de fonctions auxiliaires ou d'employer des objectifs. Standard Haskell a déjà ce dont vous avez besoin. Prenons l'exemple de Don Stewart:
data Foo = Foo { a :: Int, b :: Int , c :: String }
test = Foo 1 2 "Hello"
Ensuite, vous pouvez simplement dire test { c = "Goodbye" }
pour obtenir un enregistrement mis à jour.