Обычно лучше определить собственную функцию сравнения, чем полагаться на встроенное полиморфное сравнение (чем зависит от представления значений во внутренней памяти).Например,
let (<) x y = match x, y with
| Simple n, Simple m -> n < m
| Simple _, _
| Jack, ( Queen | King | Ace )
| Queen, ( King | Ace )
| King, Ace -> true
| _ -> false
Или вы можете проецировать на пару целых чисел
let num = function
| Simple n -> 0, n
| Jack -> 1, 0
| Queen -> 1, 1
| King -> 1, 2
| Ace -> 1, 3
, а затем определить <
как
let (<) x y = num x < num y
, чтобы не затенятьПри полиморфном сравнении может оказаться более практичным поместить определение этого пользовательского оператора (<)
в подмодуль, например Infix
, а затем использовать его с локальным открытым синтаксисом: Infix.( x < y )
.
Возвращениена ваш первоначальный вопрос функция полиморфного сравнения считает, что конструкторы вариантов с аргументами больше, чем конструкторы без аргументов.Другими словами, если вы определите
type t = A | B of int | C | D of int
, порядок конструктора будет A < C < B < D
.Примечательно, что это определение дает обычный лексикографический порядок применительно к списку.Действительно, списки по существу определяются как
type 'a list =
| []
| (::) of 'a * 'a list
Тогда, порядок [] < (::)
подразумевает, что для любых элементов x
и списка q
: [] < a :: q