最新 GHC 中不推荐使用 DatatypeContext:为什么?

发布于 2024-12-05 03:47:57 字数 436 浏览 1 评论 0原文

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

The Glorious Glasgow Haskell Compilation System, version 7.2.1

当我这样做时,我收到以下错误:

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

当您的代码采用以下格式时,就会出现这种情况:

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

我的问题是:为什么这个功能首先被弃用,我应该做什么来实现相同或相似的功能?

I was just doing some Haskell development and I recompiled some old code on a new version of GHC:

The Glorious Glasgow Haskell Compilation System, version 7.2.1

And when I did I received the following error:

Warning: -XDatatypeContexts is deprecated: It was widely considered a misfeature, and has been removed from the Haskell language.

That appears when you have code in the following format:

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

My question is: Why was this feature deprecated in the first place and what am I supposed to do instead to achieve the same or similar functionality?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

厌倦 2024-12-12 03:47:57

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

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

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

一般来说,GADT 在许多其他方面都更加灵活同样,但对于这种特殊情况,创建一个值需要 Ord 约束,然后该约束与该值一起携带,并且构造函数上的模式匹配会拉取它回来了。因此,您甚至不需要使用它的函数的上下文,因为您知道,通过期待 MyType a 类型的内容,您将获得 Ord a与它的约束。

It's deprecated because it was a misfeature, and didn't actually have any useful functionality! All it did was force a bunch of extra constraints in other locations. In particular, when pattern matching on such a type, you'd be forced to add a constraint, rather than (as one might initially hope) get access to a context, based on the knowledge that one must have been available to construct the value in the first place.

The "replacement", which actually works the other way and tracks the known contexts for you, is to use GADT-style declarations instead:

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

GADTs in general are more flexible in many other ways as well, but for this particular case what happens is that creating a value needs the Ord constraint, which is then carried along with the value, and pattern matching on the constructor pulls it back out. So you don't even need the context on the functions using it, because you know that by virtue of expecting something of type MyType a, you'll get an Ord a constraint with it.

若有似无的小暗淡 2024-12-12 03:47:57

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

In general, you still need to add the Ord a constraint to any function which uses your MyType type, and as such isn't as useful as it may seem. For more information about why they were removed, see http://hackage.haskell.org/trac/haskell-prime/wiki/NoDatatypeContexts

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文