首页 文章

了解F#内联和静态解析的类型参数:F#cast示例

提问于
浏览
4

具有静态解析通用参数的F#内联函数似乎与C的模板类似 . 但是,与C不同,您需要指定约束 - 这是如何工作的?

例如,我正在尝试实现向上转换功能,但这不起作用:

let inline myUpcast< ^a, ^b  when ^a :> ^b  > (x: ^a) :  ^b =  x

错误消息为:错误FS0698:无效约束:用于约束的类型是密封的,这意味着约束只能通过最多一个解决方案来满足 .

我实际上正在尝试编写一个函数,当底层类型可以被转换时(在解决方案中缺乏协方差)会强制转换序列,但是以下方法也不能正常工作:

let inline upcastseq (xs: seq< ^a >) : seq< ^b > when ^a :> ^b = xs :?> seq< ^b >

导致以下警告:警告FS0064:此构造导致代码不像类型注释所指示的那样通用 . 类型变量'a已被约束为类型'^ b' . 正如可能预期的那样,实际使用该功能并不像预期的那样有效 .

所以,我正在寻找一个函数,如果用于以协变无效的方式转换序列(因此通用参数限制),将导致类型检查错误 - 这样的事情可能吗?

更一般地说,与C的模板相比,静态解析类型参数的局限性是什么?

1 回答

  • 4

    这是不可能的,但它与静态成员约束无关 . 由于同样的原因,使用普通的通用约束同样注定要失败:

    // doesn't work
    let myUpcast<'a, 'b when 'a :> 'b) (x: 'a) : 'b = unbox (box x)
    

    基本上F#不允许涉及两个不同类型参数的类型约束;他们总是被限制在平等 .

    有关更多评论,请参阅我对How to constrain one type parameter by another的回答 .

相关问题