假设我有以下记录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
),创建这样的函数需要进行大量的输入,我觉得这是非常不必要的。
有没有那么乏味的方法做同样的事情?
答案 0 :(得分:134)
是的,有一种更新记录字段的好方法。在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" }
答案 1 :(得分:31)
lenses这是一个很好的工作:
data Foo = Foo { a :: Int, b :: Int , c :: String }
test = Foo 1 2 "Hello"
然后:
setL c "Goodbye" test
会将'test'的字段'c'更新为您的字符串。
答案 2 :(得分:8)
您不需要定义辅助功能或使用镜头。 Standard Haskell已经满足您的需求。让我们以Don Stewart为例:
data Foo = Foo { a :: Int, b :: Int , c :: String }
test = Foo 1 2 "Hello"
然后,您只需说test { c = "Goodbye" }
即可获取更新的记录。