为什么不了解此通用成员约束

rob*_*kuz 2 generics f#

给出以下函数定义

let inline add<'X,'Y when 'X : (member Add : 'Y -> unit)> 
    (target:'X) (value:'Y) = target.Add value  
Run Code Online (Sandbox Code Playgroud)

为什么我会收到此错误?

  target.Add v
----^^^^^^^^^^
stdin(64,5): error FS0072: Lookup on object of indeterminate type based on 
information prior to this program point. A type annotation may be needed 
prior to this program point to constrain the type of the object. This may 
allow the lookup to be resolved.
Run Code Online (Sandbox Code Playgroud)

我对这里需要的其他类型注释感到有点困惑.谁能解释一下?

vcs*_*nes 5

我相信这样做的正确方法是:

let inline add (target : ^X when ^X : (member Add : ^Y -> unit)) (value : ^Y) = 
    (^X : (member Add :  ^Y -> unit) target, value)
Run Code Online (Sandbox Code Playgroud)

答案和评论这个回答说明了一下,为什么这句法是必要的.

我们可以在这里看到它:

let l = System.Collections.Generic.List<string>()
add l "Hello"
Run Code Online (Sandbox Code Playgroud)

kvb还指出,鉴于成员约束现在在正文中,不需要在参数中明确定义它,因为编译器可以推断它,所以我们可以稍微清理一下:

let inline add target value = 
    (^X : (member Add : ^Y -> unit) target, value)
Run Code Online (Sandbox Code Playgroud)

  • 这是对的; 请注意,给定函数体中的成员调用表达式,编译器可以推断出参数的类型和约束. (3认同)