私の問題は、一言で言えば、これです:
IComparable を必要とする C# コンテナーにタプル (または「比較」の制約がある任意の型) を格納するにはどうすればよいですか?
これは機能します:
> let x (y : 'a when 'a : comparison) = y ;;
val x : y:'a -> 'a when 'a : comparison
> x (1,2) ;;
val it : int * int = (1, 2)
私はこれがうまくいくと思っていたでしょう:
> let x (y : IComparable<int>) = y ;;
val x : y:IComparable<int> -> IComparable<int>
> x (1,2) ;;
x (1,2) ;;
---^^^
stdin(28,4): error FS0001: The type ''a * 'b' is not compatible with the type 'IComparable<int>'
そしてこれも:
> let x (y : IComparable) = y ;;
val x : y:IComparable -> IComparable
> x (1,2) ;;
x (1,2) ;;
---^^^
stdin(30,4): error FS0001: The type ''a * 'b' is not compatible with the type 'IComparable'
編集
私は、F# は暗黙的なアップキャストを行わないという議論に従います。ただし、明示的にも:
> (1, 2) :> IComparable ;;
(1, 2) :> IComparable ;;
^^^^^^^^^^^^^^^^^^^^^
stdin(43,1): error FS0193: Type constraint mismatch. The type
int * int
is not compatible with type
IComparable
The type 'int * int' is not compatible with the type 'IComparable'
F# タプルの比較可能性は F# 型システム内で構造的に推論されるため、これは理にかなっていると思います。おそらく、その追加情報は .NET では利用できません。
以下のコメントごとに1つの回避策が呼び出されているようです
Tuple<_,_> (1,2) ;;
あるいは
box (1, 2) :?> IComparable ;;