short-cutting equality checking in F#?

匆匆过客 提交于 2019-12-07 06:22:46

问题


In F#, the equality operator (=) is generally extensional, rather than intensional. That's great! Unfortunately, it appears to me that F# does not use pointer equality to short-cut these extensional comparisons.

For instance, this code:

type Z = MT | NMT of Z ref

// create a Z:
let a = ref MT
// make it point to itself:
a := NMT a

// check to see whether it's equal to itself:
printf "a = a: %A\n" (a = a)

... gives me a big fat segmentation fault[*], despite the fact that 'a' and 'a' both evaluate to the same reference. That's not so great. Other functional languages (e.g. PLT Scheme) get this right, using pointer comparisons conservatively, to return 'true' when it can be determined using a pointer comparison.

So: I'll accept the fact that F#'s equality operator doesn't use short-cutting; is there some way to perform an intensional (pointer-based) equality check? The (==) operator is not defined on my types, and I'd love it if someone could tell me that it's available somehow.

Or tell me that I'm wrong in my analysis of the situation: I'd love that, too...

[*] That would probably be a stack overflow on Windows; there are things about Mono that I'm not that fond of...


回答1:


There are two options that I'm aware of. The standard .NET approach would be to use System.Object.ReferenceEquals. A slightly better approach in F# might be to use LanguagePrimitives.PhysicalEquality which is basically identical, but only works on reference types (which is probably correct for your purposes) and requires both arguments to have the same static type. You can also define a custom operator of your choice in terms of either of these functions if you'd like nicer syntax.

As an aside, on .NET I get an infinite loop but not a stack overflow when I run your code, presumably due to tail call optimization.



来源:https://stackoverflow.com/questions/2686216/short-cutting-equality-checking-in-f

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!