F# 使用柯里化函数进行类型推断

F# Type inference with curried functions

我有以下代码

let bar foo baz = foo, baz 

let z = bar 3
let z1 = z 2

但是如果我注释掉最后一行 let z1 = z 2 我会得到一个错误

let z = bar 3
----^

stdin(78,5): error FS0030: Value restriction. 
The value 'z' has been inferred to have generic type
val z : ('_a -> int * '_a)    
Either make the arguments to 'z' explicit or, if you do not intend for it to be generic, 
add a type annotation.

我完全不知道如何正确注释函数。

您在这里面临的是 F# 的一个方面,称为 值限制。这实质上意味着,如果您定义的值在语法上不是函数,那么它就不能是通用的。

let bar foo baz = foo, baz

... 在语法上是一个函数(它显然有两个参数),因此它被推断为通用的。然而:

let z = bar 3

... 在语法上不是一个函数——它只是一个值 z 恰好是一个函数(因为那是 bar 的类型所指示的)。所以,这不能通用。在您的代码段中,通用性受到下一行的限制:

let z1 = z 2

这将 z 的类型固定为 int -> int * int。如果你没有这一行,你可以自己修复类型:

let z : int -> int * int = bar 3

或者,您可以将其设为可以推断为泛型的句法函数:

let z a = bar 3 a

有关详细信息,请搜索讨论 value restriction 的各种其他 SO 问题和答案。