136

假设我有以下记录 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)的记录,创建这样的函数将需要大量输入,我认为这是非常不必要的。

有没有更乏味的方法来做同样的事情?

4

3 回答 3

181

是的,有一种更新记录字段的好方法。在 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" }
于 2013-02-19T10:54:42.023 回答
40

这是镜头的好工作:

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

test = Foo 1 2 "Hello"

然后:

setL c "Goodbye" test

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

于 2013-02-19T14:57:59.710 回答
25

您无需定义辅助功能或使用镜头。标准 Haskell 已经拥有你所需要的。让我们以唐斯图尔特的例子为例:

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

test = Foo 1 2 "Hello"

然后你可以说test { c = "Goodbye" }获取更新的记录。

于 2018-08-17T15:33:22.150 回答