繁体   English   中英

F#显式成员约束:无法广义化类型变量^ T,因为它将逃避其范围

[英]F# explicit member constraints: The type variable ^T could not be generalized because it would escape its scope

我正在尝试在F#中使用显式成员约束 文档说“ F#支持公共语言运行时支持的完整约束集”,但是如果我实际上用这样的显式约束(例如以下内容)编译一个类,则会出现非常奇怪的错误。

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

报告

错误FS0670:此代码不够通用。 当^ T:(静态成员(+):^ T * ^ T-> ^ T)时,类型变量^ T不能被泛化,因为它将逃避其范围。

并在定义member this.F的位置报告。 这是什么意思? 相关范围是什么?

该语言支持多种方法来执行此类工作。 可以在StackOverflow上找到一个不错的探索,但是我还没有清楚地解释为什么不允许这种特殊的通用约束“转义”。

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

潜在的问题可能是整个类型不能内联。

另请参阅: http : //msdn.microsoft.com/en-us/library/dd548046.aspx

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

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

a和b的类型将被自动限制。

您需要标记成员inline (如果要强制参数为^T类型,请添加类型注释):

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

我还添加了一个构造函数,以便您可以实际调用该方法:

MyType().F 1 2

正如其他人指出的那样,几乎不需要手动写出显式成员约束,因为通常可以推断出它们。 此外,在这种情况下,没有理由将约束置于类型而不是方法上,并且通过静态解析的类型变量对类型进行参数化不是惯用的。

F#规范:

^ ident形式的类型是静态解析的变量类型。 将创建一个新的类型推断变量,并将其添加到类型推断环境中(请参见第14.6节)。 用一个属性标记该类型变量,该属性指示除非在内联定义中(参见第14.7节),否则不能对其进行一般化,同样,通过类型推断方程式对其进行等同运算的任何类型变量也可以类似地不进行一般化。

http://research.microsoft.com/zh-cn/um/cambridge/projects/fsharp/manual/spec.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM