我正在学习haskell,我有以下代码:
fib a b =
a : fib b (a + b)
findFibSum =
sum [x | x <- fib 1 2, mod x 2 == 0 && x < 100]
Run Code Online (Sandbox Code Playgroud)
如果我findFibSum没有发生任何事情,它只是坐在那里.不fib应该评估并返回每个项目?我猜这与懒惰评估有关.
如果我先拨打电话take,请findFibSum接受以下列表:
findFibSum $ take 100 $ fib 1 2
Run Code Online (Sandbox Code Playgroud)
它起作用了.如何制作它以便我可以检索并检查每个项目?我可以通过批量使用来逃避,take但我想首先理解这一点.
UPDATE
感谢@amalloy我终于得到了它:
findFibSum xs =
sum [x | x <- takeWhile (<4000000) xs, mod x 2 == 0]
Run Code Online (Sandbox Code Playgroud)
takeWhile 确保它一旦达到> = 4m就停止从fib中检索值.
考虑总结前100个正整数的简单问题:
sum [x | x <- [1,2..], x <= 100]
Run Code Online (Sandbox Code Playgroud)
这也不起作用.作为一个人,你知道一旦x <= 100返回False,它将永远不会再返回True,因为它会变x大.但是Haskell并不知道这一点!所以这个列表理解产生前100个整数,然后尝试101并发现它不起作用,然后尝试102并发现它不起作用......没有必要sum确保列表中没有更多元素,所以它永远不会为你返回一个数字.
你的列表理解fib 1 2有同样的问题.你可以通过调用take或takeWhile单独解决它,而不是像你在问题中演示的那样在每个元素上使用一个保护.
| 归档时间: |
|
| 查看次数: |
80 次 |
| 最近记录: |