haskell - 如何使用实例组织 Haskell 模块 : stick to data type vs type class?

标签 haskell module instance hierarchy typeclass

一般的问题是,在为现有对象添加实例时,哪种模块结构更方便?有哪些优点和缺点?

假设我想为 Seq 类型添加 NFData 实例。我可以把它放在:

  • Data.Sequence.Extra(在 vty 包中也做了同样的事情)
  • Data.Sequence.Instances.NFData(更精确)
  • Control.DeepSeq.Instances
  • Control.DeepSeq.Instances.Sequence

当我既不拥有类型类也不拥有数据类型时就会出现这种情况。另一种常见情况是,当我拥有一个类型类型类并希望从 Hackage 的某些“重”包(例如 OpenGL)添加数据类型的实例时。假设我设计的类型类非常轻,与 OpenGL 没有直接关系。我不希望我的类型类依赖于“重”包,所以我想将OpenGL实例放在一个单独的模块中(这是我的直觉,如果你有其他意见,让我们讨论一下)。那么,这个模块应该是什么:

  • MyClass.Instances.OpenGL
  • Graphics.Rendering.OpenGL.Extra(与其他类的实例一起)
  • Graphics.Rendering.OpenGL.Instances.MyClass

什么是更灵活的解决方案?在某些时候 OpenGL 可以被其他库替换,或者 MyClass 也可以被替换。有什么细微的差别吗?

此外,如果选择 MyClass.Instances 变体,哪种方案更好:

  • MyClass.Class 模块用于类本身和基本实例,MyClass 模块重新导出它(也许还有 MyClass.Instances)
  • MyClass 模块用于类和基本实例,MyClass.All 重新导出所有内容
  • MyClass 类和基本实例的模块,没有用于重新导出的模块。

最佳答案

决定将实例放置在何处的通常过程如下所示:

  1. 如果您正在创建新的数据类型并想要现有类的实例:

    将实例放在与数据类型相同的模块中。

  2. 如果您正在创建新类型类并希望为现有类型创建实例。

    将实例放在与类型类相同的模块中。

  3. 类型类和数据类型都已存在(您的情况)。

    如果实例足够通用,我会联系类型类或数据类型的作者,并尝试说服他们将实例添加到他们的包中。

    否则,创建一个 newtype 包装器并为其编写一个实例。

    只有作为最后的手段才考虑创建孤儿实例。

关于haskell - 如何使用实例组织 Haskell 模块 : stick to data type vs type class?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6641105/

相关文章:

python - 我希望能够动态地向 python 类添加函数,而事先不知道它们的名称

Java - 如何根据用户输入创建类实例

python - Pip 不工作 - ModuleNotFoundError : No module named 'runpy'

java - 实例变量可以在类的底部声明吗?

haskell - Bifunctor 实例定义上的类型签名不匹配

Haskell 列表理解映射

module - 使用 Rcpp 模块的通用方法

java - 运行 JavaFx 媒体应用程序时出现模块错误

Haskell初学者,尝试输出一个列表

haskell - 'return' 关键字有什么特别之处