如何测试Haskell对象的引用相等性?

How to test Haskell objects for reference equality?

提问人:radrow 提问时间:3/30/2022 最后编辑:radrow 更新时间:5/13/2023 访问量:278

问:

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

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

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

Haskell 引用 相等

评论

2赞 willeM_ Van Onsem 3/30/2022
不,它使用了一个称为引用透明度的概念,这意味着您看不到将生成输出的表达式与实际输出之间的差异。这很重要,否则它可能会被用作某种后门机制,使功能不纯。
1赞 radrow 3/30/2022
你会提供这样的后门吗?
1赞 Ben 3/30/2022
最主要的是它使评估可观察。如果我有,然后我问,如果意味着指针比较,那么我会得到不同的结果,具体取决于是否已经评估过。如果这是可观察到的,那么我们需要仔细定义何时可以进行评估,这样我们才能确保评估的结果是可预测的。这基本上会迫使我们成为一种命令式语言,将代码作为一系列步骤,而不是一种“永恒”的表达语言。此外,它还排除了许多编译器优化。xs = [1, 2, 3]ys = id xsxs == ys==ysxs == ys
0赞 chepner 3/31/2022
撇开不谈,不要在 GHCi 中计时,因为代码不会像在编译代码中那样优化,而编译代码会真正关心性能。
0赞 Taylor Fausak 4/5/2022
您可能对 reallyUnsafePtrEquality# 和以下其他问题感兴趣:stackoverflow.com/q/9649500stackoverflow.com/q/19355772stackoverflow.com/q/30175974 stackoverflow.com/q/48163259

答:

11赞 alias 3/30/2022 #1

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

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

  • Claessen 和 Sands 解释了 Observable Sharing 在哪些情况下是有用的,以及如何将其整合到语言中。这是一篇非常容易阅读的论文,它详细解释了这个问题,并提出了一个非保守的扩展。有利于理解基本问题。

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

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

0赞 comonad 5/13/2023 #2

如果搜索比较引用的替代方法以加快相等计算速度,请尝试 System.Mem.StableName。 两个对象的 StableName 相等保证两个对象实际上是同一个对象。但不等式并不意味着什么,因为对象可以被运行时系统复制和移动。