Haskell记录设置器导出

4
有没有办法只导出记录的“getter”而不是“setter”?
例如,假设我们有一个 M1.hs 文件。
module M1(customCtor, field1) where
  data DType = DCtor { field1 :: Int }
  customCtor = DCtor { field1 = 1 }

以及 M2.hs

import M1
modified = customCtor{ field1 = 3 }  -- how to prevent this?
main = putStrLn . show . field1 $ modified

我希望能够在M2.hs中运行field1 getter但不更新M1之外的记录。 如果可以的话,您能指向Haskell文档的相关部分吗? 如果不可以,您能解释一下原因吗?


你无法控制导出或导入记录名称,因为Haskell的记录系统最多只能算是hackish。你可能会使用lenses,这比记录要好得多。 - user824425
1
@Rhymoid,能否展示一下使用lenses后我的示例会是什么样子?我是否需要完全放弃记录式数据?还是只需像下面回答中描述的那样导出由lenses提供的访问器函数,类似于同义词?如果不清楚,请原谅,我不知道使用lenses后会是什么样子... - Myuller
一定是脑抽了,使用镜头并不更容易 >_< Neil Brown的解决方案更接近于实用。 - user824425
1个回答

2

一个相对简单的选项是定义一个同义词并导出它:

module M1(customCtor, getField1) where

data DType = DCtor { field1 :: Int }
customCtor = DCtor { field1 = 1 }

getField1 = field1

这里,getField1 是一个“getter”函数(类型:DType -> Int),它获取 field1,但没有更新记录字段的附加状态。


导出类型构造函数 - daniel gratzer
@jozefg。我的示例可以编译并运行,而无需导出类型构造函数。据我所知,导出“DType”允许M1的用户将其包含在其类型签名中。因此,如果我不导出它,他们只能在其签名中放置类型变量或依赖于类型推断。这是正确的吗? - Myuller
是的,没错。导出列表应该写成 module M1(DType, customCtor, getField1)。这会导出类型 DType,但不会导出它的构造函数或字段。如果在导出列表中省略了 DType,则不能在模块外部使用 DType 的名称。 - user824425

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接