5

在 F# 中,等式运算符 (=) 通常是外延的,而不是内涵的。那太棒了!不幸的是,在我看来,F# 没有使用指针相等来缩短这些扩展比较。

例如,这段代码:

类型 Z = MT | Z 参考的 NMT

// 创建一个 Z:
让 a = 参考 MT
// 使其指向自身:
一个:= NMT

// 检查它是否等于自身:
printf "a = a: %A\n" (a = a)

... 给我一个很大的分段错误[*],尽管 'a' 和 'a' 都评估为相同的参考。那不是很好。其他函数式语言(例如 PLT Scheme)正确地使用指针比较,在可以使用指针比较确定时返回“真”。

所以:我会接受 F# 的相等运算符不使用捷径这一事实;有什么方法可以执行内涵(基于指针的)相等检查吗?(==) 运算符没有在我的类型上定义,如果有人能告诉我它以某种方式可用,我会很高兴。

或者告诉我,我对这种情况的分析是错误的:我也喜欢这样……

[*] 这可能是 Windows 上的堆栈溢出;Mono 有一些我不太喜欢的东西……

4

1 回答 1

8

我知道有两种选择。标准的 .NET 方法是使用System.Object.ReferenceEquals. F# 中稍微好一点的方法可能是使用LanguagePrimitives.PhysicalEquality基本相同的方法,但仅适用于引用类型(这对于您的目的可能是正确的)并且要求两个参数具有相同的静态类型。如果您想要更好的语法,您还可以根据这些函数中的任何一个定义您选择的自定义运算符。

顺便说一句,在 .NET 上,当我运行您的代码时,我得到一个无限循环但没有堆栈溢出,这可能是由于尾调用优化。

于 2010-04-21T20:21:09.180 回答