2014-10-21 61 views
1

我剛剛開始閱讀關於Haskell的一些信息,並且只編碼了一點點,這意味着我是一個完整的Haskell新手。來自Haskell Wiki的項目Euler#2解決方案

項目歐拉問題#2如下:

在Fibonacci序列中的每個新項是通過將先前的兩個術語生成。通過用1和2開始,第一10項將是:

1,2,3,5,8,13,21,34,55,89,...

通過考慮中的條款斐波納契數列的值不超過四百萬,找到偶數項的和。

我自己的第一步創建斐波納契數字是一個天真(和慢/昂貴)。失敗後,我去尋找解決方案。 Haskell Wiki has a solution。有幾個,我發現第一個非常優雅 - 但我不完全理解它。這是我的代碼(與在那裏/小謊構建分裂出來的可讀性和修修補補)

p :: Integer 
p = sum [ x | x <- takeWhile (< 4000000) fibs, even x] 

fibs :: [Integer] 
fibs = 1 : 1 : zipWith (+) fibs (tail fibs) 

main :: IO() 
main = do 
    print $ p 
    -- BEWARE print $ fibs 

當我跑這跟print $ fibs它只是沒有結束,這就是我懷疑,因爲fibs只是不斷打電話本身和中止條件是takeWhile呼叫的一部分。

僅僅看看fibs,它在我看來像函數已經返回列表的一部分,它將返回,但它仍然添加更多的元素被附加到列表,它永遠不會結束。這是什麼人會稱之爲無限列表,它可能也是我懷疑的尾遞歸? fibs函數如何工作?

更新

當然,我不是第一個問這個。 A very thourough explanation can be found elsewhere on SO

+4

此問題已在這裏得到很好的回答:http://stackoverflow.com/questions/6273621/understanding-a-recursively-defined-list-fibs-in-terms-of-zipwith – 2014-10-21 22:34:12

+0

@ErikVesteraas謝謝你的鏈接,我專門搜索與歐拉相關的問題。 – stackmagic 2014-10-22 06:45:06

回答

4

fibs函數通過將列表左移1並將其添加到自身來工作。

你告訴它,fibs = 1 : 1 : something,並從它可以告訴tail fibs = 1 : something。所以zipWith (+) fibs (tail fibs)1+1=2開頭。

現在哈斯克爾知道fibs = 1 : 1 : 2 : something,它可以繼續爲您無限地生成更多條款。