Angenommen, ich habe den folgenden Datensatz ADT:
data Foo = Bar { a :: Integer, b :: String, c :: String }
Ich möchte eine Funktion, die einen Datensatz aufnimmt und einen Datensatz (desselben Typs) zurückgibt, bei dem alle Felder bis auf eines identische Werte wie das als Argument übergebene haben:
walkDuck x = Bar { a = a x, b = b x, c = lemonadeStand (a x) (b x) }
Das Obige funktioniert, aber für einen Datensatz mit mehr Feldern (z. B. 10
) würde das Erstellen einer solchen Funktion viel Tippen erfordern, was ich für ziemlich unnötig halte.
Gibt es weniger langwierige Möglichkeiten, dasselbe zu tun?
Antworten:
Ja, es gibt eine gute Möglichkeit, Datensatzfelder zu aktualisieren. In GHCi können Sie tun -
quelle
RecordWildCards
Erweiterung kann auch nützlich sein, um Felder in einem Bereich zu „entpacken“. Für Updates ist es allerdings nicht ganz so schön:incrementA x@Foo{..} = x { a = succ a }
updateFoo x = x.{ c = "Goodbye" }
(beachten Sie den.
Operator).Dies ist ein guter Job für Objektive :
Dann:
würde das Feld 'c' von 'test' an Ihrer Zeichenfolge aktualisieren.
quelle
test $ c .~ "Goodbye"
ist, wielens
würde es iirc tun. Ich sage nicht, dass dies intuitiv ist, aber wenn Sie die Operatoren kennen, dann gehe ich davon aus, dass es so einfach wie möglich sein wird$
.Sie müssen keine Hilfsfunktionen definieren oder Objektive verwenden. Standard Haskell hat bereits das, was Sie brauchen. Nehmen wir das Beispiel von Don Stewart:
Dann können Sie einfach sagen
test { c = "Goodbye" }
, um einen aktualisierten Datensatz zu erhalten.quelle