Haskell标准库类型类的替代实现

时间:2011-04-20 12:28:11

标签: haskell typeclass standard-library

我见过很多人抱怨标准库中的某些类型类,说“Monad应该要求Functor”,甚至“Monad应该要求Applicative”,“Applicative应该要求Pointed”,“Num不应该要求显示“等, 所以,我有一些问题:

  1. 类型类依赖关系树的方式是否存在社区认为存在“缺陷”的方式,或者这只是历史事件的结果?

  2. 这种变化有多大会破坏现有代码?

  3. 是否有基本类型类的替代实现(特别是箭头,monad,applicative等等)实现“正确”的类依赖关系?

4 个答案:

答案 0 :(得分:18)

除了向后兼容性之外,由于Haskell处理类型类的相当简单的方式,有一些(主要是装饰性的,但是很难处理)问题:

没有向上隐式定义Monad仅由pure(>>=)完全定义; fmap(<*>)可以用这些来写。在“适当的”层次结构中,每个实例都需要写出来。在这种情况下并不是太糟糕,但随着粒度的增加,每个添加一些小功能的实例数也会增加。如果类定义可以根据它们自己的函数提供超类函数的默认实现,那么它将大大简化事情,因此像(>>=)这样完全包含超类中多个函数的函数可以作为整个相关层次结构的定义。 / p>

上下文膨胀:只要Num需要ShowEq的“原因”,这是因为打印和比较数字相等是很常见的。这些是严格正交的,但是将它们分开意味着完成所有三件事的函数现在必须在它们的类型中指定所有三个类。这在技术上是一件好事,但同样,随着粒度的增加,函数类型签名也会增加。

单一依赖项:类型类及其超类的层次结构可以添加到但不能更改或替换。如果一段代码感觉需要替换一些常见类型类的自己版本 - 比如使用something like this来替换Monad - 那么层次结构就会被切断;使用Monad的其他定义与代码的兼容性必须在某种程度上手动提供,并且构建在另一个定义之上的任何类型类都必须重新实现或转换,即使仅依赖于两个定义共享的行为的子集

没有明确正确的层次结构:如上所述,可以在类的粒度中进行选择。例如,Pointed确实需要存在,还是仅仅Applicative就足够了?这里真的没有答案,这是普遍的理想,而且不应该有。

我怀疑,首先解决上述问题可以更好地解决现有类型类别的问题,之后更换类型类别将不那么痛苦,甚至只是一种形式。例如,@ luqui提到的类型类同义词提议将是朝着这个方向迈出的重要一步。

答案 1 :(得分:5)

在Haskell-prime列表上有一个recentish discussion,我认为从那里发生的事情是,为了实现等级变更,需要先实施JónFairbairn的提案,这样才能修复@ camccan列表中非常非常重要的第1点:类型类可以为其超类定义提供默认实现。我不知道该提案的任何实施,甚至是中途的正式规范。

键入类同义词修复点#2,上下文膨胀。请注意,您可以这样做,前提是您使用UndecidableInstances(并且每次推断类型时让GHC扩展同义词......)

对于#4,对#1和#2进行了不错的修复解决了大多数实际问题。如果它不仅仅是粒度问题(答案是同义词,包括为整个类型同义词编写实例),而且可以选择多个可能的超类,那么事情变得更加毛茸茸,我认为当涉及{{3 }}。 的解决方案(替代子类?)在此过程中有很大的机会解决#3。

但是,无论如何,我认为努力是值得的,因为对Haskell进行这些更改(不仅仅是对层次结构)肯定会使Haskell和Haskell代码更加灵活,从而在nay-sayer目前的论点。

答案 2 :(得分:2)

  1. 我反对代理存在,而且我也不能赞成与Applicative-Functor-Monad等级相关的提案。几年前,我曾在数学上sound前奏曲中做过嘀咕。

  2. 类群体层次结构的一个障碍在一开始就出现了幺半群。例如,整数形成加法和乘法幺半群。 Coq通过多重继承来解决这个问题。

    使用建构性数学证明系统建立数学层次结构的一个巨大优势是我们可以通过Curry-Howard同构从证明中提取程序。对于那些对程序正确性和自动验证感兴趣的人来说,在Haskell类型类和Coq等证明验证工具之间进行直接翻译是非常好的。

    我目前使用 hmatrix 包和朋友。不幸的是,我不认为它与当前的数字前奏在hackage上运行良好。理想情况下,要在通用代码中使用优化的BLAS和LAPACK库,只需要实现数字前奏中指定的类型类接口。

答案 3 :(得分:1)

  1. 一些身份不明的人(通过Vivian McPhail行事)有proposed a reform这个领域的前奏,并通过陈述“标准阶级等级是Haskell的历史发展的结果而开启他们的提议,而不是比逻辑“。无论这是否属实,我都不能说。

  2. 上述提案包含支持向后兼容性的措施,但似乎无论如何都不是完美的。

  3. 有一个简短但光荣的尝试来创造The Other Prelude以整理一些混乱。