我理解勾号表示通用参数,如:
Seq.append : seq<'T> -> seq<'T> -> seq<'T>
但是插入符号表示什么,如:
Seq.average : seq<^T> -> ^T
我理解勾号表示通用参数,如:
Seq.append : seq<'T> -> seq<'T> -> seq<'T>
但是插入符号表示什么,如:
Seq.average : seq<^T> -> ^T
插入符号表示必须静态解析类型参数,这通常是因为对必须满足的类型有特定的约束,而这些约束不能在正常的 .NET 元数据中表示。例如,Seq.average "test"
即使"test"
is a也不能调用seq<char>
,因为char
s 不支持必要的算术运算。
这些静态解析的类型变量仅来自inline
定义,当使用这样的函数时,它的主体是内联的,以便编译器可以插入正确的特定于类型的指令。
详细签名如下:
Seq.average : seq<^T> -> ^T(需要 ^T 和静态成员 (+) 和 ^T 和静态成员 DivideByInt 和 ^T 和静态成员零)
与 不同Seq.append
,Seq.average需要对元素类型进行更多限制。特别:
_ DivideByInt (s1 + s2 + ... + sn) n where n <> 0
Seq.average {s1; s2;...; sn} = /
\_ ^T.Zero where n = 0
如您所见,(+)
和DivideByInt
都是Zero
必需的,这样Seq.average<^T>
才有意义。
关于泛型的有用信息可以在这里MSDN找到。
尽管正如其他人所指出的那样,按照惯例^T
,使用 withinline
和'T
is not,两者是可以互换的 (有时?)。
因此,从技术上讲,您的问题的答案是“没有区别”。
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
约定是明确的,而实施不是。