我正在检查目前没有一些模板 - haskell /一些镜头的优点来处理简单的情况:
data Person = Person {
name :: String,
...
}
data Company = Company {
name :: String,
...
}
Run Code Online (Sandbox Code Playgroud)
目前我通过限定导入来避免污染全局命名空间,但它确实使记录访问变得笨拙.
import Person as P
isFred :: Person -> Bool
isFred p = (P.name p) == "Fred"
Run Code Online (Sandbox Code Playgroud)
是否真的还没有更好的方式来访问记录字段?
我接受了@Emmanuel Touzery的答案,因为它与另一个覆盖同一理由的问题有用.另一个问题没有显示在"haskell名称空间"上的搜索.其他答案没有错,但我只能接受.
这里提到的解决方案使用模板Haskell,镜头,类型等等,基本上为每个字段"HasName"创建一个类型类,其中包含单个函数"name".然后,每个数据类型都是具有自己的实现的该类的实例.然后有一些魔法,我不完全理解允许涉及不同的类型.
对于任何想知道这是什么的Haskell新手来说,这是因为记录基本上是元组,字段选择器实现为普通函数选择(例如)该元组的第二个元素.如果您导出这些字段选择器函数,那么它们将位于全局命名空间中,迟早(通常更早)会发生冲突.
所以 - 您要么限定导入(如上面的示例所示),要么尝试提出不冲突的名称(名称前缀并希望最好).
镜头的东西在2013年风靡一时,可以选择现场选择器/吸气器+定位器等.镜头的基本概念并不太复杂,但实现方式正好在我脑海中.
为了记录(哈哈!)我认为另一篇文章中的解决方案可能就是我所追求的,但它确实涉及大量的魔法(5个扩展仅用于假记录命名空间).
一般来说,只有两种方法,但不幸的是,在社区中没有关于它们的理由:
将带有函数的记录放在单独的文件中,并使用完全别名限定,如下所示:
import qualified Data.Person as Person; import Data.Person (Person)
isFred :: Person -> Bool
isFred p = (Person.name p) == "Fred"
Run Code Online (Sandbox Code Playgroud)
考虑这种方法与Java这样的语言相同,其中文件只包含一个类.
将您的记录放在同一个文件中,同时在字段名称前加上记录名称,例如:
data Person = Person {
personName :: String,
personAge :: Int,
...
}
Run Code Online (Sandbox Code Playgroud)两个镜头库都没有解决这个问题.
已经提出了类似的问题,您可以在这里看到建议镜头的答案: /sf/answers/1224185581/
现在,镜头是 Haskell 社区中的一个大流行词,它们肯定有其用途,并且从长远来看,它们可能是解决命名空间问题的一部分。但我认为目前使用镜头只是为了解决这个问题的人只是少数。正如 Nikita Volkov 所说,合格的导入和前缀将是目前典型的解决方案。
更新:发现了另一个尚未最终确定但似乎很有前途的选项。在这篇博文的结尾处提到了这一点。