简而言之,我的问题是:
在需要 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 无法获得额外的信息。
似乎以下评论的一种解决方法正在调用
Tuple<_,_> (1,2) ;;
甚至
box (1, 2) :?> IComparable ;;