OCaml嵌套模式 - 尽管定义了模式但是异常

Ted*_*law 3 ocaml functional-programming pattern-matching

我有一个像这样定义的函数:

 let test_func lis =
   match lis with h::t ->
    match h with h2::t2 ->
      h2
    | [] ->
      []
  | [] ->
    [];;
Run Code Online (Sandbox Code Playgroud)

编译时,我得到一个警告,即此函数与模式[]不匹配 - 即使我将其定义为第二种情况!我发现我可以通过用parens包围第二个匹配语句来解决这个问题:

 let test_func lis =
   match lis with h::t ->
    (match h with h2::t2 ->
      h2
    | [] ->
      [])
  | [] ->
    [];;
Run Code Online (Sandbox Code Playgroud)

但我想知道为什么这是必要的.此外,在顶级匹配语句中交换第一个和第二个案例也有效:

 let test_func lis =     
   match lis with [] ->
     []
   | h::t ->
    match h with h2::t2 ->
      h2
    | [] ->
      [];;
Run Code Online (Sandbox Code Playgroud)

谢谢!

sep*_*p2k 8

如果我们修复代码的缩进,它看起来像这样:

let test_func lis =
  match lis with h::t ->
    match h with h2::t2 ->
      h2
    | [] ->
      []
    | [] ->
      [];;
Run Code Online (Sandbox Code Playgroud)

如果你看一下,很明显第一个和第二个之间没有区别| [] -> [].因此,编译器无法知道您希望第二个属于外部匹配语句而不是内部匹配语句.因此,您需要使用括号来告诉编译器内部匹配语句应该在第一个之后结束| [] -> [].

在第二个版本中,第一个版本| [] -> []明显属于外部匹配语句,因为内部匹配语句甚至在程序中更远的地方才会出现.所以没有歧义,因此不需要括号.