【问题标题】:Disadvantages of Scala type system versus Haskell?Scala 类型系统与 Haskell 的缺点?
【发布时间】:2010-09-11 01:19:00
【问题描述】:

我了解到 Scala 的类型系统因 Java 互操作性而被削弱,因此无法执行与 Haskell 类型系统相同的某些功能。这是真的?是因为类型擦除的弱点,还是我在各方面都错了?这种差异是 Scala 没有类型类的原因吗?

【问题讨论】:

标签: scala haskell type-systems static-typing language-comparisons


【解决方案1】:

最大的区别在于 Scala 没有 Hindley-Milner 全局类型推断,而是使用一种局部类型推断形式,要求您​​指定方法参数的类型以及重载或递归函数的返回类型。

这不是由类型擦除或 JVM 的其他要求驱动的。这里所有可能的困难都可以克服,而且已经过去了,只要考虑一下 Jaskell - http://docs.codehaus.org/display/JASKELL/Home

H-M 推理在面向对象的上下文中不起作用。具体来说,当使用类型多态时(与类型类的临时多态相反)。这对于与其他 Java 库的强互操作以及(在较小程度上)从 JVM 获得最佳优化至关重要。

说 Haskell 或 Scala 具有更强大的类型系统是不正确的,只是它们不同而已。两种语言都在向不同方向推进基于类型的编程的界限,并且每种语言都具有彼此难以复制的独特优势。

【讨论】:

  • 第 16 章演示了 Scala 的数据类型和模式匹配开发 H/M 风格的类型推断系统scala-lang.org/docu/files/ScalaByExample.pdf
  • “H-M 推理在面向对象的上下文中不起作用”。但 F# 确实实现了 H-M 并具有面向对象的一面。
  • @Mauricio:是的,OCaml 是一个更好的反例,因为它推断类类型......
  • Jaskell 在编译时根本不检查类型,它是一种动态语言,副作用无处不在。它一点也不像 Haskell,除了它的语法(尽管在 Jaskell 中比在 Haskel 中更笨拙)。
  • 对于那些遇到这个讨论的人,F#确实在某些情况下需要类型注释:stackoverflow.com/a/2977953/2073130,而 OCaml做同样的事情:stackoverflow.com/a/22533286/2073130
【解决方案2】:

Scala 的类型系统与 Haskell 的不同,尽管 Scala 的概念有时直接受到 Haskell 的优势及其知识渊博的研究人员和专业人士社区的启发。

当然,在最初并非主要用于函数式编程的 VM 上运行会产生与针对该平台的现有语言的一些兼容性问题。 因为大多数关于类型的推理发生在编译时,Java(作为一种语言和作为一个平台)在运行时的限制是没有什么可担心的(除了 Type Erasure,虽然这个 bug 似乎确实使得集成到 Java生态系统更加无缝)。

据我所知,Java 在类型系统级别上的唯一“妥协”是处理原始类型的特殊语法。虽然 Scala 甚至不再允许原始类型,但它接受具有该错误的旧 Java 类文件。 也许你见过像List[_](或更长的等效List[T] forSome { type T })这样的代码。这是与 Java 的兼容特性,但在内部也被视为存在类型,不会削弱类型系统。

Scala 的类型系统确实支持type classes,尽管它比 Haskell 更冗长。我建议阅读这篇论文,它可能会对 Scala 类型系统的相对优势产生不同的印象(第 17 页的表格很好地列出了非常强大的类型系统概念)。

Scala 和 Haskell 的编译器用来推断类型的方法不一定与类型系统的强大相关,尽管它对人们编写代码的方式有一些影响。 拥有强大的类型推断算法可以让编写更抽象的代码变得值得(您可以自行决定这在所有情况下是否都是好事)。

最终,Scala 和 Haskell 的类型系统的驱动力是为用户提供解决问题的最佳工具的愿望,但实现该目标的途径不同。

【讨论】:

  • 存在类型与原始类型并不完全相同。例如,List[] 不被认为是与另一个 List[] 相同的类型
【解决方案3】:

另一个需要考虑的有趣点是 Scala 直接支持经典的 OO 风格。这意味着,存在 subtype 关系(例如 List 是 Seq 的子类)。这使得类型推断更加棘手。除此之外,您可以在 Scala 中混合使用特征,这意味着给定类型可以具有多个超类型关系(这使得它更加棘手)

【讨论】:

    【解决方案4】:

    Scala 没有rank-n types,尽管在某些情况下可能有work around this limitation

    【讨论】:

    • 在相关的说明中,它也不支持不可预测性。
    【解决方案5】:

    我对 Haskell 的经验很少,但我注意到 Scala 类型系统与 Haskell 不同的最明显的一点是类型推断。

    在 Scala 中,没有全局类型推断,您必须明确告知函数参数的类型。

    例如,在 Scala 中你需要这样写:

    def add (x: Int, y: Int) = x + y
    

    而不是

    add x y = x + y
    

    当您需要适用于各种类型的通用版本的 add 函数具有“+”方法时,这可能会导致问题。有一个解决方法,但它会变得更冗长。

    但在实际使用中,我发现 Scala 的类型系统对于日常使用来说已经足够强大了,而我几乎从不将这些变通方法用于泛型,这可能是因为我来自 Java 世界。

    并且显式声明参数类型的限制并不是一件坏事,无论如何你都需要记录它。

    【讨论】:

    • “无论如何都需要记录”——是的。这就是我对类型推断的困扰。这一切似乎都基于错误的信念,即价值在于类型安全,而不是可读性。正如鸭子类型的支持者所指出的那样,在实践中,排序类型系统捕获的类型错误不是问题——至少在静态类型的语言中是这样。当然,从例如的角度来看。由于常量(有效)类型不明确,Javascript 类型安全看起来很有用。但是像例如这样的语言nim(也可能是haskell,idk)设法使打字的lang读起来很像鸭子打字的。具有讽刺意味。
    【解决方案6】:

    它们是图灵可约的吗?

    参见 Oleg Kiselyov 的页面 http://okmij.org/ftp/ ... 可以在 Haskell 的类型系统中实现 lambda 演算。如果 Scala 可以做到这一点,那么在某种意义上,Haskell 的类型系统和 Scala 的类型系统计算相同的类型。问题是:一个比另一个自然吗?一个比另一个优雅吗?

    【讨论】:

      猜你喜欢
      • 2011-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-29
      • 1970-01-01
      • 2011-10-27
      • 1970-01-01
      • 2010-12-21
      相关资源
      最近更新 更多