如何测试Haskell对象以进行参考平等?

发布于 01-17 20:19 字数 329 浏览 3 评论 0 原文

在 Haskell 中,相等测试通常使用来自 Eq 类的 == 来执行。该函数(在大多数情况下)是在纯 Haskell 术语下定义的,因此它遵循将其递归应用于大数据结构的所有后果。因此,看似微不足道的比较可能会花费大量时间。来吧,这应该是即时的(关于懒惰的提醒):

ghci> let x = [1..100000000] in x == x
True
(2.81 secs, 14,400,130,800 bytes)

为什么 Haskell 在这里不使用引用比较?如果我真的愿意的话,Haskell 是否允许我这样做?

In Haskell, equality test is normally performed using == coming the Eq class. This function is (in most cases) defined under pure Haskell terms, so it follows all consequences of applying it recursively to big data structures. Therefore, a seemingly trivial comparison can take significant amount of time. Come on, this should be instant (reminder about laziness):

ghci> let x = [1..100000000] in x == x
True
(2.81 secs, 14,400,130,800 bytes)

Why doesn't Haskell use comparison by reference here? Does Haskell even allow me to do so if I really want to?

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

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

发布评论

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

评论(2

甜嗑 2025-01-24 20:19:13

简短的回答:不,这在 Haskell 中是不可能的,并且有很好的理由。引用相等是语言设计的基本部分,保留它使 Haskell 与语言设计领域中的许多其他语言不同。

稍微长一点的答案:这是一个经过充分研究的主题,通常被称为可观察共享,至少可以追溯到 2000 年代初:

  • Claessen 和 Sands 解释了一些案例,其中的案例 可观察共享很有用,以及如何将其合并到语言中。这是一篇非常容易阅读的论文,它详细解释了这个问题并提出了非保守的扩展。有助于理解基本问题。

  • Gill 对这个问题的解决方案是一种在实践中使用的非常可行的方法,称为 类型安全的可观察共享。这里的想法是,您可以在纯代码中创建相等性,但只能在单子 IO 上下文中观察它们;它保留了引用平等。它没有假阴性,假阳性也很少。 hackage 上也有这个想法的实现,您可以轻松使用。

长话短说:不,你不能在 Haskell 中进行引用相等、指针相等或直接观察共享,这是有充分理由的。这个问题已经得到了很好的研究和理解,并且在 Haskell 生态系统中有一些实用的解决方案可以在不破坏引用透明度的情况下解决这个问题。

Short answer: No this isn't possible in Haskell, and for very good reasons. Referential equality is a fundamental part of the language design, and preserving it makes Haskell distinct from many other languages in the language design space.

A slightly longer answer: This is a well-studied topic, typically referred to as observable sharing, dating back to at least early 2000s:

  • Claessen and Sands explain cases in which cases Observable Sharing is useful and how it can be incorporated into the language. This is a very easy to read paper which explains the issue in detail and suggests a non-conservative extension. Good for understanding the basic problems.

  • Gill's solution to this problem is a very viable approach that is used in practice, called type-safe observable sharing. The idea here is that you can create equalities in pure code, but you can only observe them in the monadic IO context; which preserves referential equality. It has no false negatives, and very few false positives. There is also an implementation of this idea on hackage that you can readily use.

Long story short: No, you cannot do referential-equality, or pointer-equality, or directly observe sharing in Haskell for very good reasons. The problem is well studied and understood, and there are practical solutions to address the issue in the Haskell ecosystem without breaking referential transparency.

一直在等你来 2025-01-24 20:19:13

如果您正在寻找比较引用以实现更快的相等计算的替代方法,请尝试 "="">System.Mem.StableName。
两个对象的 StableName 相等可以保证这两个对象实际上是同一个对象。但这种不等式并不意味着什么,因为对象可以被运行时系统复制和移动。

If you search for an alternative to comparing references for faster equality calculation, try System.Mem.StableName.
The equality of the StableNames of two objects guarantee that both objects are actually the same object. But the inequality does not imply anything, because objects can be duplicated and moved around by the runtime system.

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