F # - О параметрах, передаваемых в методы C # - они кортежи или что?

Я много раз читал, что

Сборки, сгенерированные из F # или любого другого языка .NET (почти) неразличимы.

Затем я экспериментировал с F # и C # взаимодействием на .NET 4 (бета 2). Я создал новое решение и проект на C # со следующим классом:

public class MyClass {
    public static int Add(int a, int b) { return a + b; }
}

Затем в проекте F # после ссылки на проект C # я попытался:

MyClsas.Add(4, 5) |> printfn "%d" // prints 9 (no kidding!)

Все идет нормально. Затем мне пришло в голову другое предложение, которое я читал много раз (возможно, в разных книгах):

При передаче аргументов в функции из других библиотек .NET вы используете синтаксис, такой как «.MethodName (parm1, parm2)», то есть параметры передаются как кортеж.

Добавьте это к тому, что я когда-то читал здесь на SO (но не смог найти его для ссылки), на вопрос, где OP пытался создать подобное использование[ 4, 5, 6 ] (когда он имел в виду[4; 5; 6]):

«Запятая - это оператор создания кортежа, для всего остального используйте точку с запятой».

Затем я изменил свой класс следующим образом:

public class MyClass {
    public static int Add(int a, int b) { return a + b; }
    public static int Add(Tuple<int, int> a) { return a.Item1; }
}

Теперь я попытался использовать его на F #:

MyClass.Add(4, 5) |> printf "%d" // prints ... (keep reading!)

Итак, сложив три цитаты выше, можно сделать вывод, что:

F # создаст кортеж, когда увидит(4, 5)Тогда это вызовет перегрузкуAdd(Tuple<int, int>)Так будет печатать 4

К моему удивлению,напечатано 9, Разве это не интересно?

Что на самом деле здесь происходит? Приведенные выше цитаты и это практические наблюдения, похоже, противоречат друг другу. Можете ли вы обосновать «рассуждения» F # и, если возможно, указать на некоторые документы MSDN?

Спасибо!

РЕДАКТИРОВАТЬ

(чтобы добавить больше информации (из ответа Блинди))

Если вы делаете:

MyClass.Add((4, 5)) |> printfn "%d" // prints 9

F # вызываетAdd(Tuple<int, int>) перегрузки.

Однако, если вы создадите другой проект F # (таким образом, другую сборку) с этим:

namespace MyFSharpNamespace
type MyFShapClass = class
    static member Add x y = x + y
    end

Вы можете использовать его на C #, как это

public static void Main(string[] args) {
    MyFSharpNamespace.MyFSharpClass.Add(4, 5);
}

Все идет нормально. Теперь, когда вы пытаетесь использовать его из F # (из другого проекта, другой сборки), вы должны сделать:

MyFSharpNamespace.MyFSharpClass.Add 4 5 |> printfn "%d"

Если вы передаете аргументы как(4, 5) F # не будет компилироваться, потому чтоAdd являетсяint -> int -> int, и нет(int * int) -> int.

Что случилось?!?

Ответы на вопрос(4)

Ваш ответ на вопрос