簡體   English   中英

文件夾不返回無限列表

[英]foldr not returning with an infinite list

我已閱讀https://www.haskell.org/haskellwiki/Foldl_as_foldr和其他一些有關foldl和foldr之間差異的博客文章。 現在,我嘗試使用文件夾將斐波那契數列編寫為無限列表,並提出了以下解決方案:

fibs2 :: [Integer]
fibs2 = foldr buildFibs [] [1..]
  where
    buildFibs :: Integer -> [Integer] -> [Integer]
    buildFibs _ [] = [0]
    buildFibs _ [0] = [1,0]
    buildFibs _ l@(x:s:z) = (x + s):l

但是當我take 3 fibs2 ,該函數不會返回。 我認為文件夾遞歸可以在這些情況下與無限列表一起使用。 為什么這不適用於我的解決方案?

問自己:哪個斐波那契數字將是列表中的第一個? 我對您的代碼的理解是,該問題的答案是“最大的問題”(概念上,每次buildFibs迭代buildFibs在結果列表的buildFibs添加一個稍大的數字)。 由於有無數斐波納契數,因此計算需要一段時間!

這是進行方程式推理的好方法:

fibs2 = foldr buildFibs [] [1..]

foldr f z [] = z
foldr f z (x:xs) = f x (foldr f z xs)

foldr buildFibs [] [1..] =
    buildFibs 1 (foldr buildFibs [] [2..]) =
    buildFibs 1 (buildFibs 2 (foldr buildFibs [] [3..])) =
    buildFibs 1 (buildFibs 2 (buildFibs 3 (foldr buildFibs [] [4..]))) =
    ...

我希望現在您可以看到問題所在: foldr在返回之前試圖遍歷整個列表。 如果我們改用foldl會怎樣?

foldl f z [] = z
foldl f z (x:xs) = foldl f (f z x) xs

buildFibs' = flip buildFibs

foldl buildFibs' [] [1..] =
    foldl buildFibs' (buildFibs 1 []) [2..] = 
    foldl buildFibs' [0] [2..] =
    foldl buildFibs' (buildFibs 2 [0]) [3..] =
    foldl buildFibs' [0,1] [3..] =
    foldl buildFibs' (buildFibs 3 [0,1]) [4..] =
    foldl buildFibs' (0+1 : [0,1]) [4..] =
    foldl buildFibs' [1,0,1] [4..] =
    foldl buildFibs' (buildFibs 4 [1,0,1]) [5..] =
    foldl buildFibs' (1+0 : [1,0,1]) [5..] =
    foldl buildFibs' [1,1,0,1] [5..] =
    foldl buildFibs' (buildFibs 5 [1,1,0,1]) [6..] =
    foldl buildFibs' [2,1,1,0,1] [6..] =
    -- For brevity I'll speed up the substitution
    foldl buildFibs' [3,2,1,1,0,1] [7..] =
    foldl buildFibs' [5,3,2,1,1,0,1] [8..] =
    foldl buildFibs' [8,5,3,2,1,1,0,1] [9..] =
    ...

因此,如您所見,您實際上可以使用buildFibsfoldl計算斐波那契數,但是不幸的是,您向后建立了一個無限的列表,您將永遠無法計算列表中的特定元素,因為foldl永遠不會終止。 但是,您可以計算有限數量的它們:

> take 10 $ foldl buildFibs' [] [1..10]
[34,21,13,8,5,3,2,1,1,0]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM