This pattern seems exhaustive, but I'm still getting warnings

扶醉桌前 提交于 2019-12-08 21:41:21

问题


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;

Which is generating the following warning:

! Toplevel input:
!   val head::head2::tail = x
!       ^^^^^^^^^^^^^^^^^
! Warning: pattern matching is not exhaustive

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:

  1. Why does sml think that this is not exhaustive (how am I misinterpreting this)?
  2. Is there a case where this function will fail?
  3. Am I doing something dumb writing the function this way?

回答1:


  1. SML gives you that warning because it doesn't know that x has at least two elements. All it knows is that x is a list, it doesn't remember the fact that x had to have not matched the first two patterns, to go into the third case.

  2. No, the code can not fail.

  3. 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;
    


来源:https://stackoverflow.com/questions/9074042/this-pattern-seems-exhaustive-but-im-still-getting-warnings

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!