我试图在F#中使用显式成员约束.文档说"F#支持公共语言运行库支持的完整约束集",但是如果我实际上编译了一个具有这种显式约束的类,比如下面的那样,我就会遇到异乎寻常的错误.
type MyType<'T when ^T: (static member ( + ) : ^T * ^T -> ^T)> =
member this.F a b = a + b
Run Code Online (Sandbox Code Playgroud)
报告
错误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
Run Code Online (Sandbox Code Playgroud)
a和b的类型将自动被正确约束.
您需要标记该成员inline(如果您想强制参数为 类型,则需要添加类型注释^T):
type MyType<'T when ^T: (static member ( + ) : ^T * ^T -> ^T)>() =
member inline this.F (a:^T) (b:^T) = a + b
Run Code Online (Sandbox Code Playgroud)
我还添加了一个构造函数,以便您可以实际调用该方法:
MyType().F 1 2
Run Code Online (Sandbox Code Playgroud)
正如其他人所指出的,很少需要手动写出显式成员约束,因为它们通常会被推断出来。此外,在这种情况下,没有理由对类型而不是方法施加约束,并且通过静态解析的类型变量参数化类型并不符合惯用做法。
F# 规范:
\n\n\n\n\n^ident 形式的类型是静态解析的变量类型。创建\n新的类型推断变量并将其添加到\n类型推断环境(请参阅\xc2\xa714.6)。\n此类型变量带有一个\n属性标记,表明它可能无法\n泛化除了内联定义(参见 \xc2\xa714.7),同样,通过类型推断方程与之等同的任何类型变量也可能无法被泛化。
\n
http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/manual/spec.html
\n| 归档时间: |
|
| 查看次数: |
2596 次 |
| 最近记录: |