Scala类型系统与Haskell相比的缺点?

时间:2010-09-11 01:19:00

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

我已经读过Scala的类型系统因Java互操作性而削弱,因此无法执行与Haskell类型系统相同的功能。这是真的?因为类型擦除是弱点,还是我在各方面都错了?这是不同的Scala没有类型类的原因吗?

6 个答案:

答案 0 :(得分:53)

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

这不是由类型擦除或JVM的其他要求驱动的。这里可能遇到的所有困难都可以解决,而且只考虑Jaskell - http://docs.codehaus.org/display/JASKELL/Home

H-M推理在面向对象的上下文中不起作用。特别是,当使用类型多态时(与类型类的ad-hoc多态性相反)。这对于与其他Java库的强大互操作至关重要,并且(在较小程度上)从JVM获得最佳可能的优化。

说Haskell或Scala有一个更强大的类型系统,只是它们是不同的,这并不是真的有效。两种语言都在不同方向推动基于类型的编程的界限,每种语言都有独特的优势,难以在另一种语言中复制。

答案 1 :(得分:23)

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

当然,首先在不主要用于函数式编程的VM上运行会产生一些与针对此平台的现有语言的兼容性问题。 因为关于类型的大多数推理都是在编译时发生的,所以Java(作为一种语言和一个平台)在运行时的局限性无需担心(除了类型擦除之外,尽管这个错误似乎使得集成到Java中)生态系统更加无缝)。

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

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

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

最后,Scala和Haskell的类型系统是由为用户提供解决问题的最佳工具的愿望驱动的,但是已经采取了不同的途径来实现这一目标。

答案 2 :(得分:13)

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

答案 3 :(得分:10)

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

答案 4 :(得分:8)

我对Haskell只有很少的考虑,但最明显的是我注意到与Haskell不同的Scala类型系统是类型推断。

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

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

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

而不是

add x y = x + y

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

但在实际使用中,我发现Scala的类型系统足够强大,适合日常使用,我几乎从不使用这些解决方法进行通用,也许这是因为我来自Java世界。

而显式声明参数类型的限制并不是一件坏事,你还是需要记录它。

答案 5 :(得分:6)

他们图灵可以减少吗?

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