这种模式似乎详尽无遗,但我仍然收到警告 [英] This pattern seems exhaustive, but I'm still getting warnings
问题描述
我正在学习 sml,并编写了以下简单函数:
I'm learning sml, and wrote the following simple function:
(* Return a list with every other element of the input list *)
fun everyOther [] = []
| everyOther [x] = [x]
| everyOther x = let
val head::head2::tail = x
in
head::everyOther(tail)
end;
产生以下警告:
! Toplevel input:
! val head::head2::tail = x
! ^^^^^^^^^^^^^^^^^
! Warning: pattern matching is not exhaustive
我相信该函数永远不会失败,因为 val head::head2::tail
将始终适用于具有两个或多个元素的列表,并且涵盖了一个元素和零个元素的情况.据我所知,此功能按预期工作.我认为这个问题可能与 []
的使用有关,但我真的不知道.
I believe the function can never fail, since val head::head2::tail
will always work for lists with two or more elements and the case of one element and zero elements is covered. As far as I can tell, this function works as expected. I think the issue might be related to the use of []
but I really don't know.
我的问题实际上是三重的:
My question is actually three fold:
- 为什么 sml 认为这不是详尽无遗的(我怎么会误解)?
- 此功能是否会失败?
- 我在用这种方式编写函数是在做蠢事吗?
推荐答案
SML 给你这个警告是因为它不知道
x
至少有两个元素.它只知道x
是一个列表,它不记得x
必须不匹配前两个模式的事实,才能进入第三种情况.
SML gives you that warning because it doesn't know that
x
has at least two elements. All it knows is thatx
is a list, it doesn't remember the fact thatx
had to have not matched the first two patterns, to go into the third case.
不,代码不能失败.
没有理由在 let 语句中执行模式匹配.您可以将模式放在 fun
语句中,这样可以减少代码并消除警告:
There is no reason to perform the pattern match in the let-statement. You can just put the pattern to the fun
statement, which will result in less code and remove the warning:
fun everyOther [] = []
| everyOther [x] = [x]
| everyOther (head::head2::tail) = head :: everyOther tail;
这篇关于这种模式似乎详尽无遗,但我仍然收到警告的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!