学习Haskell,我发现foldl
创建thunk可能导致堆栈崩溃,因此最好使用从Data.List
。为什么它只是foldl
,而不是例如foldr
?Haskell thunks - foldl vs foldr
感谢
学习Haskell,我发现foldl
创建thunk可能导致堆栈崩溃,因此最好使用从Data.List
。为什么它只是foldl
,而不是例如foldr
?Haskell thunks - foldl vs foldr
感谢
没有必要为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'
可以提供帮助的情况。
有人可以在翻转的列表中翻转翻转的f。 – Ingo
你是说如果'f'是严格的?对,但是从某种意义上说,颠倒名单本身并不是一种“廉价操作”。 –
是[这个答案](http://stackoverflow.com/questions/1292212/how-to-solve-stack-space-overflow-in-haskell/1292853#1292853),特别是前几句话,任何帮帮我? – 2013-02-06 10:21:07
一些关于折叠的Haskell维基页面:[Fold](http://www.haskell.org/haskellwiki/Fold)和[Foldr_Foldl_Foldl'](http://www.haskell.org/haskellwiki/Foldr_Foldl_Foldl') –