Haskell类型系统中的问题

Problems in Haskell's Type-System

我遇到了一些答案(在这里是这样)说哈斯克尔有许多"黑暗角落"在它的类型系统,以及一些混乱的洞。有人能详细解释一下吗?

提前谢谢


我想我应该回答这个问题,特别是因为迄今为止有两个人误解了我的话…

关于不终止,所讨论的评论是戏剧性效果的轻微夸张,并指在价值水平上的不终止。这是在将haskell与定理证明者进行比较的背景下进行的,这是对某些人的回答,他们提到类型强制的正确性属性是他们特别欣赏的。从这个意义上说,存在于其他空类型的是一个"缺陷",因为它改变了像A -> B这样的类型的含义,从"给定的A,生成的B"变为"给定的A,或者生成的B,或者使程序崩溃",从正确性证明的角度来看,这显然不太令人满意。

它与几乎所有的日常编程都是完全无关的,也不比任何其他通用语言差,因为,当然,图灵完整性需要不终止的可能性。

我对UndecidableInstances没有任何问题。实际上,在值级别上,它比更让我困扰,因为它只在编译时崩溃GHC,而不是完成的程序。不过,OverlappingInstances是另一回事,而且GHC扩展的临时混乱提供了一些最自然需要依赖类型的东西,这当然被认为是"混乱的"。

但是请记住,我在Haskell抱怨的大部分事情只是一个问题,因为其他的基础非常扎实。与其他静态类型语言中的大多数类型系统相比,它们甚至不够连贯,不足以被称为"错误的",而清理我称为"杂乱"的东西则是一个活跃且持续的研究领域。


实际上,哈斯克尔的类型系统没有问题,也没有杂乱的漏洞。Haskell98可以完全推断类型。它拥有所谓的"主体类型"属性,也就是说,任何给定的表达式最多只能有一个最一般的类型。但是,有一系列的表达式是好的、有用的和有效的,但是在haskell 98下不输入。其中最重要的是排名较高的类型。forall a b. (a -> b) -> a -> b是一个(无趣的)一级类型的例子,也就是说forall只是在外面。forall b. -> (forall a. a -> a) -> b -> b是一个无用但可能的类型的例子,它不是一级的,不能用haskell98表示。更高级别的类型是打破主体类型属性的许多事情之一。

随着对基本haskell98系统添加了越来越多的扩展,开始在编写真正强大的类型(表示不同类型的多态性和不同类型的约束)的能力和具有尽可能多的完全类型推断代码的能力之间进行权衡。在可能的边缘,类型可能变得杂乱和复杂,有时你会碰到一些看起来应该工作但不应该工作的东西。但是在那一点上,你通常正在做所谓的"类型级编程",你的大量应用程序逻辑已经嵌入到类型本身中,并通过一个组合类型类技巧的国家,你已经连接到编译器,本质上,运行类型作为一个程序在编译时。

顺便说一下,我不同意卡曼的观点,即潜在的不终止是类型检查程序中一个混乱的妥协。我认为这是一个非常有用的特性,实际上是在类型级别上实现完整性的先决条件,只有当您明确地要求编译器开始允许许多不可靠的东西时,您才会冒险使用它。


所以你指的是卡曼所说的"哈斯克尔式的系统充满了漏洞,由于不终止和其他混乱的妥协"?我认为他在谈论不可决定的实例扩展,可能还有其他一些。

然后你提到诺曼,我只能假设,他说"哈斯克尔的类型体系是雄心勃勃和强大的,但是它在不断地改进,这意味着历史的结果有一些不一致。"我相信他有想法,但当他看到这个问题时会让他澄清。