Это открытый вопрос, но мне так и не удалось найти решение, которое меня удовлетворило бы.
Скажем, у меня есть этот алгебраический тип данных:
type t = A of int | B of float | C of string
Теперь предположим, что я хочу написать функцию compare
— потому что я хочу поместить свои значения, например, в Map
— я бы написал это так:
let compare t1 t2 =
match t1, t2 with
| A x, A y -> compare x y
| A _, _ -> -1
| _, A _ -> 1
| B x, B y -> compare x y
| B _, _ -> -1
| _, B _ -> 1
| C x, C y (* or _ *) -> compare x y
Или я мог бы написать это так:
let compare t1 t2 =
match t1, t2 with
| A x, A y -> compare x y
| B y, B x -> compare x y
| C x, C y -> compare x y
| A _, _
| B _, C _ -> -1
| _ -> 1
Если я не ошибаюсь, говоря, что n
- это количество конструкторов, то у первого compare
будет 3 * (n - 1) + 1
случаев, а у второго - n + ((n - 2) * (n - 1)) / 2 + 2
случаев.
Это довольно неудовлетворительно, так как:
n = 3
(наш случай): 7 или 6 случаевn = 4
: 10 или 8 случаевn = 5
: 13 или 13 случаев
Он растет довольно быстро.
Итак, мне интересно, вы делаете это, как я, или вы используете другой метод?
Или, что еще лучше, есть ли возможность сделать что-то вроде
let compare t1 t2 =
match t1, t2 with
| c1 x, c2 y ->
let c = compare c1 c2 in
if c = 0 then compare x y else c
Or,
let compare (c1 x) (c2 y) =
let c = compare c1 c2 in
if c = 0 then compare x y else c
Изменить: добавлено сравнение, если два конструктора равны для сеньора Друпа (от Гуадалупа; -П)
A 1
иA 2
равны. - person Drup   schedule 02.03.2017