将歧视的联合案例与<和>在F#中

时间:2014-08-14 20:36:51

标签: f# comparison-operators discriminated-union

我正在学习F#,我正在建立一套快速的功能,比较两个扑克手并确定获胜者。

我让这个有区别的联盟代表了扑克手的类别:

type Category =
    | HighCard
    | OnePair
    | TwoPair
    | ThreeOfAKind
    | Straight
    | Flush
    | FullHouse
    | FourOfAKind
    | StraightFlush

我使用此代码来比较类别,以确定一只手是否优于另一只手:

if playerCategory > houseCategory then Win
elif playerCategory < houseCategory then Loss
// ... More code to handle cases within the same category

因此,例如,表达式:

let playerCategory = FullHouse
let houseCategory = HighCard
if playerCategory > houseCategory then Win
elif playerCategory < houseCategory then Loss
// ... Other code

将具有值Win

然而,我不明白&lt;和&gt;运营商可以在这里工作。 (最初我有一个函数将每个案例映射到一个数值,但我意识到这没有必要。)如果我重新排列案例的顺序然后逻辑中断,所以我假设每个案例都分配了一些默认值对应于其类型内的顺序?

但我肯定会更欣赏一点......

2 个答案:

答案 0 :(得分:5)

这在说明书中描述:

  

默认情况下,记录,联合和结构类型定义被调用   结构类型隐式包含编译器生成的声明   用于结构平等,散列和比较。这些含蓄   声明由结构平等和以下内容组成   散列

8.15.4生成的CompareTo实现的行为

  

如果T是联合类型,则调用Microsoft.FSharp.Core.Operators.compare   首先在两个值的union例子的索引上,然后再打开   每个对应的字段对x和y用于所携带的数据   工会案件。返回第一个非零结果。

答案 1 :(得分:3)

除了Lee所说的,还有规范

8.5.4从其他CLI语言使用的联合类型的编译表格

  

编译的联合类型U具有:

...

  

每个案例C的一个CLI实例属性 U.Tag 。此属性获取或计算与案例对应的整数标记。

编译器生成的CompareTo方法使用这些属性的支持字段来确定 8.15.4 中规定的索引。这可以通过IlSpy证明:

int tag = this._tag;
int tag2 = category._tag;
if (tag != tag2)
{
    return tag - tag2;
}
if (this.Tag != 0)
{
    return 0;
}