Охранники - это when
части.Компилятор говорит вам, что он не может сказать, является ли ваше совпадение исчерпывающим (охватывает все возможные случаи), но что это не так.Компилятор не может точно сказать наверняка, потому что полнота неразрешима для произвольных выражений.Компилятор просто считает, что у вас должен быть хотя бы один шаблон без защиты, потому что когда совпадение является исчерпывающим, защита в последнем случае будет избыточной.
Поскольку вы знаете, что ваше сопоставление является исчерпывающим, компилятор в основном прав,Ваш второй охранник лишний.Вы можете просто оставить это без разницы в значении:
match z with
| y when List.length z = 0 -> ...
| y -> ...
Это сделает компилятор счастливым.
Мне нравится это предупреждение;он обнаружил несколько логических ошибок для меня за эти годы.
Если этот код не просто пример, а действительно то, что вы написали, было бы гораздо более идиоматичным написать его так:
match z with
| [] -> ...
| head :: tail -> ...
Это также немного более эффективно, так как он не потрудится вычислить длину списка и затем отбросить результат.
Если вам не нужно деструктурировать список, выможет сделать это еще проще:
if z = [] then
...
else
...