Сокращенный способ назначения одного поля в записи при копировании остальных полей?
допустим, у меня есть следующая запись ADT:
data Foo = Bar { a :: Integer, b :: String, c :: String }
мне нужна функция, которая принимает запись и возвращает запись (того же типа), где все поля, кроме одного, имеют одинаковые значения с тем, который передается в качестве аргумента, например:
walkDuck x = Bar { a = a x, b = b x, c = lemonadeStand (a x) (b x) }
выше работает, но для записи с нескольких полей (например,10), создание такой функции повлечет за собой много ввода, что я чувствую себя совершенно ненужным.
есть ли менее утомительные способы делать же?
3 ответа:
Да, есть хороший способ обновления полей записи. В GHCi вы можете сделать --
> 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" }
Это хорошая работа для объективы:
data Foo = Foo { a :: Int, b :: Int , c :: String } test = Foo 1 2 "Hello"затем:
setL c "Goodbye" testобновит поле 'c' из 'test' для вашей строки.
вам не нужно определять вспомогательные функции или использовать линзы. Стандартный Haskell уже имеет то, что вам нужно. Давайте возьмем пример Дона Стюарта:
data Foo = Foo { a :: Int, b :: Int , c :: String } test = Foo 1 2 "Hello"затем вы можете просто сказать
test { c = "Goodbye" }для получения обновленной записи.