Haskell -- 用foldr表示foldl
2012-04-16 11:38
267 查看
Real World Haskell的哥仨写到foldr表示foldl时:
" Understanding foldl in terms of foldr.
If you want to set yourself a solid challenge, try to follow the above definition of
ghci (so that you can find out what the
请准备好阿司匹林,一打纸,一只新笔,谢谢。
书中没给答案和解释,引得众人吐槽不已,后来
Don Stewar (上书哥仨之一)在stackoverflow
http://stackoverflow.com/questions/6172004/writing-foldl-using-foldr
上回了篇长文。
最早Graham Hutton在 A tutorial on the universality and expressiveness of fold 中介绍了这个trick:
foldl f acc xs = foldr (\x g s -> g (f s x)) id xs acc
或者
myFoldl :: (a -> b -> a) -> a -> [b] -> a
myFoldl f z xs = foldr step id xs z
where step x g a = g (f a x)
以下以myFoldl为例(个人更喜欢第一个,表达更清晰),继续之前,需要对foldl和foldr熟悉。
fold是控制结构的函数,参数 f 是干活函数,进行实际计算。相当于PM与码农。
现在 foldl 带领 f 开发出产品 a,即 a = foldl f z xs,
另一pm foldr不干了,要求在他的指导下,开发出同 foldl 功能及体验一样的产品。
两者框架不同,要求结果一致,码农表示压力很大。
看来不能像f一样只傻干活,也需要进行结构调整,以满足 foldr变性的需求。
于是 step,
一方面雇佣 f 干活, 达到功能相同;
一方面在foldr的架构下,在进行重组,达到体验一致。
myFoldl :: (a -> b -> a) -> a -> [b] -> a
myFoldl f z xs = foldr step id xs z
where step x g a = g (f a x)
步骤如下:
foldr step id (x:xs) z -- apply foldr
= step x (foldr step id xs) z -- apply step
= (foldr step id xs) (f z x) -- 'f z x' updates accumulator just like foldl's 'f z s'
go on ...
.......
.......
-- at last, encounter the empty list. foldr _ acc [] = acc
= (foldr step id []) sth
= id sth
= sth
It simulates the foldl computation process, namely, every time it controls 'f'
applying to the accumulator and an element of the list as the new accumulator.
It is not that hard, right ? Hope your pen still has ink to remain your next re-practice of foldl & foldr.
In my experience, you should at least do it three times then you may say I really know it.
" Understanding foldl in terms of foldr.
If you want to set yourself a solid challenge, try to follow the above definition of
foldlusing
foldr. Be warned: this is not trivial! You might want to have the following tools at hand: some headache pills and a glass of water,
ghci (so that you can find out what the
idfunction does), and a pencil and paper. "
请准备好阿司匹林,一打纸,一只新笔,谢谢。
书中没给答案和解释,引得众人吐槽不已,后来
Don Stewar (上书哥仨之一)在stackoverflow
http://stackoverflow.com/questions/6172004/writing-foldl-using-foldr
上回了篇长文。
最早Graham Hutton在 A tutorial on the universality and expressiveness of fold 中介绍了这个trick:
foldl f acc xs = foldr (\x g s -> g (f s x)) id xs acc
或者
myFoldl :: (a -> b -> a) -> a -> [b] -> a
myFoldl f z xs = foldr step id xs z
where step x g a = g (f a x)
以下以myFoldl为例(个人更喜欢第一个,表达更清晰),继续之前,需要对foldl和foldr熟悉。
fold是控制结构的函数,参数 f 是干活函数,进行实际计算。相当于PM与码农。
现在 foldl 带领 f 开发出产品 a,即 a = foldl f z xs,
另一pm foldr不干了,要求在他的指导下,开发出同 foldl 功能及体验一样的产品。
两者框架不同,要求结果一致,码农表示压力很大。
看来不能像f一样只傻干活,也需要进行结构调整,以满足 foldr变性的需求。
于是 step,
一方面雇佣 f 干活, 达到功能相同;
一方面在foldr的架构下,在进行重组,达到体验一致。
myFoldl :: (a -> b -> a) -> a -> [b] -> a
myFoldl f z xs = foldr step id xs z
where step x g a = g (f a x)
步骤如下:
foldr step id (x:xs) z -- apply foldr
= step x (foldr step id xs) z -- apply step
= (foldr step id xs) (f z x) -- 'f z x' updates accumulator just like foldl's 'f z s'
go on ...
.......
.......
-- at last, encounter the empty list. foldr _ acc [] = acc
= (foldr step id []) sth
= id sth
= sth
It simulates the foldl computation process, namely, every time it controls 'f'
applying to the accumulator and an element of the list as the new accumulator.
It is not that hard, right ? Hope your pen still has ink to remain your next re-practice of foldl & foldr.
In my experience, you should at least do it three times then you may say I really know it.
相关文章推荐
- haskell笔记二:foldl与foldr的效率(惰性计算与尾递归)
- Haskell foldl, foldr, foldl'
- haskell笔记一:用foldr实现foldl
- haskell的foldl,foldr
- 使用Haskell计算一个正整数二进制表示中最大的连续的1的个数
- haskell中类型的等价表示(1)–Product
- haskell中类型的等价表示(2)–Sum
- IEC61850之TrgOps报告触发选项各bit位表示含义
- HDU-2609 How many (最小表示法)
- hdu 2609 最小(大)表示法解决同构问题
- poj1509(最小表示法)
- 程序的机器级表示
- 数据与python表示
- Microsoft Office Word 遇到问题需要关闭。我们对此引起的不便表示抱歉。
- 在表格中截取部分显示的数据,其他部分用...表示
- 小数在计算机的表示
- 打印数据的二进制表示
- 单循环链表(使用尾指针表示)
- int,long型表示的整数范围
- UVA 11732 —— 左儿子右兄弟表示法&&Tire