F#带有curried函数的类型推断

rob*_*kuz 3 f# types type-inference

我有以下代码

let bar foo baz = foo, baz 

let z = bar 3
let z1 = z 2
Run Code Online (Sandbox Code Playgroud)

但如果我注释掉最后一行,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.
Run Code Online (Sandbox Code Playgroud)

我完全迷失了如何正确地注释函数.

Tom*_*cek 6

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

let bar foo baz = foo, baz
Run Code Online (Sandbox Code Playgroud)

...在语法上是一个函数(它显然有两个参数),所以它被推断为泛型.然而:

let z = bar 3
Run Code Online (Sandbox Code Playgroud)

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

let z1 = z 2
Run Code Online (Sandbox Code Playgroud)

这修复了z要进行的类型int -> int * int.如果您没有此行,您可以自行修复该类型:

let z : int -> int * int = bar 3
Run Code Online (Sandbox Code Playgroud)

或者,您可以将其作为一个语法函数,可以推断为泛型:

let z a = bar 3 a
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请搜索讨论价值限制的各种其他SO问题和答案.