获取haskell中的每个fibbonacci值

时间:2015-06-16 03:49:52

标签: haskell fibonacci

我正在学习haskell并且我有以下代码:

fib a b =
  a : fib b (a + b)

findFibSum =
  sum [x | x <- fib 1 2, mod x 2 == 0 && x < 100]

如果我跑findFibSum没有任何反应,它只是坐在那里。不应该评估fib并返回每个项目吗?我猜测这与懒惰评估有关。

如果我先拨打take并让findFibSum接受如下所列的列表:

findFibSum $ take 100 $ fib 1 2

它起作用了。如何制作它以便我可以检索并检查每个项目?我可以通过批量使用take来逃避,但我想首先理解这一点。

更新

感谢@amalloy,我终于得到了它:

findFibSum xs =
  sum [x | x <- takeWhile (<4000000) xs, mod x 2 == 0]

takeWhile确保一旦获得&gt; = 4m就停止从fib中检索值。

1 个答案:

答案 0 :(得分:6)

考虑总结前100个正整数的简单问题:

sum [x | x <- [1,2..], x <= 100]

这也不起作用。作为一个人,你知道一旦x <= 100返回False,它将永远不会再返回True,因为x变大了。但是Haskell并不知道这一点!因此,这个列表理解产生前100个整数,然后尝试101并发现它不起作用,然后尝试102并发现它不起作用...... sum无法确定没有列表中的更多元素,因此它永远不会为您返回一个数字。

您对fib 1 2的列表理解存在同样的问题。您可以分别致电taketakeWhile来解决问题,而不是在每个元素上使用警示,如您在问题中所示。