2013-02-06 39 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'是严格的?对,但是从某种意义上说,颠倒名单本身并不是一种“廉价操作”。 –