考虑以下代码示例:
function
| [] -> "bla"
| ds -> let x::l = List.rev ds in "woot";;
编译/解释以上代码时,会发生以下警告:
line 3, characters 14-18:
Warning 8: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
[]
我想知道为什么会出现此警告。显然,由于顶级模式匹配,[]不是有效的选项。我希望OCaml的编译器/解释器能够通过将信息从顶级匹配传递到嵌套匹配来轻松推断上述代码的详尽性。为什么不这样呢?我想念什么吗?
答案 0 :(得分:3)
OCaml抱怨
let x::l = List.rev ds in "woot"
如果List.rev ds
产生[]
,则会失败。
当然,我们知道不能这样做,因为如果List.rev ds
为空,那么ds
就必须为空,由于另一个保护,这是不可能的。但是OCaml不知道。
请参见docs:
OCaml的模式匹配可以仅基于 type 来检查一组模式是否完整。
并继续提供一个与您的示例非常相似的示例。
关于您的“轻松推断出上面代码的穷尽性”……我认为这听起来并不容易。想象一下,如果您要求而不是ds
不为空,则它必须为“ foo”,并且内部警卫人员确保Digest.to_hex(Digest.string ds)
为"acbd18db4cc2f85cedef654fccc4a4d8"
(必须是这样,因为"foo"
的MD5摘要)。即使对于我们人类而言,也不再如此简单。但是,从计算机的角度来看,List.rev ds
和Digest.to_hex(Digest.string ds)
之间有区别吗?类型很容易。值是 hard 。