作为.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)
它编译正常。
这种行为是故意的吗?如果是,括号是如何改变接口的?
这里的Tuple是什么?如果它是.NET的System.Tuple
,那么这就没有意义了。
val x : Tuple -> float
将是一个接受静态类元组并返回浮点值的函数。如果你想要一个元组实例,那么你需要准确地指定你想要的n元组类型(Tuple<'a>
和Tuple<'a, 'b>
是两种不同的类型(。
以下内容应该有效:
var x : Tuple<float, _, _, _> -> float
是的,这是故意行为。
在创建一个更简单的例子来回应汤姆的回答时,我实际上正确地阅读了错误消息,上面写着:
签名和实现中的arities不同。签名指定"sum"是函数定义或lambda表达式至少接受2个参数,但实现是计算的函数值。声明计算的函数值是允许的实现只需在签名中用括号括起其类型,例如。↔valsum:int->(int->int(↔而不是↔val sum:int->int->内部
因此,括号用于指示计算表达式以及lambda和函数定义是允许的实现。(我不会假装我完全理解其中的区别。(