【问题标题】:Non-exhaustive patterns error when recursion a list [duplicate]递归列表时出现非详尽模式错误[重复]
【发布时间】:2019-05-08 09:11:50
【问题描述】:

我收到以下错误,如果我尝试执行我的 x_length 函数,那应该测量给定列表的长度:

例外:test.hs:2:1-36:函数 x_length 中的非详尽模式

我使用Prelude>:l test.hs 将我的test.hs 文件加载到ghci 中。

x_length函数的实现是(在test.hs文件内):

x_length :: [Int] -> Int
x_length (x:xs) = 1 + x_length xs

我已经想通了,它必须与加载test.hs 文件有关,但我还没有想通,如何解决这个问题。

我使用x_length [1,2,3,4] 进行的实际函数调用。

【问题讨论】:

  • 提示:(x:xs) 匹配哪些列表?如果仍有疑问,请尝试“手动”评估您的功能以获得合理的简短列表,然后看看会发生什么
  • 您的代码明显的逻辑问题是x_length 从不返回值。它总是调用自己(它再次调用自己(它再次调用自己(which ...)))。
  • 如果你到达列表的end,所以它是[]而不是(x:xs)
  • @RobinZigmond 对我来说都是 _|_。
  • 启用警告会使 GHC 报告错过的[] 案例。我建议始终启用警告。

标签: haskell recursion


【解决方案1】:

再看看你的定义:

x_length :: [Int] -> Int
x_length (x:xs) = 1 + x_length xs

现在让我们评估一下x_length [1,2,3,4]

x_length [1,2,3,4]
x_length (1:2:3:4:[])
= 1 + x_length (2:3:4:[])
= 1 + 1 + x_length (3:4:[])
= 1 + 1 + 1 + x_length (4:[])
= 1 + 1 + 1 + 1 + x_length []

但是您的定义没有匹配[] 的情况!它有一个匹配(x:xs) 的大小写,但这需要列表中的至少一个元素。因此错误:“非详尽模式”;也就是说,有一种情况与模式不匹配。

要解决此问题,您需要一个额外的箱子,用于x_length []。所以你的定义看起来像这样:

x_length :: [Int] -> Int
x_length [] = _something
x_length (x:xs) = 1 + x_length xs

给你一个小练习:_something 应该是什么? (提示:空列表的长度是多少?)如果您需要,我会将答案放在剧透引号中;将鼠标悬停在它上面以显示答案。

x_length [] = 0

【讨论】:

  • 感谢您的详细解答。通过我发现的评论部分,我必须检查空列表案例。但我不知道,我可以简单地在函数的实际实现之上声明第二种情况x_length [] = 0。这种方法是被视为一个功能还是这两个不同的功能?抱歉,我是 Haskell 的新手。非常感谢。
  • @TabmanRekoj 这是一个函数,它根据与输入匹配的模式“分支”为多个定义之一:将使用匹配的最顶层模式。这可以被认为类似于数学中的分段函数。实际上,它相当于在函数定义中直接使用case 语句。
  • @TabmanRekoj 详细说明 DarthFennec 的评论:在 Haskell 编译器中,f case1 = _something; f case2 = _somethingelsef x = case x of { case1 -> _something; case2 -> _somethingelse } 被处理相同
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多