F# 中具有整数值的可区分联合

Discriminated Union with Integer Values in F#

我正在尝试编写具有以下签名的 F# 类型:

type Foo = (Distance * Event * Course)

这样你就可以像这样创建一个 Foo:

let bar = (25, Freestyle, LCM)

现在后两部分(事件和课程)很容易了——我确定距离也是,我只是还不知道——我只是用了一个可区分的联合。

假设距离的唯一有效值是 [25;50;100],构造距离类型的最佳方法是什么?

您可以使用 .NET 枚举:

type Distance = TwentyFive=25 | Fifty=50 | Hundred=100

对于模式匹配,您必须使用限定名称:Distance.Fifty

我假设目标是轻松访问真实整数值,但将其限制在一定数量的情况下。

@Petr 的建议可以,您只需将枚举值转换为 int。

另一种选择是在 DU 类型的方法中计算值:

type Distance = 
    TwentyFive | Fifty | Hundred
    member this.ToInt() =
        match this with
        | TwentyFive -> 25
        | Fifty -> 50
        | Hundred -> 100

或者,如果您需要更强的语法支持,单大小写活动模式可能会更好:

type Event = Freestyle | Backstroke
type Distance = TwentyFive | Fifty | Hundred
let (|IntDistance|) d =
    match d with
    | TwentyFive -> 25
    | Fifty -> 50
    | Hundred -> 100

let race = (Fifty, Freestyle)

let (IntDistance(dist), evt) = race
printfn "Race info: %d %A" dist evt

match race with
| IntDistance(dist), Freestyle -> ...
| IntDistance(dist), Backstroke -> ...