我正在检查是否有一些当前的模板-haskell 实践/一些镜头幻想来处理以下简单情况:
data Person = Person {
name :: String,
...
}
data Company = Company {
name :: String,
...
}
目前我正在通过限定导入来避免污染全局命名空间,但它确实使记录访问变得笨拙。
import Person as P
isFred :: Person -> Bool
isFred p = (P.name p) == "Fred"
真的没有更好的方法来访问记录字段吗?
我接受@Emmanuel Touzery 的回答,因为它提供了指向同一领域的另一个问题的有用链接。另一个问题没有出现在“haskell 命名空间”上的搜索中。其他答案没有错,但我只能接受一个。
那里提到的解决方案使用模板 Haskell、镜头、类型类等,基本上为每个字段“HasName”创建一个类型类,并带有单个函数“名称”。每个数据类型都是该类的一个实例,具有自己的实现。然后有一些我不完全理解允许涉及不同类型的魔法。
对于任何想知道这是怎么回事的 Haskell 新手来说,这是因为记录基本上是带有字段选择器的元组,它们被实现为选择(例如)该元组的第二个元素的普通函数。如果您导出这些字段选择器函数,那么它们位于全局命名空间中,迟早(通常很快)您会遇到冲突。
所以 - 你要么限定导入(如我上面的例子),要么尝试想出不冲突的名称(前缀名称并希望最好)。
镜头的东西在 2013 年风靡一时,并允许组合字段选择器/ getter + setter 等。镜头的基本思想并不太复杂,但实现就在我的脑海中。
为了记录(哈!)我认为另一篇文章中的解决方案可能是我所追求的,但它确实涉及大量魔法(5 个扩展只是为了伪造记录命名空间)。
最佳答案
通常只有两种方法,但不幸的是,社区中没有关于它们的共识:
import qualified Data.Person as Person; import Data.Person (Person)
isFred :: Person -> Bool
isFred p = (Person.name p) == "Fred"
将此方法视为与 Java 等语言相同的方法,其中文件仅包含一个类。
data Person = Person {
personName :: String,
personAge :: Int,
...
}
两个镜头库都没有解决这个问题。
关于haskell - 当前关于记录全局命名空间的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19176645/