Совпадение по вложенному шаблону, не исчерпывающее предупреждение - PullRequest
0 голосов
/ 07 ноября 2018

Рассмотрим следующий пример кода:

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 сможет легко определить исчерпывающий характер вышеприведенного кода, передавая информацию из сопоставления верхнего уровня во вложенное сопоставление. Почему это не так? Я что-то упустил?

1 Ответ

0 голосов
/ 07 ноября 2018

OCaml жалуется на

let x::l = List.rev ds in "woot"

, который завершится неудачей, если List.rev ds выдаст [].

Конечно, мы знаем, что это невозможно, потому что, если List.rev ds будет пустым, тогда ds должен быть пустым, что невозможно из-за другого охранника; но Окамл этого не знает.

См. документы :

Сопоставление с образцом в OCaml может проверить, является ли набор шаблонов исчерпывающим или нет, основываясь только на типе .

и далее приводит пример, который удивительно похож на ваш.

Относительно того, что вы "легко выводите исчерпывающий характер вышеприведенного кода" ... Я не думаю, что это так просто, как вы делаете это звучащим. Представьте, что вместо ds вы потребовали, чтобы он не был пустым, чтобы он был "foo", а внутренняя охрана убедилась, что Digest.to_hex(Digest.string ds) равно "acbd18db4cc2f85cedef654fccc4a4d8" (что должно быть так, как это MD5 дайджест "foo"). Уже не так просто, даже для нас, людей. Но есть ли разница между List.rev ds и Digest.to_hex(Digest.string ds), с точки зрения компьютера? Типы просты. Значения жесткие .

...