开发者

Idiomatic way to modify a member variable

I know Haskell isn't OO so it isn't strictly a 'member variable'.

data Foo = Foo {
    bar :: Int,
    moo :: Int,
    meh :: Int,
    yup :: Int
}

modifyBar (Foo b m me y) = (Foo b' m me y)
    where b' = 2 

This is how my code looks at the moment. The problem is I am开发者_开发技巧 now making data types with 16 or more members. When I need to modify a single member it results in very verbose code. Is there a way around this?


modifyBar foo = foo { bar = 2 }

This syntax will copy foo, and then modify the bar field of that copy to 2. This could be naturally extended to more fields, so you don't need to write that modifyBar function at all.

(See http://book.realworldhaskell.org/read/code-case-study-parsing-a-binary-data-format.html#id625467)


Haskell's "record syntax" that @KennyTM shows is the built-in way to do this, though keep in mind that it's still just a way of constructing a new value based on the old one.

There are some annoying limitations to record syntax, though, particularly that the form used to "modify" a single item in a record aren't first-class entities in the language, so you can't abstract over them and pass them around the way you'd do with a regular function.

An alternative is using a library such as fclabels which provides similar functionality, using Template Haskell to auto-generate accessor functions instead of built-in syntax. The result is often much nicer, with the downside that you now have a dependency on TH....

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜