我读到Scala的类型系统与Java互操作性相克,并且不能像Haskell的类型系统那样执行一些功能。 这是真的吗? 这种弱点是由于类型擦除,还是我完全错了? 这种差异是Scala没有类型类的原因吗?
我读到Scala的类型系统与Java互操作性相克,并且不能像Haskell的类型系统那样执行一些功能。 这是真的吗? 这种弱点是由于类型擦除,还是我完全错了? 这种差异是Scala没有类型类的原因吗?
Scala与Haskell的最大区别在于,Scala没有Hindley-Milner全局类型推断,而是使用一种本地类型推断形式,需要你为方法参数指定类型以及递归函数的返回类型或重载函数的返回类型。
这不是由类型擦除或JVM的其他要求驱动的。所有可能的困难都可以克服,并且已经解决了,只需考虑Jaskell - http://docs.codehaus.org/display/JASKELL/Home
H-M推理在面向对象的上下文中不起作用。具体来说,当使用类型多态性时(而不是类型类的特殊多态性)时,这非常关键,以实现与其他Java库的强交互,以及(在较小程度上)获得最佳的JVM优化。
不太合适地宣称Haskell或Scala拥有更强的类型系统,只能说它们不同。这两种语言正在不同方向推进基于类型的编程的边界,每种语言都具有独特的优势,很难在另一种语言中复制。
Scala的类型系统与Haskell的不同,尽管Scala的概念有时直接受到Haskell的优势和其知识渊博的研究员和专业人士社区的启发。
当然,首先在一个不是针对函数式编程的虚拟机上运行会导致与现有语言针对此平台的兼容性问题。由于大部分关于类型的推理都发生在编译时,Java(作为一种语言和平台)在运行时的限制并不值得担心(除了类型擦除,尽管恰恰这个错误似乎使其与Java生态系统的集成更加无缝)。
据我所知,仅在Java的类型系统层面上进行的"妥协"是一种特殊的语法来处理原始类型。虽然Scala甚至不再允许使用原始类型,但它接受具有该错误的旧Java类文件。
也许你已经看到过像List[_]
(或者更长的等价物List[T] forSome { type T }
)的代码。这是与Java的兼容性特性,但在内部也被视为存在类型,并且不会削弱类型系统。
Scala的类型系统确实支持类型类,尽管以比Haskell更冗长的方式。我建议阅读这篇论文,它可能会产生不同的印象,关于Scala类型系统的相对优势(第17页上的表格是非常强大的类型系统概念的好列表)。
与类型系统的强大无关的是Scala和Haskell编译器用于推断类型的方法,尽管它对人们编写代码的方式有些影响。 拥有强大的类型推断算法可以使编写更抽象的代码变得更有价值(你可以自己决定在所有情况下是否是一件好事)。
最终,Scala和Haskell的类型系统都是由提供用户解决问题的最佳工具的愿望驱动,但它们已经走上了不同的道路。
另一个有趣的观点是,Scala直接支持经典的面向对象风格。这意味着存在子类型关系(例如,List是Seq的子类)。这使得类型推断更加棘手。再加上你可以在Scala中混入特质,这意味着给定类型可以具有多个超类型关系(使它更加棘手)。
我对Haskell只有一点经验,但我发现Scala类型系统与Haskell不同的最明显的事情是类型推断。
在Scala中,没有全局类型推断,你必须明确告诉函数参数的类型。
例如,在Scala中,你需要这样写:
def add (x: Int, y: Int) = x + y
add x y = x + y
他们是否可图灵约简?
请参阅Oleg Kiselyov的页面http://okmij.org/ftp/... 可以在Haskell的类型系统中实现λ演算。如果Scala也可以做到这一点,那么从某种意义上说,Haskell的类型系统和Scala的类型系统计算相同的类型。问题是:哪个更自然?哪个更优雅?