Сокращенный способ назначения одного поля в записи при копировании остальных полей?

Скажем, у меня есть следующая запись 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), создание такой функции повлечет за собой много типизации, которое, как мне кажется, совершенно не нужно.

Есть ли менее утомительные способы сделать то же самое?

Ответы

Ответ 1

Да, есть хороший способ обновления полей записей. В 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" }

Ответ 2

Это хорошая работа для объективов:

data Foo = Foo { a :: Int, b :: Int , c :: String }

test = Foo 1 2 "Hello"

Тогда:

setL c "Goodbye" test

обновит поле 'c' 'test' к вашей строке.