Shorthand way for assigning a single field in a record, while copying the rest of the fields?

僤鯓⒐⒋嵵緔 提交于 2020-01-28 13:16:29

问题


Let's say I have the following record ADT:

data Foo = Bar { a :: Integer, b :: String, c :: String }

I want a function that takes a record and returns a record (of the same type) where all but one of the fields have identical values to the one passed as argument, like so:

walkDuck x = Bar { a = a x, b = b x, c = lemonadeStand (a x) (b x) }

The above works, but for a record with more fields (say 10), creating a such function would entail a lot of typing that I feel is quite unnecessary.

Are there any less tedious ways of doing the same?


回答1:


Yes, there's a nice way of updating record fields. In GHCi you can do --

> 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:


This is a good job for lenses:

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

test = Foo 1 2 "Hello"

Then:

setL c "Goodbye" test

would update field 'c' of 'test' to your string.




回答3:


You don’t need to define auxiliary functions or employ lenses. Standard Haskell has already what you need. Let’s take the example by Don Stewart:

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

test = Foo 1 2 "Hello"

Then you can just say test { c = "Goodbye" } to get an updated record.



来源:https://stackoverflow.com/questions/14955627/shorthand-way-for-assigning-a-single-field-in-a-record-while-copying-the-rest-o

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!