При попытке сортировать массив вариантов 1d (здесь под «вариантом» я имею в виду все типы Excel, например, bool, double (и date), string, различные ошибки ...) с помощью следующей функции:
[<ExcelFunction(Category="test", Description="sort variants.")>]
let sort_variant ([<ExcelArgument(Description= "Array to sort.")>] arr : obj[]): obj[] =
arr
|> Array.sort
Я получаю следующую ошибку: Error FS0001 The type 'obj' does not support the 'comparison' constraint. For example, it does not support the 'System.IComparable' interface
, возможно, это означает, что нет универсальной функции упорядочения, доступной для всех типов obj.
Но в Excel есть естественная функция упорядочения, которую я хотел бы эмулировать (по крайней мере, приблизительный). Например, двойной (и даты) <строка <bool <ошибка ... </p>
Мой вопрос : Какой идиоматический способ сортировки массива «вариантов» в F # / Excel-Dna? (Я после функции, которая принимает obj[]
и возвращает obj[]
, ничего больше, не макрос ...)
Мое (временное?) Решение:
Я создал «дискриминационный союз» типа
type XLVariant = D of double | S of string | B of bool | NIL of string
(не совсем уверен, нужен ли NIL, но это не повредило. Также в моем реальном жизненном коде я добавил экземпляр DT of DateTime
, поскольку мне нужно отличать даты от двойных).
let toXLVariant (x : obj) : XLVariant =
match x with
| :? double as d -> D d
| :? string as s -> S s
| :? bool as b -> B b
| _ -> NIL "unknown match"
let ofXLVariant (x : XLVariant) : obj =
match x with
| D d -> box d
| S s -> box s
| B b -> box b
| NIL _ -> box ExcelError.ExcelErrorRef
[<ExcelFunction(Category="test", Description="sort variants.")>]
let sort_variant ([<ExcelArgument(Description= "Array to sort.")>] arr : obj[]): obj[] =
arr
|> Array.map toXLVariant
|> Array.sort
|> Array.map ofXLVariant
(ради простоты я пропустил типы ошибок, но идея та же)