Generics 一般能指与一般能指有什么区别;以及F#方法签名中的符号^

Generics 一般能指与一般能指有什么区别;以及F#方法签名中的符号^,generics,f#,method-signature,Generics,F#,Method Signature,我理解勾号表示通用参数,如: Seq.append : seq<'T> -> seq<'T> -> seq<'T> Seq.append:Seq->Seq插入符号表示必须静态解析类型参数,通常是因为必须满足类型上的特定约束,而这些约束不能在正常的.NET元数据中表示。例如,您不能调用Seq.average“test”,即使“test”是Seq,因为char不支持必要的算术运算 这些静态解析的类型变量只产生于内联定义,当使用此类函数时,其主体是内联

我理解勾号表示通用参数,如:

Seq.append : seq<'T> -> seq<'T> -> seq<'T>

Seq.append:Seq->Seq插入符号表示必须静态解析类型参数,通常是因为必须满足类型上的特定约束,而这些约束不能在正常的.NET元数据中表示。例如,您不能调用
Seq.average“test”
,即使
“test”
Seq
,因为
char
不支持必要的算术运算


这些静态解析的类型变量只产生于
内联定义,当使用此类函数时,其主体是内联的,以便编译器可以插入正确的特定于类型的指令。

详细签名为:

Seq.average:Seq->^T(需要^T和静态成员(+)和^T 使用静态成员DivideByInt和^T(使用静态成员零)

Seq.append
不同,需要对元素类型进行更多约束。特别是:

                                _ DivideByInt (s1 + s2 + ... + sn) n where n <> 0
Seq.average {s1; s2;...; sn} = /
                               \_ ^T.Zero where n = 0
\uudividebyint(s1+s2+…+sn)n其中n0
序列平均值{s1;s2;…;sn}=/
\_^T.Zero,其中n=0
如您所见,
(+)
DivideByInt
Zero
都是必需的,以便
Seq.average
有意义


可以找到有关泛型的有用信息。

尽管如其他人所指出的,按照惯例,
^T
内联
一起使用,而
'T
不一起使用,但两者是可互换的(有时?)

所以,从技术上来说,你的问题的答案是“没有区别。”

kvb指出:这是有区别的。但这并不像其他答案所表明的那样明确。在某些情况下,两者是可互换的,例如:

let inline add (x:^T) (y:^T) = x + y
let inline add (x:'T) (y:'T) = x + y


约定是明确的,而实现是不明确的。

在运行时解析(泛型)<代码>^
在编译时解析。看,伊尔贾恩,你为什么不把这个作为回答而不是评论呢。对我来说,这似乎是正确的。因为仅仅链接到文档而不添加详细信息是一个糟糕的答案,而且我现在不想添加详细信息。;-]谢谢你的澄清。我删除它是为了缩短示例,不应该这样做。我认为这不对-看看如果您尝试执行
let f(x:^t)=x
let f(x:'t)=x
,会发生什么。我对
^
的效果感到困惑。这两种方法都是一样的:
让add(x:^T)(y:^T)=x+y
。区别似乎是
^
要求可以推断出一些静态约束……这与
f(x:^T)=x
的情况不同。在这些示例中,定义不是通用的,因此类型变量在任何情况下都会消失。查看将函数显式泛型(例如
add@kvb:(提示暮光之城主题)在我看来,这将使区分变得深奥和无定形。也许可以快速说明撇号。不需要太多细节,但它对不太了解泛型的人很有用。
let inline add (x:^T) (y:^T) = x + y
let inline add (x:'T) (y:'T) = x + y
let f (x:^T) = !x
let f (x:'T) = !x