首页 > 解决方案 > 没有双分号的 OCaml 模式匹配语法错误

问题描述

我对 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,它会按预期编译和运行。但是,如果我尝试使用 运行该文件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在出现语法错误之前,我一直很困惑为什么要这样做。

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

标签: syntaxocaml

解决方案


将 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))

推荐阅读