价值限制和类型推断

时间:2017-11-23 08:25:03

标签: types f#

我构建了一个简单的函数,给定一个列表,返回一个列表,其中输入中元素的连续出现次数减少为一。

let rec reduce l =
match l with
| []                ->  []
| [x]               ->  [x]
| x::(y::_ as xs)   ->  if x = y then
                            reduce xs
                        else
                            x::(reduce xs)


# reduce [1;1;2;2;2;3;3;4;3;3;3];;
- : int list = [1;2;3;4;3].
# reduce [’a’;’a’;’a’;’b’];;
- : char list = [’a’; ’b’].
# reduce [];;                // The case 
- : ’a list = []

除了空列表[]输入外,一切都按预期工作。投诉人说错误FS0030:价值限制。我试图通过documentation更好地理解这些现象,但我觉得我仍然不具备正确理解这一点的技巧。为什么泛型函数确实需要指定类型为[]的情况?结果[]无法在没有类型推断的情况下报告?最后,如何构建函数,以便管理这种情况?

1 个答案:

答案 0 :(得分:2)

正如John在评论中所说,问题是[]没有给编译器任何关于列表类型的提示 - 在所有其他情况下,你知道它是整数字符列表,但在这里,类型尚不清楚。

您无法运行涉及未知泛型类型的F#代码,因此无法运行代码并返回通用列表 - 在运行代码时,需要完全指定所有类型。

您可以通过多种方式提供类型注释来修复类型:

reduce ([] : int list)
(reduce [] : int list)
(reduce:int list -> _) []

您还可以将调用包装到另一个编译的泛型函数中,因为现在通用代码位于另一个需要类型才能使用的泛型函数中:

let foo () = reduce []

但是现在你遇到了同样的问题 - 你需要在调用foo时指定类型,或者编译器需要能够从上下文推断它,例如如果你写1 :: foo()