【问题标题】:Haskell style & typeclass design (should typeclasses be minimized?)Haskell 风格和类型类设计(应该最小化类型类吗?)
【发布时间】:2023-03-25 09:14:01
【问题描述】:

假设

class A a where
   m1 :: a -> a 
   m2 :: a -> a
   m3 :: a -> a
   ...

可以使用 m1 为 m2 和 m3 编写默认实现。

m2m3 留在A 中还是将它们作为额外函数m2 :: A a => a -> a 写在A 之外更好?或者换句话说,是否值得将类 API 最小化或是否重要?

我(快速)查看了一些风格指南,例如 programmin guidelineslarge-scale design-question 中的一些链接,以及一些书籍(工艺和 rwh),但找不到对这本书的推荐。如果有介绍此类问题的演示文稿、博客或书籍,请您分享一些建议吗?

电子邮件列表线程 type class design 讨论了这一点,并可能强调最小化。

【问题讨论】:

  • 您的班级是否有关于m2m3 必须如何表现的任何法律?考虑mconcat,它有一个可以覆盖的默认值,但预计相当于重复应用mappend
  • 就此而言,如果它只是一个外部定义的函数,是否可以覆盖默认值?
  • 就我而言,是的,他们这样做了:我正在玩“参数化的平等”,这个问题在某种程度上也适用于 Eq 和 Ord 类。我认为如果您可以选择在制作实例时编写哪种方法会很方便。但是最小值和最大值呢?
  • @chepner,首先想到覆盖外部定义的函数是不导入函数并编写自己的函数。
  • 如果没有别的,将函数保留在类中提供了实例必须支持该函数的文档。另外,考虑是否有人要定义class A a => B aB 是否需要定义 m2

标签: haskell


【解决方案1】:

如果

  • 该类有多个不同的最小完整定义集,对于给定的实例,您无法先验地判断哪个更简单/更优雅。
  • 可以合理地预期特定类型(例如未装箱的向量)将允许比默认类型更有效地实现 m2m3。如果这些方法不能作为方法被覆盖,则您需要为这种优化重写规则。

具有大量“多余”方法的标准类的示例是(在最近的版本中)Foldable。这部分是由于历史原因,但也因为不同的容器可以具有非常不同的严格性等属性,因此某些方法的默认实现可能对某些实例的性能非常不利。

如果这些注意事项都不适用于您的班级,请将 m2m3 拒之门外。 (您可以随时将它们放入以后:如果您提供默认实现,它不会破坏任何人的代码。)

【讨论】:

  • “多余的”,也许:)
  • 其他好的例子:<$ in Functor and <* and *> in Applicative.
  • 有趣,我不知道<$Functor 中。 (确实 Prelude 没有导出它,所以该方法没有出现在 Haddocks 中。)
  • 另外:join 应该在 Monad 中。
  • 除了(=<<) = flip (>>=),你还想要什么?也许你的意思是<=<
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-12
  • 2016-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多