我學習Haskell和我下面的表達式上Haskell Wiki 真的困擾了我:自我參照的功能
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
我不能完全弄清楚爲什麼這個工程。
如果我應用標準柯里格邏輯(zipWith (+))
返回一個函數將列表作爲參數,然後返回另一個函數,它將另一個列表作爲參數返回一個列表(zipWith::(a -> b -> c) -> [a] -> [b] -> [c]
)。因此,fibs
是對列表的引用(尚未評估),(tail fibs)
是相同(未評估)列表的尾部。當我們嘗試評估(take 10 fibs
)時,前兩個元素綁定到0
和1
。換句話說,fibs==[0,1,?,?...]
和(tail fibs)==[1,?,?,?]
。第一次添加完成後fibs
變爲[0,1,0+1,?,..]
。同樣,在第二次加入後,我們得到[0,1,0+1,1+(0+1),?,?..]
- 我的邏輯是否正確?
- 有沒有一個更簡單的方式來解釋這一點? (來自知道Haskell編譯器對此代碼做什麼的人的任何見解?)(鏈接和引用是受歡迎的)
- 確實,這種類型的代碼僅適用於懶惰評估?
- 我做什麼評估
fibs !! 4
? - 此代碼是否假定zipWith首先處理元素? (我想應該沒有,但我不明白爲什麼不)
EDIT2:我只是發現了上述問題,並問及回答here。如果我浪費了任何人的時間,我很抱歉。
編輯:這是一個比較困難的情況下,理解(來源:Project Euler forums):
filterAbort :: (a -> Bool) -> [a] -> [a]
filterAbort p (x:xs) = if p x then x : filterAbort p xs else []
main :: Int
main = primelist !! 10000
where primelist = 2 : 3 : 5 : [ x | x <- [7..], odd x, all (\y -> x `mod` y /= 0) (filterAbort (<= (ceiling (sqrt (fromIntegral x)))) primelist) ]
注意all (\y -> x mod y /= 0)...
怎麼能指X這裏不是導致無限遞歸?
這似乎是正確的。對我而言,這似乎也很簡單 - 當你更加和Haskell一起工作時,你的大腦會開始採用這些模式,這對你也很簡單。好的開始。 – luqui 2011-06-16 05:38:56
首先,'filterAbort'和'takeWhile'是一樣的。其次,你可以通過編寫'[7,9 ..]'來避免偶數。第三,如果你使用'[5,7 ..]',那麼你不需要在你的初始列表中有'5'。最後,這個原理的原因是相當深的。這是因爲對於每個素數「p」,在「p^2」之前還有一個素數。是Lindemann定理的一個微不足道的結果(p和2p之間的素數)。 – augustss 2011-06-16 08:09:52
謝謝,8月。優化和清理你建議是有道理的。至於終止,你能否詳細說明一下?在'(\ y - > x mod y/= 0)'中綁定了'x'?我懷疑我的錯誤在於認爲它是無限的列表。如果它只有一個值(比如'7'),那麼就沒有問題了。你可否確認? – 2011-06-16 11:14:21