在最新的 GHC 中弃用 DatatypeContext: 为什么?

我只是在做一些 Haskell 开发,然后在新版本的 GHC 上重新编译了一些旧代码:

The Glorious Glasgow Haskell Compilation System, version 7.2.1

当我这样做的时候,我收到了下面的错误:

警告:-XDatatypeContext 已被弃用: 它被广泛认为是一个错误的特性,并已从 Haskell 语言中删除。

如果代码格式如下:

data Ord a => MyType a
= ConstructorOne a
| ConstructorTwo a a

我的问题是: 为什么这个特性一开始就被弃用了? 我应该怎么做才能实现相同或类似的功能?

7547 次浏览

一般来说,您仍然需要将 Ord a约束添加到任何使用您的 MyType类型的函数中,因此并不像它看起来那样有用。有关为什么删除它们的更多信息,请参见 http://hackage.haskell.org/trac/haskell-prime/wiki/NoDatatypeContexts

它已经被废弃了,因为它的 曾经是一个错误的功能,并没有实际上 have任何有用的功能!它所做的只是在其他地方强加了一些额外的约束。特别是,当在这种类型上进行模式匹配时,您将被迫添加一个约束,而不是(正如人们最初可能希望的那样)获得对上下文的访问权限,这种访问权限是基于一开始就知道必须可以构造这个值的知识。

“替换”实际上是以另一种方式工作,为你跟踪已知的上下文,是 而是使用 GADT 样式的声明:

data MyType a where
ConstructorOne :: Ord a => a -> MyType a
ConstructorTwo :: Ord a => a -> a -> MyType a

一般来说,广义扩展模式匹配在许多其他方面也更加灵活,但是在这种特殊情况下,会发生的情况是,创造中的一个值需要 Ord约束,这个约束随着该值一起传递,然后构造函数将其拉出。因此,您甚至不需要使用它的函数的上下文,因为您知道,通过期待类型为 MyType a的内容,您将得到一个 Ord a约束。