あれは何度も読んだ
F# またはその他の .NET 言語から生成されたアセンブリは (ほとんど) 区別できません。
その後、.NET 4 (ベータ 2) で F# と C# の相互運用性を試していました。次のクラスを使用して、新しいソリューションと 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)" のような構文を使用します。つまり、パラメーターはタプルとして渡されます。
OPがlikeを使用して作成しようとしていた質問で、SOでここで読んだことがあります(しかし、リンクすることができませんでした[ 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!)
したがって、上記の 3 つの引用を合計すると、次のように結論付けることができます。
- F# は、表示されるとタプルを作成します。
(4, 5)
- 次に、オーバーロードを呼び出します
Add(Tuple<int, int>)
- したがって、4が出力されます
驚いたことに、それは 9を出力しました。面白くないですか?
ここで実際に何が起こっているのでしょうか? 上記の引用とこの実際の観察は矛盾しているようです。F# の「推論」を正当化し、可能であれば MSDN のドキュメントを参照することはできますか?
ありがとう!
編集
(さらに情報を追加するには(Blindyの回答から))
もしあなたがそうするなら:
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"
引数を as として渡すと、isと not の(4, 5)
ため、F# はコンパイルされません。Add
int -> int -> int
(int * int) -> int
何が起こっている?!?