Неустранимая ошибка: исключение Match_failure("main.ml", 8, 15)

Вот мой код:

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 ответа

Решение

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

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

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 функция. Где вы были предупреждены, что ваше сопоставление с образцом было неполным. Урок здесь: "Не игнорируйте предупреждения, они не надоедают, они важны".

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

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

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

Другие вопросы по тегам