我构建了一个简单的函数,给定一个列表,返回一个列表,其中输入中元素的连续出现次数减少为一。
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更好地理解这些现象,但我觉得我仍然不具备正确理解这一点的技巧。为什么泛型函数确实需要指定类型为[]
的情况?结果[]
无法在没有类型推断的情况下报告?最后,如何构建函数,以便管理这种情况?
答案 0 :(得分:2)
正如John在评论中所说,问题是[]
没有给编译器任何关于列表类型的提示 - 在所有其他情况下,你知道它是整数字符列表,但在这里,类型尚不清楚。
您无法运行涉及未知泛型类型的F#代码,因此无法运行代码并返回通用列表 - 在运行代码时,需要完全指定所有类型。
您可以通过多种方式提供类型注释来修复类型:
reduce ([] : int list)
(reduce [] : int list)
(reduce:int list -> _) []
您还可以将调用包装到另一个编译的泛型函数中,因为现在通用代码位于另一个需要类型才能使用的泛型函数中:
let foo () = reduce []
但是现在你遇到了同样的问题 - 你需要在调用foo
时指定类型,或者编译器需要能够从上下文推断它,例如如果你写1 :: foo()