涉及静态类型转换的f#方法约束的泛型类型

时间:2014-03-03 10:42:09

标签: f#

我正在尝试在FSharp中创建一个函数,它将获取接口类型的参数和派生类型的参数,它将这两个参数作为该接口的实现传递:

简化示例:

type IFoo =
    abstract member Compare : IFoo -> bool

type Foo =
    interface IFoo with
        member this.Compare _ = false

let doCompare (a : IFoo) (b : IFoo) = a.Compare(b)

let comp  (x : IFoo) (y : #IFoo) = doCompare x (y :> IFoo)
let comp2 (x : 'T)   (y : #'T)   = doCompare x (y :> 'T)

我在通用版本上遇到以下两个错误(此处为comp2):

参数:

This construct causes code to be less generic than indicated by its type annotations. 
The type variable implied by the use of a '#', '_' or other type annotation at or near '...' 
has been constrained to be type ''T'.

关于演员:

The static coercion from type 'T to 'T involves an indeterminate type based on information prior to this program point. 
Static coercions are not allowed on some types. Further type annotations are needed.

我有没有办法解决这个问题,除了使用'T'U创建签名并通过对象进行投射显然不安全?

此代码(连同显示此问题的原始代码 - 用于将NSubstitute包装在测试夹具中)可在tryfsharp上找到

1 个答案:

答案 0 :(得分:5)

#是子类型约束的语法糖,即。 comp2相当于:

let comp2<'T, 'U when 'U :> 'T> (x:'T) (y:'U) = doCompare x (y :> 'T)

不幸的是,类型系统不支持'U :> 'T部分(您不能将类型约束为类型变量的子类型),因此这是不可能的。