簡體   English   中英

為什么xs ++ acc在無限列表上使用foldr時有效,但是acc ++ xs卻沒有?

[英]Why xs ++ acc works when using foldr on an infinite list, but acc ++ xs doesn't?

我知道問題標題可能會產生誤導,因為我沒有在這里連接任何無限列表。 隨意提出更合適的東西。

以下是Prelude使用foldrcycle函數的工作實現:

fold_cycle :: [a] -> [a]
fold_cycle xs = foldr step [] [1..]
    where step x acc = xs ++ acc

如果我們將++的操作數切換為acc ++ xs ,則此函數不再起作用。 它會產生一個堆棧溢出,根據我的理解,這是嘗試生成一個永無止境的表達式以供以后評估的結果。

我無法理解這背后的原因是什么。 我的理由是,無論操作數的順序如何, foldr都應該評估step一次,產生新的累加器並在必要時再次評估step函數。 為什么會有區別?

如果沒有強制, foldr根本不評估累加器。 fold_cycle正好工作,因為它不一定評估acc

fold_cycle [1, 2]

減少到

[1, 2] ++ ([1, 2] ++ ([1, 2] ++ ([1, 2] ++ ...

這允許我們評估結果的前綴,因為++允許我們遍歷第一個參數而不評估第二個參數。

如果我們使用step _ acc = acc ++ xs ,則上面表達式中的括號與左側而不是右側相關聯。 但由於我們有無限多的附加,表達式最終會像這樣:

((((((((((((((... -- parentheses all the way down

直觀地說,我們必須跨過無數個括號來檢查結果列表的第一個元素。

暫無
暫無

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

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