ocaml begin/end 模式匹配

ocaml begin/end pattern matching

无法在 ocaml 中找到很多关于 begin/end 的在线文档。我在同一个函数中有两个不同的模式匹配(我想彼此独立),但是 vscode 正在解析它们以将第二个嵌套在第一个中。我尝试围绕 begin/end 中的第一个模式匹配,但它给我语法错误:

    begin match c.r with (* first pattern match *)
    | [ r1; r2; r3 ] -> 
        let _ = print_endline (String.make 1 r3.top) in end
    match cl with (* second pattern match *)
    | [] -> []

我在 end 上看到一条红色下划线,上面写着 Syntax error after unclosed begin, expecting expr。我不明白这是什么意思,既然我写了end来关闭begin,那么为什么begin没有关闭呢?代码在没有 begin/end 的情况下编译得很好(除了它将第二个模式匹配嵌套在第一个模式中)。谢谢。

在 OCaml 中,begin/end 与 open/close 括号基本相同。在里面你应该有一个格式正确的表达式(就像在几乎任何编程语言中一样)。

begin/end 中的内容不是表达式,因为它以 in 结尾。 let 表达式看起来像 let pattern = expr1 in expr2。您缺少 begin/end.

中的第二个表达式

你应该做的(我认为)是 begin/end 围绕 内部 match 像这样:

match c.r with
| [r1; r2; r3 ] ->
    let _ = print_endline (String.make 1 r3.top) in
    begin
    match c1 with
    | [] -> []
    ...
    end
| ...

(这段代码没有多大意义,但我认为这只是一个例子。)

作为另一个简化,如果 a 是单位类型,您可以将 let _ = a in b 更改为 a; b,就像您的代码中那样。

杰弗里斯科菲尔德说的。考虑一下当我们嵌套匹配时这会如何变得混乱。我们如何阅读以下内容?

match "foo" with
| "bar" -> 42
| "foo" ->      
  match "baz" with
  | "baz" -> 27
  | _ -> 19
| _ -> 33

缩进可以很清楚地说明这是什么意思,但 OCaml 并不关心你的漂亮缩进。它可能很容易就是你的意思:

match "foo" with
| "bar" -> 42
| "foo" ->      
  match "baz" with
  | "baz" -> 27
| _ -> 19
| _ -> 33

或:

match "foo" with
| "bar" -> 42
| "foo" ->      
  match "baz" with
  | "baz" -> 27
  | _ -> 19
  | _ -> 33

括号或 begin/end 消除这种情况的歧义。

match "foo" with
| "bar" -> 42
| "foo" ->      
  (match "baz" with
   | "baz" -> 27
   | _ -> 19)
| _ -> 33

或:

match "foo" with
| "bar" -> 42
| "foo" ->      
  begin
    match "baz" with
    | "baz" -> 27
    | _ -> 19
  end
| _ -> 33

还有一件事...

嵌套 match 表达式通常是不必要的。考虑一下当你有一个嵌套的 match 时,如果你不能更清楚地表达与值元组上的单个级别 match 相同的内容。

match a with
| X -> ...
| Y ->
  (match b with
   | Z -> ...
   | W -> ...
   | _ -> ...)
| U ->
  (match c with
   | F -> ...
   | G -> ...
   | _ -> ...)
| _ -> ...

对比

match a, b, c with
| X, _, _ -> ...
| Y, Z, _ -> ...
| Y, W, _ -> ...
| Y, _, _ -> ...
| U, _, F -> ...
| U, _, G -> ...
| U, _, _ -> ...
| _, _, _ -> ...