负暄琐话

我的email: rot47('649@ 6(hF+`hd"w=92vhG{>}G3"@l M >:>6?4@56 \F')

囧囧ID:g9yuayon
858909次访问,排名32好友20人,关注者24
姓名:g9yuayon
前世:夜郎国厚脸皮神棍
魅力指数:0
名气:1
宠物:一只从来不对生人叫的看门狗
g9yuayon的文章
原创 244 篇
翻译 4 篇
转载 48 篇
评论 849 篇
g9的公告
最近评论
icoding:恩。这年头牛人也不好混啊
icoding:离开IBM也不和咱说一下
LINSOSO:“每头成员”里面的这个“头”字用得是那么地经典。。。
xingranliuyun:老大总是能用简单的话语点起大家无限的激情。

看了这篇文章我有一种燃的感觉。

愿爱伴老大一路前行!
xingranliuyun:老大加油,相信凭你的实力没啥问题。
文章分类
收藏
    相册
    旅游
    计算机科学
    Lambda the Ultimate
    软件开发
    Reddit编程专栏(RSS)
    正在读的书
    存档
    订阅我的博客
    XML聚合  FeedSky

    转载 吃了大力丸的Ruby:unfold的实现收藏

    新一篇: WEB开发的技术 | 旧一篇: Pina Colada Song现实版

    最近奇忙。从早到晚工作。别说写博客,连读博客都 没有时间。虽然一直想八卦一下JavaScript那浓眉大眼的也背叛革命了这件大事,却抽不出空。不过看到这么精彩的代码,还是忍不住转载。

    起因是这样的:大家都熟悉fold函数,也就是Ruby里常用的inject()函数:给出起始值,把某个Collection里的值叠加上去。比如说,给出起始值0,累加数组[1, 2, 3, 4, 5]: 

    [1, 2, 3, 4, 5].inject(0){|sum, n| sum = sum + n}
    

    有了fold,便有相反的unfold:把单个的对象映射到Collection上。比如说 

    10.unfold { |n| n-1 unless n == 1 }.inspect => [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
    10.class.unfold(&:superclass).inspect => [Fixnum, Integer, Numeric, Object]

    它的实现也出奇地漂亮:通过递归把unfold调用改写为数组操作。颇有term rewriting系统的风范: 

    class Object
    def unfold &block
    block.call(self).unfold(&block).unshift(self)
    end
    end


    class NilClass
    def unfold &block
    []
    end
    end
    用例子最容易说明这段实现的惊艳之处。我们手工执行3.unfold{|n| n - 1 unless n ==1}:
    1. 我们用block指代上式里的{|n| n - 1 unless n == 1}。根据unfold的定义,上式变为block.call(3).unfold(&block).unshift(3)
    2. 执行block.call(3)得到2,于是我们得到2.unfold(&block).unshift(3)
    3. 根据定义,我们得到block.call(2).unfold(&block).unshift(2).unshift(3)
    4. 执行block.call(2),我们得到1.unfold(&block).unshift(2).unshift(3)
    5. 再根据定义,我们得到block.call(1).unfold(&block).unshift(1).unshift(2).unshift(3)
    6. block.call(1)的结果是nil,所以我们得到nil.unfold(&block).unshift(1).unshift(2).unshift(3)
    7. nil早准备好了unfold的定义,于是我们得到[].unshift(1).unshift(2).unshift(3),也就是[3, 2, 1]了。

    现在胃口被吊起来的老大们可以看这里的讨论了。

     

    发表于 @ 2007年11月08日 14:52:00|评论(loading...)|编辑

    评论

    #Googol 发表于2007-11-08 02:51:01  IP: 10.194.65.*
    好久没见老大出手了。

    不过……怎么我这里显示的代码没有换行呢?IoCCC?
    2007-11-08 10:37:44作者回复
    奇怪,在后台编辑器里看好好的。我用Vim把代码转换成加亮的HTML,然后直接拷贝的转换结果。可能拷贝后哪里出错了。现在应该已经改好了。谢谢。
    #FrankYue 发表于2007-11-08 04:29:23  IP: 125.171.139.*
    楼上的,几乎每天都来看的BLOG,就是不见更新啊,呵呵。现在好了,开始更新了。
    2007-11-08 14:39:49作者回复
    谢谢。要忙到明年初了。有心杀贼,无力回天的说。:-)
    #chenxiaoshun 发表于2007-11-09 12:51:00  IP: 210.76.202.*
    g9同学,你终于更新了啊,太好了。期待你忙完之后出更多更好的文章,加油!
    #interhanchi 发表于2007-11-11 05:55:00  IP: 125.77.224.*
    csdn的blog真郁闷,opera支持的真差,只能用firefox来回复了。

    js2.0,看起来真是恐怖,我仿佛又看见了java....

    #ffyd2000 发表于2007-11-22 04:50:53  IP: 220.166.202.*
    页面拖回家消化
    发表评论  


    当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
    Csdn Blog version 3.1a
    Copyright © g9