Сравнение случаев дискриминационного объединения с <и> в F#
Я изучаю 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
,
Однако я не понимаю, как операторы <и> могут работать здесь. (Изначально у меня была функция, которая отображала каждый случай в числовое значение, но я понял, что в этом нет необходимости.) Если я переставлю порядок случаев, то логика сломается, поэтому я предполагаю, что каждому случаю назначается какое-то значение по умолчанию. соответствует его порядку внутри типа?
Но я бы определенно оценил немного больше понимания...
2 ответа
Это описано в спецификации:
по умолчанию определения типов записей, объединений и структур, называемые структурными типами, неявно включают в себя сгенерированные компилятором объявления для структурного равенства, хэширования и сравнения. Эти неявные объявления состоят в следующем для структурного равенства и хеширования
8.15.4 Поведение сгенерированных реализаций CompareTo
Если T является типом объединения, вызовите Microsoft.FSharp.Core.Operators.compare сначала в индексе случаев объединения для двух значений, а затем в каждой соответствующей паре полей x и y для данных, переносимых случаем объединения. Вернуть первый ненулевой результат.
В дополнение к тому, что сказал Ли, есть также в спецификации
8.5.4 Скомпилированная форма Union Type для использования с другими языками CLI
Скомпилированный тип объединения U имеет:
...
Одно свойство экземпляра CLI U.Tag для каждого случая C. Это свойство выбирает или вычисляет целочисленный тег, соответствующий случаю.
Сгенерированный компилятором 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;
}