53

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

+1

您可能想要阅读本文。 http://lambda-the-ultimate.org/taxonomy/term/32 – 2010-09-11 01:28:58

+4

我非常肯定Haskell至少有和Scala一样的删除类型,因为这是值得的。 – 2010-09-11 01:47:08

回答

51

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

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

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

说明Haskell或Scala具有更强大的类型系统并非真正有效,只是它们不同。两种语言都在向不同的方向推进基于类型的编程的界限,并且每种语言都有其独特的优势,难以在其他方面重复。

+0

相同的类型。第16章演示Scala的数据类型和模式匹配,开发H/M风格的类型推断系统。http://www.scala -lang.org/docu/files/ScalaByExample.pdf – oluies 2010-09-12 16:38:12

+4

“HM推理在面向对象的上下文中不起作用”。但是F#确实实现了H-M并且具有面向对象的一面。 – 2010-10-31 19:32:00

+10

@Mauricio:是的,OCaml是一个更好的反例,因为它推断出类的类型...... – 2010-11-14 21:46:10

13

另一个需要考虑的问题是Scala直接支持经典的OO风格。也就是说,有子类型关系(例如List是Seq的子类)。这使得类型推断更加棘手。再加上这个事实,你可以在Scala中混合使用特征,这意味着给定类型可以有多个超类型关系(使它更棘手)

8

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

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

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

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

,而不是

add x y = x + y 

,当你需要添加功能的通用版本,与各种类型的工作,这可能会导致问题有“+”方法。有一个解决方法,但它会变得更加冗长。但是在实际使用中,我发现Scala的类型系统对于日常使用来说足够强大,而且我几乎从不使用那些通用的解决方法,也许这是因为我来自Java世界。

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

23

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

当然,在主要用于功能编程的虚拟机上运行的虚拟机会在针对此平台的现有语言中产生一些兼容性问题。 由于大多数关于类型的推理发生在编译时,Java(作为语言和平台)在运行时的局限性没有什么可担心的(除了Type Erasure,尽管这个bug似乎使得集成到Java生态系统更加无缝)。

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

斯卡拉的类型系统确实支持type classes,尽管采用比Haskell更详细的方式。我建议阅读本文,这可能会对Scala的类型系统的相对强弱产生不同的印象(第17页的表格充当了非常强大的类型系统概念的很好列表)。

与类型系统的力量不一定相关的是Scala和Haskell的编译器用来推断类型的方法,尽管它对人们编写代码的方式有一些影响。有一个强大的类型推理算法可以让写出更多抽象代码值得(值得一提的是,如果这在所有情况下都是好事的话,你可以自己决定)。

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

+0

提及该表。 – 2010-09-11 22:12:33

+3

存在类型与原始类型并不完全相同。例如,List [_]不被认为是与另一个List [_] – 2010-09-15 01:59:51

6

他们是图灵还原?

请参阅Oleg Kiselyov的页面http://okmij.org/ftp/ ... 可以在Haskell的类型系统中实现lambda演算。如果Scala能够做到这一点,那么Haskell的类型系统和Scala的类型系统就可以计算出相同的类型。问题是:彼此之间有多自然?彼此之间有多优雅?