Haskell 修改成员变量的惯用方法

Haskell 修改成员变量的惯用方法,haskell,Haskell,我知道Haskell不是OO,所以严格来说它不是一个“成员变量” 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 这就是我的代码目前的样子。问题是我现在正在创建包含16个或更多成员的数据类型。当我需要修改单个成员时,会导致非常冗长的代码。有办法解决这个问题吗

我知道Haskell不是OO,所以严格来说它不是一个“成员变量”

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 
这就是我的代码目前的样子。问题是我现在正在创建包含16个或更多成员的数据类型。当我需要修改单个成员时,会导致非常冗长的代码。有办法解决这个问题吗

modifyBar foo = foo { bar = 2 }

此语法将复制
foo
,然后将该副本的
bar
字段修改为2。这可以自然地扩展到更多字段,因此根本不需要编写
modifyBar
函数

(请参见)

Haskell的@KennyTM所展示的“记录语法”是实现这一点的内置方法,但请记住,它仍然只是基于旧值构造新值的一种方法

不过,记录语法有一些恼人的限制,特别是用于“修改”记录中单个项的表单在语言中不是一流的实体,因此不能像使用常规函数那样对它们进行抽象和传递


另一种方法是使用提供类似功能的模板Haskell来自动生成访问器函数,而不是内置语法。结果通常要好得多,缺点是您现在依赖于……

您不需要修改任何内容。你创建了一个新的、不同的值。如果你的数据类型有16个成员,那么很可能其中的一些成员可以组合成一个新的数据类型。请原谅我的无知,因为这似乎是一个普遍的想法,但为什么依赖TH是不好的呢?@Davorak:我认为主要是因为它体积庞大,而且可能不太便于移植。当你在编译一些东西时,GHC花在加载所有依赖项之类的东西上的时间比编译你的实际代码要多,这感觉有点傻。TH得到了这个特别的结果,因为它倾向于为小的三行元编程实用程序提供便利。