我遇到了一些答案(在SO中),说Haskell在其类型系统中有许多“黑暗角落”,还有一些凌乱的漏洞。有人可以详细说明吗?
提前致谢
答案 0 :(得分:13)
我想我应该回答这个问题,特别是因为到目前为止有两个人误解了我的言论......
关于非终止,有问题的评论是戏剧性效果的轻微夸张,并且指的是值级别的非终止。这是在将Haskell与定理证明器进行比较的背景下,回答那些提到类型强制正确性属性的人,他们特别欣赏这些属性。从这个意义上说,居住在其他空类型中的is是一个“缺陷”,因为它将类似A -> B
的类型的含义从“给定A,产生B”变为“给定A,或者产生a B或崩溃程序“由于显而易见的原因,从正确性证明的角度来看,这有点不太令人满意。
它几乎与所有日常编程完全无关,并且不比任何其他通用语言更糟糕,因为当然,图灵完整性需要不终止的可能性。
我对UndecidableInstances
没有任何问题。实际上,它在价值水平上不到b困扰我,因为它只会在编译时崩溃GHC,而不是完成的程序。 OverlappingInstances
是另一回事,而GHC扩展的特设混搭提供了一些自然需要依赖类型的东西,这当然有点“杂乱”。
但请记住,我在Haskell中抱怨的大多数事情只是一个问题,因为其他非常坚实的基础。其他静态类型语言中的大多数类型系统甚至不够连贯,相比之下被称为“错误”,清理我称之为“杂乱”的东西是一个活跃且持续的研究领域。
答案 1 :(得分:6)
forall a b. (a -> b) -> a -> b
是一个(无趣的)排名类型的例子,也就是说forall
仅在外面。 forall b. -> (forall a. a -> a) -> b -> b
是一个无用但可能的类型的例子,它不是排名第一,不能在Haskell98中表达。排名较高的类型是打破主要类型属性的众多因素之一。
随着人们对基本的Haskell98系统添加越来越多的扩展,开始在编写真正强大的类型的能力之间进行权衡,这些类型表达不同类型的多态性和不同类型的约束以及拥有尽可能多的代码的能力尽可能完全类型推断。在尽可能可能的边缘,类型可能会变得混乱和复杂,偶尔你可能遇到看起来应该工作但却没有的东西。但是在这一点上,你通常会做所谓的“类型级编程”,其中大量的应用程序逻辑已经嵌入到类型本身中,并且通过结合使用类编译技巧将编译器连接到,实际上,在编译时将类型作为程序运行。
顺便说一下,我不同意camccann断言潜在的不确定性在类型检查器中是一个混乱的妥协。我认为这是一个非常有用的功能,实际上是类型级别的完整性的先决条件,如果您明确要求编译器开始允许大量狡猾的东西,您只会冒险。答案 2 :(得分:1)
所以你指的是Camccann说“由于不确定和其他混乱的妥协,Haskell的类型系统充满漏洞”?我认为他正在谈论UndecidableInstances扩展,可能还有其他一些扩展。
然后你提到了Norman,我只能假设,“Haskell的类型系统雄心勃勃,功能强大,但它不断得到改进,这意味着历史会产生一些不一致。”我确信他有一些想法,但当他看到这个问题时会让他澄清。