类型(单位 - >单位)的函数是否可以在F#中静态解析类型参数?

Dan*_*iel 1 f# inline

为什么不允许这样做?

type Foo() =
    static member Bar() = ()

let inline bar<^a>() = //ERROR: unexpected infix operator in pattern
    (^a : (static member Bar : unit -> unit)())

//Hypothetical usage: let _ = bar<Foo>()
Run Code Online (Sandbox Code Playgroud)

......但是这样可以吗?

type Foo() =
    static member Bar() = new Foo()

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

let x : Foo = bar()
Run Code Online (Sandbox Code Playgroud)

具有静态解析类型参数的函数是否需要返回已解析类型的实例?

kvb*_*kvb 6

正如您所注意到的,F#将字符序列<^视为中缀运算符,因此您需要将它们与空格分开.至于何时需要明确指定约束的问题,我认为规则是当你明确给出一个函数类型参数时,你还需要指定任何必要的约束.否则,如果F#可以推断类型参数和约束,则无需指定它们.

所以你的问题中的这个例子很好:

let inline bar() :^a =
  (^a : (static member Bar : unit -> ^a)())
Run Code Online (Sandbox Code Playgroud)

就像这样:

let inline bar(x : ^a) =
  (^a : (static member Bar : unit -> unit)())
Run Code Online (Sandbox Code Playgroud)

因为有一个泛型类型参数,但你没有明确地将它放在函数上,而F#可以推断出所需的约束.

另一方面,如果您尝试修改其他示例以省略显式泛型参数:

let inline bar() =
  (^a : (static member Bar : unit -> unit)())
Run Code Online (Sandbox Code Playgroud)

你会看到F#不允许这样做,因为它没有办法弄清楚如何^a为任何给定的调用实例化bar().因此,您需要显式提供类型参数,一旦执行,您还必须显式提供约束.