在 F# 签名文件中,函数签名两边的括号有何意义?

In an F# signature file, what is the significance of parentheses around a function signature?

作为 .fsi 签名文件的消费者,两者之间有什么区别(如果有的话):

val sum : int -> int -> int

val sum : (int -> int -> int)

好像第二个可以用函数定义实现或者用函数实现'alias',但是第一个只能用函数定义实现。

具有以下内容:

// .fsi
val add : int -> int -> int
val sum : int -> int -> int
// .fs
let add a b = a + b
let sum = add

产生错误

error FS0034: Module 'Butter' contains
    val sum : (int -> int -> int)
but its signature specifies
    val sum : int -> int -> int    

但是如果签名文件是:

// .fsi
val add : (int -> int -> int)
val sum : (int -> int -> int)

它编译正常。

这种行为是故意的吗?如果是的话,括号是如何改变界面的?

这里的元组是什么?如果是 .NET 的 System.Tuple,那么这就没有意义了。

val x : Tuple -> float

将是一个接受 static class 元组和 returns 浮点数的函数。如果你想要一个元组实例,那么你需要准确指定你想要的 n 元组类型(Tuple<'a>Tuple<'a, 'b> 是两种不同的类型)。

以下应该有效:

var x : Tuple<float, _, _, _> -> float

是的,这是故意的行为。

在创建一个更简单的示例来响应 Tom 的回答时,我实际上正确地阅读了错误消息,它说:

The arities in the signature and implementation differ. The signature specifies that 'sum' is function definition or lambda expression accepting at least 2 argument(s), but the implementation is a computed function value. To declare that a computed function value is a permitted implementation simply parenthesize its type in the signature, e.g.↔ val sum: int -> (int -> int)↔instead of↔ val sum: int -> int -> int.

因此括号用于指示计算表达式是允许的实现以及 lambda 和函数定义。 (我不会假装我正确理解其中的区别。)