F#显式成员约束:无法泛化类型变量^T,因为它将超出其作用域

F#显式成员约束:无法泛化类型变量^T,因为它将超出其作用域,f#,generics,F#,Generics,我正试图在F#中使用。文档中说“F#支持公共语言运行库支持的完整约束集”,但如果我真的用这样一个显式约束编译一个类,比如下面,我会得到一个奇怪的错误 type MyType<'T when ^T: (static member ( + ) : ^T * ^T -> ^T)> = member this.F a b = a + b type MyTypeF#规格: ^ident形式的一种类型是 静态解析变量类型。A. 新类型推断变量为 创建并添加到类型中 推理环境(见§

我正试图在F#中使用。文档中说“F#支持公共语言运行库支持的完整约束集”,但如果我真的用这样一个显式约束编译一个类,比如下面,我会得到一个奇怪的错误

type MyType<'T when ^T: (static member ( + ) : ^T * ^T -> ^T)> =
    member this.F a b = a + b
type MyTypeF#规格:

^ident形式的一种类型是 静态解析变量类型。A. 新类型推断变量为 创建并添加到类型中 推理环境(见§14.6)。 此类型变量使用 属性,指示它可能不可用 广义内联除外 定义(见§14.7),同样 与之匹配的任何类型变量 通过一个类型推断方程等价 同样地,也不可能是广义的


成员约束需要静态解析的类型参数。但是类型上不允许使用静态解析的类型参数(如您的示例中所示),仅限于内联函数和内联方法

潜在的问题可能是类型作为一个整体不能内联

另见:

如果使用这样的内联成员:

type MyType() =
    member inline this.F a b = a + b

a和b的类型将自动被正确约束。

您需要将成员标记为内联(如果您想强制参数的类型为
^T
,则需要添加类型注释):


正如其他人所指出的,很少需要手工写出显式成员约束,因为它们通常是推断出来的。此外,在这种情况下,没有理由将约束放在类型而不是方法上,并且由静态解析的类型变量参数化类型也不是惯用方法。

几乎不需要显式指定成员约束。编译器会为您推断它(比如在wmeyer的示例中),关键思想是明确的成员约束是编译器的一个功能,而不是运行时。文档是正确的:F#支持所有CLR约束,但编译器支持更多。
type MyType<'T when ^T: (static member ( + ) : ^T * ^T -> ^T)>() =   
    member inline this.F (a:^T) (b:^T)  = a + b
MyType().F 1 2