为什么这个OCaml语法错误

mlj*_*jrg 2 ocaml syntax-error

我在Ocaml中有这个代码

let double x = 2 * x

let triple x = 3 * x

let s = "Hello" in print_endline s

let () = triple 10 |> string_of_int |> print_endline
Run Code Online (Sandbox Code Playgroud)

并且在使用ocamlc file.ml此编译时会出现错误:

File "file.ml", line 5, characters 16-18:
Error: Syntax error
Run Code Online (Sandbox Code Playgroud)

如果我;;像这样放在第3行的末尾

let triple x = 3 * x;;
Run Code Online (Sandbox Code Playgroud)

如果我像这样评论第5行中的字符16-18

let s = "Hello" (* in print_endline s *)
Run Code Online (Sandbox Code Playgroud)

语法错误消失了.

有人可以解释语法错误的原因,以及这两个更正中的每一个都可以解决它吗?

gle*_*nsl 5

let s = "Hello" in print_endline s它不是一个顶级声明,即使它始于let,它是一个let .. in表达.如果你不使用;;它终止前面的表达式,那么接下来要表达的是那个表达式的一部分,而不是将它解释为顶级声明.

如果删除in ...部件,则将其从let ... in表达式更改为顶级let声明.

您还可以将其转换为顶级声明,如下所示:

let () = let s = "Hello" in print_endline s
Run Code Online (Sandbox Code Playgroud)

编辑:

考虑这一点的一种方法是,如果不是

let triple x = 3 * x

let s = "Hello" in print_endline s
Run Code Online (Sandbox Code Playgroud)

let s = ... in ...用一个更简单的表达式替换,就像"Hello":

let triple x = 3 * x

"Hello"
Run Code Online (Sandbox Code Playgroud)

这相当于

let triple x = 3 * x "Hello"
Run Code Online (Sandbox Code Playgroud)

将解析为将参数"Hello"应用于函数x

  • 这一切都有点混乱,因为我认为``;``终结符有点像是一种后遗症,但经验法则是:如果顶级声明后面的内容本身不是顶级声明,则需要将它们分开与`;;`. (2认同)
  • 或者,您可以将`let s = ...`转换为顶级声明:在print_endline s中`let()= let s ="Hello" (2认同)