haskell - 当前关于记录全局命名空间的最佳实践

标签 haskell

我正在检查是否有一些当前的模板-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/

    相关文章:

    macos - 无法在 Mac 上安装图表/arithmoi

    haskell - monad bind (>>=) 运算符是否更接近函数组合(链接)或函数应用程序?

    oop - Haskell 中的面向对象多态性

    haskell - 为什么 haskell 版本控制策略有两个主要版本的地方,而不是语义版本控制中的一个?

    haskell - 由于缩进而调试显式字符

    haskell - "applicative"是什么意思?

    list - Haskell 列表 Monad 状态依赖

    haskell - 与 Functor 合作时的令人振奋的策略

    haskell - 找不到模块 `Control.Parallel'

    perl - Perl 5 中惰性求值技术的例子?