8

私の問題は、一言で言えば、これです:

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 ;;
4

2 に答える 2

1

確かに何か変なことが起こっています。FWIW、System.Tuple<_, _>明示的に構築すると機能するため、回避策になる可能性があります。

let x (y : IComparable) = y
let t = (2, 3)

x (Tuple<_,_> t)
于 2013-08-07T06:47:11.023 に答える