浏览 1883 次
锁定老帖子 主题:Ruby中实现stream
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-05-08
流是通过延时求值实现的,Ruby中实现stream也是可以做到,可惜就是没有尾递归优化。按照sicp,首要的是两个函数:delay和force: def mem_proc(exp) alread_run=false result=false lambda{ if !alread_run result=exp.call alread_run=true result else result end } end def force(delayed_object) delayed_object.call end def delay(exp) mem_proc(lambda{exp}) end delay函数返回延时对象,就是对于未来某个时间求值表达式的承诺;force函数以延时对象为参数,进行相应的求值工作,这里的mem_proc用于记忆已经求值过的表达式。定义stream的constructor和selector函数: def cons_stream(a,b) return a,delay(b) end def stream_car(s) s[0] end def stream_cdr(s) force(s[1]) end def stream_null?(s) s.nil? or s==[] end 用Ruby中的数组充当“粘合剂”,stream_car直接返回第一个元素,而stream_cdr需要用force求值表达式,履行承诺。另外,将空 数组[]作为the-empty-stream。再定义几个高阶函数,map、filter和foreach等: def stream_enumerate_interval(low,high) if low>high return [] else cons_stream(low,stream_enumerate_interval(low.succ,high)) end end def stream_ref(s,n) if n==0 stream_car(s) else stream_ref(stream_cdr(s),(n-1)) end end def stream_map(proc,s) if stream_null?(s) [] else cons_stream(proc.call(stream_car(s)),stream_map(proc,(stream_cdr(s)))) end end def stream_filter(pred,s) if stream_null?(s) [] elsif pred.call(stream_car(s)) cons_stream(stream_car(s),stream_filter(pred,stream_cdr(s))) else stream_filter(pred,stream_cdr(s)) end end def stream_for_each(proc,s) if stream_null?(s) :done else proc.call(stream_car(s)) stream_for_each(proc,stream_cdr(s)) end end def display_stream(s) stream_for_each(lambda{|item| puts item},s) end 最后,看下例子: puts "s:" s=stream_enumerate_interval(1,5) display_stream(s) puts "odd_s:" odd_s=stream_filter(lambda{|x| x%2==1},s) display_stream(odd_s) puts "ss:" ss=stream_map(lambda{|x|x*x},s) display_stream(ss)
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |