在记录中分配单个字段,同时复制其余字段的速记方法?

假设我有以下 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) ,创建这样的函数需要进行大量键入,我认为这是完全没有必要的。

还有什么方法可以减少这种无聊的做法吗?

34593 次浏览

是的,有一个很好的方法来更新记录字段。在 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

将“ test”的字段“ c”更新为字符串。

你不需要定义辅助功能或使用透镜。Standard Haskell 已经有你需要的东西了。让我们以唐•斯图尔特(Don Stewart)为例:

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


test = Foo 1 2 "Hello"

然后你可以说 test { c = "Goodbye" }来得到一个更新的记录。