【问题标题】:short-cutting equality checking in F#?F# 中的快捷相等检查?
【发布时间】:2011-02-10 18:55:09
【问题描述】:

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

例如,这段代码:

类型 Z = MT | Z 参考的 NMT // 创建一个 Z: 让 a = 参考 MT // 使其指向自身: 一个:= NMT // 检查它是否等于自身: printf "a = a: %A\n" (a = a)

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

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

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

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

【问题讨论】:

    标签: f# equality


    【解决方案1】:

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

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

    【讨论】:

    • 谢谢!顺便说一句:是的,这确实在 mono/osx 上转储了核心。在我正在使用的特定单声道/fsharp 组合中,可能没有正确实现尾调用以进行相等性检查。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多