【发布时间】:2010-12-21 09:24:33
【问题描述】:
如何向 Haskell 专家解释 Scala 的类型系统? 哪些例子显示了 Scala 的优势?
如何向高级 Scala 实践者解释 Haskell 的类型系统? Haskell 能做哪些 Scala 不能做的事?
【问题讨论】:
标签: scala haskell type-systems
如何向 Haskell 专家解释 Scala 的类型系统? 哪些例子显示了 Scala 的优势?
如何向高级 Scala 实践者解释 Haskell 的类型系统? Haskell 能做哪些 Scala 不能做的事?
【问题讨论】:
标签: scala haskell type-systems
Scala 致 Haskell 程序员:
Scala 是一门严格且不纯粹的语言,具有一流的模块。数据类型被声明为具有细微差别的“类”或“特征”,模块或“对象”是这些类型的值。 Scala 支持采用通用量化类型参数的类型构造函数。对象/类/特征具有由值、可变变量和函数组成的成员(称为“方法”,模块作为名为@987654322@ 的变量隐式传递给该方法)。模块可能有也可以接受参数的类型成员。类型成员是存在量化的,类型参数可以是更高种类的。因为类型可以是一等值的成员,所以 Scala 提供了一种称为 path-dependent types 的依赖类型。
一流的函数也是模块。函数是具有名为apply 的方法的模块。方法不是一流的,但提供了一种语法来将方法包装在一流的函数中。不幸的是,一个模块预先需要它的所有类型参数,因此不允许对部分应用的一流函数进行普遍量化。更一般地说,Scala 完全没有针对 rank 高于 1 的类型的直接机制,但是可以利用在更高种类的类型上参数化的模块来模拟 rank-n 类型。
Scala 允许您声明任何给定类型的隐式值,而不是具有全局范围的类型类。这包括提供隐式转换的函数类型,因此也包括类型扩展。除了隐式转换之外,类型扩展由“扩展”机制提供,它允许您声明模块之间的子类型/超类型关系。这种机制可用于模拟代数数据类型,其中超类型可以视为数据声明左侧的类型,其子类型可以视为右侧的值构造函数。 Scala 使用具有一流模式的虚拟化模式匹配器具有广泛的模式匹配功能。
Scala 支持子类型化,这极大地限制了类型推断。但随着时间的推移,类型推断有所改进。支持更高种类的类型的推断。然而,Scala 缺乏任何有意义的种类系统,因此没有种类推断和种类统一。如果引入了类型变量,除非另有注释,否则它是一种*。某些类型,如Any(所有类型的超类型)和Nothing(每种类型的子类型)在技术上属于所有类型,尽管它们不能应用于类型参数。
对 Scala 程序员的 Haskell:
Haskell 是一种纯粹的函数式语言。这意味着函数根本不允许有任何副作用。例如,Haskell 程序不会像这样打印到屏幕上,而是一个返回 IO[_] 数据类型值的函数,该数据类型描述了 IO 子系统要执行的一系列操作。
Scala 默认是严格的,并为非严格函数参数提供“按名称”注释,而 Haskell 默认情况下是惰性的,使用“按需”语义,并为严格参数提供注释。
Haskell 中的类型推断比 Scala 更完整,具有完全推断。这意味着几乎不需要类型注释。
最近对 GHC 编译器的扩展允许高级类型系统功能在 Scala 中没有等效功能,例如 rank-n 类型、类型族和种类多态性。
在 Haskell 中,模块是类型和函数的集合,但模块不是一流的实体。隐式是由类型类提供的,但是一旦声明它们就是全局范围的,它们不能像在 Scala 中那样显式传递。给定类型的类型类的多个实例通过使用 newtype 包装来消除歧义,而在 Scala 中,这将通过范围限定或显式传递实例来解决。
由于 Haskell 不是“面向对象”,因此没有方法/函数二分法。每个函数都是一流的,每个函数都是默认柯里化的(没有 Function1、Function2 等)。
Haskell 没有子类型机制,但类型类可以有子类关系。
【讨论】:
我认为没有人系统地将 Haskell(以 GHC 的类型系统为例)与 Scalas 进行比较。主要区别在于类型推断的程度,以及对更高级别类型的支持。但对差异的全面处理将是一个可发表的结果。
【讨论】: