警告8:let语句中的模式匹配警告不完整

lam*_*y.x 4 ocaml

我经常在let语句中进行模式匹配,在那里我知道结果的形状.很明显,我不能指望编译器通常会推断出这些知识,但也许有一种更为惯用的方式可以用简洁的方式来实现.

例如,请查看以下代码:

type foo = A of int | B of string
let x = (true, A 0)
let (b, A i) = x in i + 2 
Run Code Online (Sandbox Code Playgroud)

这正确警告我,结果(_, B _)不匹配.一种可能的方法是显式处理丢失的案例,如:

let (b,i)  = match x with 
    | (a, A j) -> (a,j+2)
    | _ -> failwith "implementation error!" 
Run Code Online (Sandbox Code Playgroud)

但这掩盖了实际的计算.有更简洁的选择吗?

编辑:杰弗里斯科菲尔德评论说,在没有嵌套的情况下,显式转换函数运行良好.是否还有嵌套类型匹配的版本?

Pat*_*atJ 6

如果您确定自己获得了正确的案例并且使用的是OCaml 4.02或更高版本,则可以添加[@@warning "-8"]到您的声明中.

有关属性的更多详细信息,请参阅OCaml手册.

在以前版本的OCaml上,您可以禁用整个文件的警告(这取决于您的构建工作流程)或使用Jeffrey Scofield的答案中描述的显式模式匹配.

我建议不要"禁用整个文件上的警告",因为它会掩盖其他不完整的模式匹配,这可能会在当前以意想不到的方式破坏您的代码(很容易发现)......或者将来的某个地方(比如,如果你在以后的升级中改变了你匹配的类型).


Jef*_*eld 5

对于简单的情况,您可以编写一个部分函数来提取感兴趣的值,其精神类似于List.hd.

let int_of_foo = function
   | A i -> i
   | _ -> raise (Invalid_argument "int_of_foo")

let string_of_foo = function
   | B s -> s
   | _ -> raise (Invalid_argument "string_of_foo")

let (_, f) = x in int_of_foo f + 2
Run Code Online (Sandbox Code Playgroud)

还有用于投影对的(非部分)函数:

int_of_foo (snd x) + 2
Run Code Online (Sandbox Code Playgroud)

(我更新了我的用法x以匹配你的,抱歉。)