F# F中带整数值的判别并集#

F# F中带整数值的判别并集#,f#,f#-3.0,F#,F# 3.0,我正在尝试编写一个F#类型,它将具有以下签名: type Foo = (Distance * Event * Course) 这样您就可以创建一个如下的Foo: let bar = (25, Freestyle, LCM) 现在后两部分(事件和过程)很简单——我确信距离也是,我只是还不知道——我只是使用了一个歧视性的结合 假设距离的唯一有效值是[25;50;100],那么构造距离类型的最佳方法是什么 您可以使用.NET枚举: type Distance = TwentyFive=25 | 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.ween
您可以使用.NET枚举:

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

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

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

@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 -> ...

我假设目标是能够轻松访问真实的整数值,但仅限于一定数量的情况

@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 -> ...

类型距离=二十五|五十|百
类型距离=二十五|五十|百
对于数字距离,可能值得考虑使用测量单位而不是整数的浮点。我删除了我的答案,并将其替换为此注释,因为这已经晚了几秒钟,并且与此答案的第一个代码块几乎没有什么不同,只是它使用了Microsoft.FSharp.Data.UnitSystems.SI.UnitSymbols中带有米注释的浮点数。不能保证单位是米,它们可能是码。课程成员决定度量单位。我并不想简单地访问整数值,尽管这很有帮助。为了与域中无处不在的语言保持同步,事件将是“25 Free LCM”,其中“LCM”表示“长航程米”,因此我认为类型构造函数需要接受整数值,而不是“二十五”“。这有帮助吗?度量单位可以是通用的,因此它们在这里仍然可能有用。如果您希望键入system以在编译时强制执行有效距离集,则需要使用union,如建议的那样。否则,您需要定义一个将数字作为构造函数参数的类,并在运行时对其进行验证。对于数字距离,可能值得考虑使用度量单位而不是整数进行浮点运算。我删除了我的答案,并将其替换为此注释,因为这已经晚了几秒钟,并且与此答案的第一个代码块几乎没有什么不同,只是它使用了Microsoft.FSharp.Data.UnitSystems.SI.UnitSymbols中带有米注释的浮点数。不能保证单位是米,它们可能是码。课程成员决定度量单位。我并不想简单地访问整数值,尽管这很有帮助。为了与域中无处不在的语言保持同步,事件将是“25 Free LCM”,其中“LCM”表示“长航程米”,因此我认为类型构造函数需要接受整数值,而不是“二十五”“。这有帮助吗?度量单位可以是通用的,因此它们在这里仍然可能有用。如果您希望键入system以在编译时强制执行有效距离集,则需要使用union,如建议的那样。否则,您需要定义一个类,该类将数字作为构造函数参数,并在运行时对其进行验证。