如何使用具有静态解析类型参数的静态扩展方法?

How to use static extension methods with statically resolved type parameters?

我想将静态解析的类型参数与我添加到内置类型的一些扩展方法一起使用,例如 float32int32,因此我尝试了以下操作:

module Foo =
    type System.Single with
        static member Bar x = x + 1.0f

    let inline bar (x : ^a) =
        (^a : (static member Bar : ^a -> ^a) x)

open Foo
[<EntryPoint>]
let main argv =
    System.Console.WriteLine (bar 1.0f) (* Compilation fails here *)
    0

编译器抱怨 The type 'float32' doesn't support the operator 'Bar'。我做错了什么?

静态解析的类型参数不会针对扩展方法进行解析,因此这种特殊方法是不可能的。

我建议仔细考虑这是否是您真正需要做的事情,或者您是否可以用不同的方式表达您试图解决的问题。

如果您确定这就是您想要的,并且您愿意勇敢面对随之而来的恶龙,那么有一个变通方法,它涉及使用一些静态方法创建辅助类型:

type Ext = Ext
    with
        static member Bar (ext : Ext, flt : float) = 1.0 + flt
        static member Bar (ext : Ext, flt : float32) = 1.0f + flt

然后您可以使用静态解析的类型参数定义一个新函数,如下所示:

let inline bar (x : ^a) =
    ((^b or ^a) : (static member Bar : ^b * ^a -> ^a) (Ext, x))

那你可以这样写:

bar 7.0f
val it : float32 = 8.0f

bar 5.0
val it : float = 6.0