【问题标题】:Alternative implementations of Haskell's standard library type classesHaskell 标准库类型类的替代实现
【发布时间】:2011-08-09 11:19:45
【问题描述】:

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

  1. 对于类型类依赖树的方式是否存在社区感知的“缺陷”,或者这只是历史上事情的结果?

  2. 在多大程度上对此进行更改会破坏现有代码?

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

【问题讨论】:

  • 这里有一个更大的问题。我们怎么知道我们是正确的这个时间?如果我们发现我们错了,我们是否必须再次经历向后兼容性破坏的痛苦?有关这个更大问题的建议解决方案,请参阅“类型类同义词”。
  • @luqui 你(或其他任何人,就此而言)是否有任何关于类型类同义词进入 GHC 的机会的信息?我可以找到关于(类似的)它们的第一次讨论可以追溯到 1995 年(!),但从那时起并没有发生太多事情。这会成为一个合理的 Google Summer of Code 项目吗?

标签: haskell typeclass standard-library


【解决方案1】:

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

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

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

整体依赖:类型类及其超类的层次结构可以添加,但不能更改或替换。如果一段代码觉得需要替换它自己版本的某个通用类型类——例如,使用something like this 替换Monad——层次结构在此时被切断;必须在某种程度上手动提供与使用Monad 的其他定义的代码的兼容性,并且必须重新实现或翻译任何基于其他定义构建的类型类,即使仅依赖于两个定义共享的行为的子集。

没有明确正确的层次结构:正如上面所暗示的,在类的粒度方面需要做出选择。例如,Pointed 真的需要存在吗,还是仅仅Applicative 就足够了?这里确实没有普遍理想的答案,也不应该有。

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

【讨论】:

  • 哇。从来没想过这些问题。很好的答案。谢谢。
【解决方案2】:

在 Haskell-prime 列表上有一个 recentish discussion 关于这个,我认为从那里发生的事情是为了发生层次结构的变化,需要首先实施 Jón Fairbairn 的提议,这解决了非常, @camccan 列表中非常重要的第 1 点:类型类可以为其超类定义提供默认实现。我不知道该提案的任何实现,甚至是中途正式规范。

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

至于#4,对#1 和#2 进行适当的修复可以解决大部分实际问题。如果这不仅仅是一个粒度问题(答案是同义词,包括为整个类型类同义词编写实例),事情会变得更加棘手,但是可以选择多个可能的超类,我认为这会出现在 a mathematical Num-hierarchy . 那个(替代子类?)的解决方案很有可能一路解决#3。

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

【讨论】:

    【解决方案3】:
    1. 我反对替代存在,并且我不能将与 Applicative-Functor-Monad 层次结构相关的提案归功于我。几年前,我曾抱怨需要数学上的 sound Prelude。

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

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

      我目前使用 hmatrix 包和朋友。不幸的是,我认为它不能很好地与当前关于 hackage 的 Numeric Prelude 配合使用。理想情况下,要在通用代码中使用优化的 BLAS 和 LAPACK 库,只需实现 Numeric Prelude 中指定的类型类接口。

    【讨论】:

      【解决方案4】:
      1. 一些身份不明的人(通过 Vivian McPhail 扮演)拥有proposed a reform 的前奏区,并通过声明“标准类层次结构是 Haskell 历史发展的结果,而不是逻辑的结果来打开他们的提案”。这到底是真是假,我不能说。

      2. 上面的提议包括支持向后兼容的措施,但它似乎无论如何都不完美。

      3. 创建The Other Prelude 以收拾一些乱七八糟的东西。

      【讨论】:

        猜你喜欢
        • 2015-09-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多