通用指示符'和符号^在F#方法签名之间有什么区别

时间:2012-06-28 17:59:20

标签: generics f# method-signature

我理解用于表示通用参数的刻度,如:

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

但是插入符号表示什么,如:

Seq.average : seq<^T> -> ^T

3 个答案:

答案 0 :(得分:6)

插入符号表示必须静态解析type参数,通常是因为必须满足的类型存在特定约束,并且无法在普通.NET元数据中表示。例如,即使Seq.average "test""test",也无法调用seq<char>,因为char不支持必要的算术运算。

这些静态解析的类型变量仅来自inline定义,当使用这样的函数时,它的主体被内联,以便编译器可以插入正确的特定于类型的指令。

答案 1 :(得分:5)

详细签名是:

  

Seq.average:seq&lt; ^ T&gt; - &GT; ^ T(需要^ T与静态成员(+)和^ T   使用静态成员DivideByInt和^ T与静态成员Zero)

Seq.append不同,Seq.average需要对元素类型进行更多限制。特别:

                                _ DivideByInt (s1 + s2 + ... + sn) n where n <> 0
Seq.average {s1; s2;...; sn} = /
                               \_ ^T.Zero where n = 0

如您所见,(+)DivideByIntZero都需要Seq.average<^T>才有意义。

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

答案 2 :(得分:0)

虽然正如其他人所指出的那样,按照约定^Tinline一起使用而'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

约定清除,而实现则不是。