Дискриминационный союз с целочисленными значениями в F#

Я пытаюсь составить тип F#, который будет иметь следующую подпись:

type Foo = (Distance * Event * Course)

Чтобы вы могли создать Foo следующим образом:

let bar = (25, Freestyle, LCM)

Теперь вторые две части (событие и курс) просты - я уверен, что расстояние тоже, я просто еще не знаю - я просто использую дискриминационный союз.

Допустим, что единственными допустимыми значениями для расстояния являются [25;50;100], каков наилучший способ построения типа расстояния?

2 ответа

Решение

Я предполагаю, что цель состоит в том, чтобы иметь легкий доступ к реальному целочисленному значению, но ограничить его только определенным числом случаев.

Предложение @Petr будет работать нормально, вы просто конвертируете значение enum в 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 -> ...

Вы можете использовать.NET перечисления:

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

Для сопоставления с образцом вы должны использовать полное имя: Distance.Fifty

Другие вопросы по тегам