Неустранимая ошибка: исключение Match_failure ("main.ml", 8, 15) - PullRequest
0 голосов
/ 11 июня 2018

Вот мой код:

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 голосов
/ 11 июня 2018

Прежде чем взглянуть на ошибки во время выполнения, лучше сначала взглянуть на выходные данные компилятора (то есть предупреждения).

У вас есть два предупреждения.Первый:

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 снова.Сделайте это.

Теперь давайте рассмотрим ваше исключение.В основном это говорит: «Сопоставление с образцом в строке 8, символ 15 не удался».Это ваша node функция.Где вы были предупреждены, что ваше сопоставление с образцом было неполным.Урок здесь: «Не игнорируйте предупреждения, они не надоедают, они важны».

0 голосов
/ 12 июня 2018

Другие уже объяснили предупреждения и что они значат.Следуйте этому.

Я просто хочу добавить кое-что о том, где ваш код в настоящее время не работает.В сбалансированной функции вы обнаруживаете, что оба левых и правых потомка пусты, и обрабатываете случай, когда оба потомка не пустые правильно.Но что, если только один ребенок пуст?В этом случае вы вычисляете node g и node d.Одним из них является пустой, который вы не рассмотрели в функции узла.В вашем примере есть узлы, в которых только одна сторона пуста, и там происходит сбой.

0 голосов
/ 11 июня 2018

Предупреждение не ошибается.Вы пропустили случай, и компилятор сгенерировал пример этого случая для вас.Этот случай появляется во время выполнения, и в результате вы получаете совпадение, которое не удается, потому что вы его не обрабатываете.

...