【问题标题】:using takeWhile AND filters with list comprehension issue使用带有列表理解问题的 takeWhile AND 过滤器
【发布时间】:2013-12-01 02:14:18
【问题描述】:

我很困惑为什么 GHCI 会无限地计算这个列表:

takeWhile (>0) [x^2 | x <- [100, 99..], odd x]

但是,此列表停止并按预期计算:

takeWhile (>0) [x | x <- [100, 99..], odd x]

我在这里缺少什么?为什么对输入进行平方会导致 takeWhile(>0) 无效?

此外,此列表按预期结束...为什么此列表会终止,而另一个则不会?

takeWhile (<1000) [x^2 | x <- [1..], odd x]

另外,如果我从第一个列表中删除奇数 x 过滤器,它会正确终止:

takeWhile (>0) [x^2 | x <- [100, 99..]]

这到底是怎么回事?

【问题讨论】:

    标签: haskell filter list-comprehension ghci


    【解决方案1】:

    因为x^2 &gt;= 0 始终为真。所以你实际上有一个无限列表,例如

    -1 * -1 = 1 > 0
    

    这只是数学。

    所以只有一种情况是x^2 &gt; 0 失败,即x = 0。当您在其中有odd x 条件时,永远不会考虑0,因此列表永远不会终止。当您删除它时,它会在 x=0 时停止。

    最后,第三个列表从100 * 100 &gt; 1000 开始平凡终止。

    【讨论】:

    • 卫生署!我觉得自己像个白痴,出于某种原因,我认为 takeWhile (>0) 已应用于 x
    • @user2293246 别担心 :) 别担心,我犯了更愚蠢的错误
    • @user2293246:这可能是一个很好的例子,说明使用列表组合符而不是理解符号更清晰。注意takeWhile (&gt;0) . map (^2) . filter oddmap (^2) . takeWhile (&gt;0) . filter odd 之间的区别。
    【解决方案2】:

    x^2 始终为&gt;0x /= 0

    您可以将列表更改为:

    [x^2 | x <- [100, 99..], odd x, x > 0]
    

    【讨论】:

    • 这永远不会结束。在 x 达到 0 后,它将继续尝试更低的数字,但永远不会打印任何内容,因为它们都不小于 0。您应该改为将其更改为 [x^2 | x &lt;- takeWhile (&gt;0) [100,99..], odd x],虽然它有点麻烦。
    猜你喜欢
    • 2015-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-20
    • 1970-01-01
    • 2019-03-19
    • 2011-03-02
    相关资源
    最近更新 更多