OCaml语法错误由双分号纠正 [英] OCaml Syntax Error fixed by double semicolon

查看:103
本文介绍了OCaml语法错误由双分号纠正的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

很抱歉在这里提出这样的基本问题,但是在尝试编译以下代码时出现语法错误,

I'm sorry for asking such a basic question here, but I'm getting a syntax error when trying to compile the following code,

let sum_of_squares_of_two_largest x y z =
    let a :: b :: _ = List.sort (fun x y -> -(compare x y)) [x; y; z] in
    a * a + b * b;

let rec factorial n =
    if n = 0 then 1 else n * factorial (n - 1);

let e_term n = 1.0 /. float_of_int (factorial n);

let rec e_approximation n =
    if n = 0 then (e_term 0) else (e_term n) +. (e_approximation (n - 1));

let rec is_even x = if x = 0 then true else is_odd (x - 1);
    and is_odd  x = not (is_even x);

let rec f_rec n =
    if n < 3 then n else f_rec(n - 1) + 2 * f_rec(n - 2) + 3 * f_rec(n - 3);

信息不详的编译器告诉我,第19行(文件的最后一行)存在语法错误.

The uninformative compiler tells me there is syntax error on line 19, which is the last line of the file.

File "source.ml", line 19, characters 0-0:
Error: Syntax error

也就是说,第19行是空白行,只有换行符.

That is, line 19 is a blank line, only with a new-line character.

我可以通过在每个函数定义的末尾添加;;而不是;来修复"此语法错误.

I can "fix" this syntax error by adding ;; at the end of each function definition instead of the ;.

我在某处缺少分号吗?

推荐答案

正如注释中指出的那样,;不是像许多其他(受Algol启发)语言一样的语句终止符,而是序列运算符.它采用两个值,丢弃第一个值(但如果不是单位则发出警告),然后返回第二个值.因此,a; b大致等同于let _ = a in b.

As has been pointed out in the comments, ; is not a statement terminator like in many other (Algol-inspired) languages, but a sequence operator. It takes two values, throws away the first (but warns if it is not unit) and returns the second. a; b is therefore roughly equivalent to let _ = a in b.

您说您会期望该错误说类似';' is missing the second operand.之类的东西,但事实是:事实并非如此.直到它到达文件末尾(此时错误消息肯定可以更智能,但无论如何可能都不十分准确).

You say you would have expected the error to say something like ';' is missing the second operand., but the thing is: it doesn't. Not until it reaches the end of the file (at which point the error message certainly could have been more intelligent, but probably not very accurate anyway).

代码中每个;之后的内容看起来都像是一个完全有效的表达式,可能会产生一个值.例如,如果let rec factorial n = ...;let rec factorial n = ... in 2,则表达式的值将是2.从编译器的角度来看,这里的问题是在表达式完成之前,它用完了文件.

What follows each ; in your code looks like a perfectly valid expression that might yield a value. For example, if let rec factorial n = ...; had been let rec factorial n = ... in 2 The value of the expression would have been 2. The problem here, from the compiler's point of view, is that it runs out of file before the expression is finished.

您也已经发现,;;实际上是一个语句终止符.也许顶级定义终止符是一个更好的术语(我不知道它是否有正式名称).它在REPL中用于终止输入,但在普通的OCaml代码中不需要使用它,除非您混合使用了顶级定义和​​表达式,而这是绝对不应该的.

As you've also found out, ;; actually is a statement terminator. Or perhaps a toplevel definition terminator is a better term (I don't know if it even has an official name). It's used in the REPL to terminate input, but isn't needed in normal OCaml code unless you mix toplevel definitions and expressions, which you never should.

;;对于初学者仍然可以作为"bulkhead"使用.如果仅在文件中间放置一个;;代替;,您会发现编译器现在将错误位置指向该位置.这是因为;;在没有完成前面的表达式的情况下终止了定义.因此,您现在知道在此之前有错误. (实际上,在前面的表达式中,但是由于您的整个文件是一个单独的表达式,因此在此之前"确实是我们可以做的最好的事情.)

;; can still be useful for beginners as a "bulkhead", however. If you put just one ;; in place of a ; in the middle of your file, you'll find the compiler now points the error location there. That's because ;; terminates the definition without the preceding expression being complete. So you now know there's an error before that. (Actually in the preceding expression, but since your entire file is one single expression, "before that" is really the best we can do).

这篇关于OCaml语法错误由双分号纠正的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆