2013-02-06 38 views
4

學習Haskell,我發現foldl創建thunk可能導致堆棧崩潰,因此最好使用從Data.List。爲什麼它只是foldl,而不是例如foldrHaskell thunks - foldl vs foldr

感謝

+4

是[這個答案](http://stackoverflow.com/questions/1292212/how-to-solve-stack-space-overflow-in-haskell/1292853#1292853),特別是前幾句話,任何幫幫我? – 2013-02-06 10:21:07

+0

一些關於摺疊的Haskell維基頁面:[Fold](http://www.haskell.org/haskellwiki/Fold)和[Foldr_Foldl_Foldl'](http://www.haskell.org/haskellwiki/Foldr_Foldl_Foldl') –

回答

10

沒有必要爲foldr',因爲你可以自己造成的影響。

這是爲什麼:考慮foldl f 0 [1,2,3]。這擴大到f (f (f 0 1) 2) 3,所以當你得到任何東西返回工作,(f 0 1)(f (f 0 1) 2)必須創建thunk。如果你想避免這種情況(通過在繼續之前評估這些子表達式),你必須指示foldl爲你做 - 也就是foldl'

foldr,事情是不同的。你從foldr f 0 [1, 2, 3]得到的是f 1 (foldr f 0 [2, 3])(括號中的表達式是thunk)。如果你想評估f的外部應用程序(的一部分),現在可以這樣做,而不需要首先創建線性數目的thunk。

但是總的來說,在查看第二個參數之前,您正在使用foldr的惰性函數f,它已經可以執行某些操作(例如生成列表構造函數)。

使用具有嚴格f(例如(+))的foldr具有將所有應用程序放入堆棧直到到達列表末尾的不利影響;顯然不是你想要的,而不是一個看起來不錯的foldr'可以提供幫助的情況。

+1

有人可以在翻轉的列表中翻轉翻轉的f。 – Ingo

+0

你是說如果'f'是嚴格的?對,但是從某種意義上說,顛倒名單本身並不是一種「廉價操作」。 –