致命错误:异常Match_failure(" main.ml",8,15)

时间:2018-06-11 16:10:18

标签: pattern-matching ocaml non-exhaustive-patterns

这是我的代码:

type 'a tree = Empty | N of 'a * 'a tree * 'a tree


let absolute x = 
    if x > 0 then x 
    else -x

let rec node = function 
    | N(_, Empty, Empty) -> 1
    | N(_, g, d) -> 1 + node g + node d

let rec balanced = function 
    | N(_, Empty, Empty) -> 0
    | N(_,g,d) when absolute (node g - node d) > 1 -> 1
    | N(_,g,d) when absolute (node g - node d) <= 1 -> balanced g + balanced d


let () = print_int (balanced (N ('x', N ('x', Empty, Empty),
  N ('x', N ('x', Empty, Empty), Empty))))

然后它告诉我:

Fatal error: exception Match_failure("main.ml", 8, 15)

我不明白这是什么意思,它似乎并不能说明我的错误来自哪里。

此外,我收到以下警告:

File "main.ml", line 8, characters 15-93:
Warning 8: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
Empty
File "main.ml", line 12, characters 19-190:
Warning 8: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
(N (_, Empty, N (_, _, _))|N (_, N (_, _, _), _)|Empty)
(However, some guarded clause may match this value.)

我怎样摆脱这个警告?

我的意思是根据我的意思并不是说我错过了N(_,_,_)这个案例,但这种情况总是得到处理,为什么编译器告诉我这个案例不匹配?

3 个答案:

答案 0 :(得分:3)

在查看运行时错误之前,最好先查看编译器输出(即警告)。

你有两个警告。第一个:

File "main.ml", line 8, characters 15-93:
Warning 8: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
Empty

这里它告诉我们node函数中的模式匹配不处理Empty情况。只需在模式匹配中添加| Empty -> 0,您就应该很好(顺便说一句,您不再需要不完整的Node (_,Empty,Empty)个案例。)

现在你的第二个警告有点棘手:

File "main.ml", line 12, characters 19-190:
Warning 8: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
(N (_, Empty, N (_, _, _))|N (_, N (_, _, _), _)|Empty)
(However, some guarded clause may match this value.)

在这里,它告诉我们几个模式不匹配,但是有些值被保护。确实案例N (_,_,_)是。

您可以通过删除第二个N (_,_,_)子句(即when)向编译器显示所有when absolute (node g - node d) <= 1的处理方式。模式匹配不会达到这一点,除非该条款为真,所以你可以确定它是。此外,您确保不要以这种方式重复两次相同的计算。请注意,在此模式匹配中,您还没有再次处理Empty情况。那样做。

现在让我们来看看您的例外情况。它基本上说&#34;第8行字符15的模式匹配失败&#34;。这是您的node功能。您被警告您的模式匹配不完整的地方。这里的教训是不要忽视警告,它们并不麻烦,它们非常重要&#34;。

答案 1 :(得分:1)

警告没有错。您缺少一个案例,编译器已为您生成了该案例。这种情况在运行时出现,因此您将获得失败的匹配,因为您无法处理它。

答案 2 :(得分:0)

其他人已经解释了警告及其含义。跟着那个。

我只想添加一些关于代码当前失败的内容。在平衡功能中,您可以看到左右儿童都是空的情况,并处理两个孩子都没有正确清空的情况。但是如果只有一个孩子是空的呢?在这种情况下,您计算node gnode d。其中一个是Empty,这是你没有在节点功能中覆盖的情况。你的例子确实有一个节点,其中只有一面是空的,它就会失败。

相关问题