Haskell -- 用foldr表示foldl

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 foldl using 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 id function 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.




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值