如何摆脱警告 "this pattern-matching is not exhaustive..."?

how to get rid of the warning "this pattern-matching is not exhaustive..."?

我在 OCaml 中编写了以下函数,它接受一个嵌套的 Pair 和 returns 一个 Pair(a,b) 以便 a 是所有奇数元素的嵌套 Pair,b 是所有奇数元素的嵌套 Pair偶数元素:

let rec split_var_val xs =
  match xs with
  | Nil -> Pair(Nil,Nil)
  | Pair(Pair(x, Pair(y, Nil)), tail) ->
      let Pair(a,b) = split_var_val tail in
      Pair(Pair(x,a),Pair(y,b)) 
  | _ -> raise X_no_match ;;

该功能运行良好,但我收到以下 警告

this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
(Nil|Bool _|Number _|Char _|String _|Symbol _)

如何修复该功能以消除警告?

指的是这一行:

let Pair(a,b) = split_var_val tail in
    ^^^^^^^^^

要消除警告,您通常会使用 match ... with。如果您确定获取 Pair 以外的其他内容是错误,您可以使用 assert false,如下所示:

(match split_var_val tail with
 | Pair(a,b) -> ...
 | Nil -> assert false
)

assert false 将引发包含源代码中错误位置的异常。

此表达式产生警告:

let Pair(a,b) = split_var_val tail in

假设 split_var_val 总是 return 使用 Pair 构造函数构造的值,如果我们研究实现(模所有 -引发异常的匹配大小写)。

如果你想做这个假设,你可以告诉编译器安静,例如,

let Pair(a,b) = split_var_val tail [@@warning "-P"] in

或者您实际上可以通过匹配所有情况使模式匹配详尽无遗,

let (a,b) = match split_var_val tail with
  | Pair (a,b) -> (a,b)
  | _ -> assert false in (* or something less generic *)

更好的解决方案是重新编写您的函数并使其 return 成对而不将其包装到 Pair 构造函数中。 (基本上,用 Pair 包装它与过早向上转换相同),例如

let rec split_var_val xs =
  match xs with
  | Nil -> (Nil,Nil)
  | Pair(Pair(x, Pair(y, Nil)), tail) ->
      let (a,b) = split_var_val tail in
      (Pair(x,a),Pair(y,b)) 
  | _ -> raise X_no_match 

然后,在您使用 split_var_val xs 的其他地方,您只需要将其换回 let x,y = split_var_val xs in Pair (x,y)