【问题标题】:A function for checking if a list's length is larger than a given number gets into an infinite loop when entering an infinite list as a parameter用于检查列表长度是否大于给定数字的函数在输入无限列表作为参数时进入无限循环
【发布时间】:2021-12-10 21:56:42
【问题描述】:

我有以下功能:

longer x y | y < 0 = True
           | length x > y = True
           | length x <= y = False

其中x[a] 类型,yInt 类型。

此函数适用于有限列表,但在我输入无限列表时不会计算并进入无限循环。我应该尝试什么其他方法?

我的尝试:

对于longer [1..] 10,我将从第一个值开始,将列表的长度(所以[1])与10进行比较,如果长度更小,则继续前两个值,比较列表的(所以[1,2])长度为10,看到该语句仍然是错误的,继续前三个值等。我认为递归可能是解决我的这个问题的正确方法。

【问题讨论】:

  • 提示:如何检查列表的长度是否大于 0?你真的需要length吗?这如何帮助解决给定的问题?
  • length 在无限列表上发散,所以你不能使用它。您可以尝试显式模式匹配和递归——这种方法应该是列出练习的默认方法,因为大多数都可以通过这种方式解决。这个任务确实可以这样解决。或者,可以尝试将dropnull 组合在一起——两者都可以在无限列表上正常工作。
  • 好的开始,但是“然后转到前两个值,将列表的(所以[1,2])长度与10 进行比较”是多余的工作。那时你已经勾选了1,不是吗?
  • 这几乎是正确的解决方案,只是您需要记住何时弹出了前导x,这也会影响您要比较的长度。而且,length [x] 永远只是 1
  • 我认为当y &lt; 0 时,我更希望这个函数返回True 而不是错误。毕竟,每个列表的长度肯定比任何负数都大!

标签: haskell infinite-loop


【解决方案1】:

你看,如果一个列表被传递给一个函数,它可以有两种形状,要么是空的

length [] y = undefined

或者它由一个值和列表的其余部分组成

length (x:xs) y = undefined

这是仅有的两种情况,因为列表数据类型是这样定义的:

Prelude> :info []
data [] a = [] | a : [a]    -- Defined in `GHC.Types'

因此,您已经通过将原始问题分成两个较小的部分而取得了进展。而且您可能能够实现第一种情况(空列表)。但请注意,您在第二种情况下也取得了进展。虽然之前您对原始列表 x(最好命名为 xs)一无所知,但您现在知道原始列表的形状为 x : xs。这里x 是列表的第一项,xs 是剩余的列表。特别是您现在知道,通过的列表的大小至少为 1。不管剩余的列表 xs 是什么,这都是正确的。你现在可以实施了吗

length (x:_) 0 = undefined

如果是,那y不为零的情况呢:

length (x:xs) y = undefined

你能问一个关于xsy 而不是x:xsy 的新问题吗?请记住,您知道xsx : xs 短一项。

【讨论】:

  • 感谢有用的回答,完成的代码在这里:longerThan [] y = False longerThan (x:_) 0 = True longerThan (x:xs) y | y &lt; 0 = error "negative value" | otherwise = longerThan (xs) (y-1)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-06
  • 1970-01-01
  • 2019-11-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多