为什么不允许这样做?
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)
具有静态解析类型参数的函数是否需要返回已解析类型的实例?
正如您所注意到的,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().因此,您需要显式提供类型参数,一旦执行,您还必须显式提供约束.