它适用于太多的论点;也许你忘记了一个`;'

时间:2018-06-11 09:43:03

标签: syntax syntax-error ocaml

我正在尝试编写一个计算列表大小的代码。

以下是我所做的:

let rec l = function 
  | [] -> 0 
  | t::q -> 1 + l q


print_int(l ([1;2;3;4]))

问题是它在说我:

It is applied to too many arguments; maybe you forgot a `;'.

当我在;;定义的末尾放置双分号l时效果很好,但我已经读过如果你不是;;根本没用在REPL编码,所以在这里我不明白为什么它给了我这个错误。

2 个答案:

答案 0 :(得分:1)

以下

print_int(l [1;2;3;4])

是一个顶级表达。这种表达需要以;;

开头
;; print_int(l [1;2;3;4])

另一个选择是使这个顶层表达式与

绑定
let () = print_int(l [1;2;3;4])

答案 1 :(得分:1)

解析代码时,解析器会前进,直到达到l q。此时可能会有更多的参数应该应用于函数l。所以解析器继续运行,它找到的下一个东西是值print_int。 l的另一个论点。这会给你错误。

解析器无法知道您已完成函数l的代码。在顶层,特殊标记;;用于告诉解析器输入已完成,它现在应该评估代码。之后,它再次开始削减剩余的输入。

现在为什么编译后的代码也没有';;'令牌?

仅仅因为它不需要。在编译的代码中,行print_int(l [1;2;3;4])不是有效输入。那将是你想要执行的语句,而函数式语言则没有这样的东西。相反,print_int(l [1;2;3;4])是一个表达式,在这种情况下返回一个值,(),你必须告诉编译器该如何处理该值。 let () =告诉编译器将它与()匹配。 let ...也告诉编译器前一个let rec l ...已经完成。因此,不需要特殊的;;令牌。

或者以这种方式考虑:如果您的输入不以let开头,则在顶层有一个隐式let _ =。这样,您只需键入一些表达式并查看其评估结果,而无需每次都键入let _ =。 ';;'令牌仍然意味着“现在评估”,但仍然需要。