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

时间:2015-01-02 15:07:58

标签: types f# type-inference

我有以下代码

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.

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

1 个答案:

答案 0 :(得分:6)

您在这里面临的是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问题和答案。