没有双分号的 OCaml 模式匹配语法错误

OCaml pattern-match syntax error without double semi colon

我对 OCaml 很陌生,如果这是一个愚蠢的问题,我深表歉意。我有这个 OCaml 文件:

type tree =
  | Node of int * tree * tree
  | Leaf of int

let t = Node (3, Node (4, Leaf 1, Node (3, Leaf 5, Leaf 2)), Leaf 1)

let rec height t =
  match t with
  | Node (n, t1, t2) -> 1 + max (height t1) (height t2)
  | Leaf n -> 0

let _ = print_string (string_of_int (height t))

如果我用 ocamlc -o out my_file.ml 编译文件,它会按预期编译和 运行s。但是,如果我尝试使用 ocaml < my_file.ml 运行 文件,我会在 height 函数的定义中遇到语法错误。

在我的 height 函数之后放置一个双分号:

let rec height t =
  match t with
  | Node (n, t1, t2) -> 1 + max (height t1) (height t2)
  | Leaf n -> 0
;;

解决了问题。

我的问题是:

  1. OCaml 是否只在交互模式下要求在模式匹配后使用双分号?这似乎是问题的来源。
  2. ocamlformat知道吗?当我在文件上 运行 ocamlformat 时,它会自动在我的 height 函数之后放置一个双分号。在我收到语法错误之前,我对它为什么这样做感到困惑。

提前感谢您提供的信息!我一直在寻找这些问题的答案,但没有成功。我确实发现 this blog 声称双分号是 从来没有 必要的。

将 OCaml 文件作为脚本 运行 通常的方法是这样的:

$ ocaml myfile.ml

如果您 运行 没有文件名,就像您正在做的那样,ocaml 会进入交互模式,在该模式下,它希望一个人输入 ;; 指示评估时间应该发生。在此模式下,它确实将 EOF 视为语法错误,因为此时您有一些未处理的输入。

如果您尝试上面的命令(没有 < 重定向),您应该会看到您期望的行为。

以下是我对您问题的回答:

  1. OCaml 实际上在任何地方都不需要双分号。它们只是一种告诉解释器(REPL,也称为顶层)它应该评估你最近输入的内容的方法。这是允许多行输入的一种方法。

  2. 当我 运行 ocamlformat 时,我没有在输出中看到任何双分号。我无法重现你的这个观察结果。

这是我看到的 运行 编写脚本的常用方法:

$ ocaml myfile.ml
3$ 

这是我在 运行 ocamlformat:

时看到的
$ ocamlformat --enable-outside-detected-project myfile.ml
type tree = Node of int * tree * tree | Leaf of int

let t = Node (3, Node (4, Leaf 1, Node (3, Leaf 5, Leaf 2)), Leaf 1)

let rec height t =
  match t with
  | Node (n, t1, t2) -> 1 + max (height t1) (height t2)
  | Leaf n -> 0

let _ = print_string (string_of_int (height t))