【问题标题】:This pattern seems exhaustive, but I'm still getting warnings这种模式似乎很详尽,但我仍然收到警告
【发布时间】:2012-02-22 20:20:22
【问题描述】:

我在学习sml,写了如下简单的函数:

(* 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 将始终适用于具有两个或多个元素的列表,并且涵盖了一个元素和零个元素的情况。据我所知,此功能按预期工作。我认为这个问题可能与[] 的使用有关,但我真的不知道。

我的问题实际上是三个方面:

  1. 为什么 sml 认为这并不详尽(我怎么会误解这个)?
  2. 是否存在此功能会失败的情况?
  3. 我这样写函数是不是在做蠢事?

【问题讨论】:

    标签: types recursion sml


    【解决方案1】:
    1. SML 向您发出警告,因为它不知道x 至少有两个元素。它只知道x 是一个列表,它不记得x 必须不匹配前两种模式才能进入第三种情况。

    2. 不,代码不能失败。

    3. 没有理由在 let 语句中执行模式匹配。您可以将模式放在fun 语句中,这将减少代码并删除警告:

      fun everyOther [] = []
        | everyOther [x] = [x]
        | everyOther (head::head2::tail) = head :: everyOther tail;
      

    【讨论】:

    • 谢谢!我仍在努力思考模式中可能出现的内容。快速提问:这是否会删除警告,因为将head::head2::tail 放入模式中允许 sml 知道至少有两个元素?还是这里有其他工作?
    • @Wilduck 它删除了警告,因为对于列表可以具有的每个值,都有一个与之匹配的模式。当您执行val head :: head2 :: tail = x 时,情况并非如此,因为该模式匹配对于至少有 2 个元素的列表只有一种情况。
    • 这很有意义。在 15 分钟内,你刚刚揭开了我已经花了半个小时的时间。再次感谢您。
    猜你喜欢
    • 2017-10-28
    • 1970-01-01
    • 2015-01-30
    • 1970-01-01
    • 2021-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-18
    相关资源
    最近更新 更多