Этот пост относится к предыдущему .
Я считаю, что F # хранит где-то метод, позволяющий сравнивать массивы одного типа, при условии, что элементы массивов сопоставимыми. Причина, по которой я так считаю: тип Set требует, чтобы его элементы были сопоставимы, а Set принимает массивы сопоставимых типов (он даже упорядочивает их элементы при создании экземпляра, что позволяет нам угадать функцию сравнения, которую он использует для массивов). Несколько примеров:
let s1 = [| [| 10; 20 |]; [| 10; 19 |]; [| 10; 19; 100 |]; [| 10; 20; -100 |] |] |> Set.ofArray;;
возвращает
val s1 : Set<int []> = set [[|10; 19|]; [|10; 20|]; [|10; 19; 100|]; [|10; 20; -100|]]
аналогично,
let s2 = [| [| ("b", 1); ("a", 2) |]; [| ("z", 1) |]; [| ("a", 0); ("a", 0); ("a", 0) |]; [| ("b", 1); ("a", 3) |] |] |> Set.ofArray;;
возвращает
val s2 : Set<(string * int) []> = set [[|("z", 1)|]; [|("b", 1); ("a", 2)|]; [|("b", 1); ("a", 3)|]; [|("a", 0); ("a", 0); ("a", 0)|]]
(сравнение выглядит так: Сравнение элементов слева направо, если два массива имеют одинаковую длину, или arr1> arr2, если arr1.Length> arr2.Length)
Последний, более сложный, пример:
type Foo = Z of int | A of int
let s3 = [| [| Z 1; A 1|]; [| A 100 |]; [| Z 1; Z 20|]; [| Z 0; Z 0; Z 0 |]; [| Z 1; Z 10|] |] |> Set.ofArray;;
возвращает
val s3 : Set<Foo []> = set [[|A 100|]; [|Z 1; Z 10|]; [|Z 1; Z 20|]; [|Z 1; A 1|]; [|Z 0; Z 0; Z 0|]]`
Однако последний пример не работает, поскольку объекты несопоставимы:
let s0 = [| [| box 10; box 20 |]; [| box 10; box 19 |] |] |> Set.ofArray;;
возвращает
stdin(52,62): error FS0001: The type 'obj' does not support the 'comparison' constraint. For example, it does not support the 'System.IComparable' interface`
Так что я надеюсь, что приведенное выше показывает этот Set знает, как сравнивать массивы (при условии, что тип их элементов сопоставим).
К сожалению, я не могу получить доступ к методу сравнения двух массивов напрямую:
let x1 : int[] = [| 1 |]
let x2 : int[] = [| 2 |]
let c12 = x1.CompareTo(x2);;
Дает следующее сообщение об ошибке:
let c12 = x1.CompareTo(x2);;
-------------^^^^^^^^^
stdin(3,14): error FS0039: The field, constructor or member 'CompareTo' is not defined.
Мой вопрос: как получить доступ к методу CompareTo, связанному с объектом массива? ... Если возможно, через сигнатуру функции arrcompare : arr1:obj -> arr2:obj -> int
или arrcompare : arr1:obj -> arr2:obj -> int option
(используя option
для случаев, когда 2 аргумента не являются массивами или не являются массивами одного типа).