Sør*_*ois 5 f# compare icomparable compareto discriminated-union
在回答这个问题compare时,我发现了受歧视工会的以下行为。
type T = A | B | C | D
compare A B (* val it : int = -1 *)
compare A C (* val it : int = -2 *)
compare A D (* val it : int = -3 *)
Run Code Online (Sandbox Code Playgroud)
我对此感到惊讶。
我可以compare像这样测量构造函数之间的“距离”吗?
规范说(第 154 页)关于生成的compareTo:
如果 T 是联合类型,则首先对两个值的联合案例的索引调用 Microsoft.FSharp.Core.Operators.compare,然后对联合案例携带的数据的 x 和 y 的每个相应字段对调用。返回第一个非零结果。
由此,我希望compare类型T总是给出其中之一,-1,0,1因为这就是compare数字类型的行为方式。(正确的?)
规范中的引用说生成的比较将首先比较标签(本质上是构造函数的索引),但我不确定这是否为您提供任何有用的信息 - 因为如果联合带有一些值,您将不知道这个数字是构造函数之间的距离,还是包含值的比较结果。例如:
type Tricky() =
interface System.IComparable with
override x.CompareTo(b) = -2
type DU =
| A of Tricky
| B
| C
// Returns -2 because of the distance between constructors
compare (A (Tricky())) C
// Returns -2 because of the comparison on `Tricky` objects
compare (A (Tricky())) (A(Tricky()))
Run Code Online (Sandbox Code Playgroud)
如果您想依靠获取构造函数之间距离的能力,那么使用枚举可能更安全:
type DU =
| A = 1
| B = 2
| C = 3
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用 将值转换为整数来获取距离(int DU.A) - (int DU.C)。