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

标签 f#

我正在尝试在 FSharp 中创建一个函数,该函数将采用接口(interface)类型的参数和派生类型的参数,并将这两个参数作为该接口(interface)的实现传递:

简化示例:

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 上找到。

最佳答案

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

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

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

关于f# - 涉及静态类型转换的 f# 方法的泛型类型约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22144571/

相关文章:

F# 过于激进的类型推断?

f# - 将函数列表缩减为 bool 值

f# - 在创建中间值时,我应该存储它吗?

arrays - 在 F# 中的数组中创建重复序列的最佳方法是什么?

F# 使用 XML Type Provider 修改 xml

f# - 如何在 fsi 中运行 .fsx

f# - F# Async.Parallel 会加快计算速度吗?

f# - 多元静态类型约束

clojure 就像 F# 中的 cond

F# - 公共(public)文字