Это не ответ, поскольку он только демонстрирует тщетность попытки обойти систему типа F # для кортежей.Но технически действительно возможно объединить кортежи разной длины с универсальной функцией, которая могла бы использовать свои аргументы безопасным для типов способом;увы, он будет иметь неопределенный тип возвращаемого значения, требующий аннотации.Это достигается за счет использования двух функций, которые по праву не имеют заметного значения в функциональном программировании:
Есть несколько других ограничений: мы не можем закодировать 1-кортеж, такая перегрузка не может быть однозначноразрешен, поскольку он может обозначать n-кортеж по очереди.По аналогичной причине исключается использование двух кортежей разной длины в качестве прямого аргумента для статических членов.
type X = X with
static member ($) (_ : X, (a, b)) = [|box a; box b|]
static member ($) (_ : X, (a, b, c)) = [|box a; box b; box c|]
let inline t2a x = X $ x
open Microsoft.FSharp.Reflection
let a2t arg : 'r =
FSharpValue.MakeTuple(arg, typeof<'r>) :?> 'r
let inline (@@) a b =
Array.append (t2a a) (t2a b) |> a2t
let (t : int * char * int64 * string) = (1, 'b') @@ (3L, "d")
// val t : int * char * int64 * string = (1, 'b', 3L, "d")
let (u : int * int * int * int * int) = (1, 2, 3) @@ (4, 5)
// val u : int * int * int * int * int = (1, 2, 3, 4, 5)
Учитывая вышеизложенное, конкатенация 4-кортежа с 2-кортежем приведет к компиляцииошибка.
let (v : int * int * int * int * int * int) = (1, 2, 3, 4) @@ (5, 6)
// error FS0001: No overloads match for method 'op_Dollar'.