流是通过延时求值实现的,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和foreach,其他如filter与此类似:
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_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
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
最后,看下例子:
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)
文章转自庄周梦蝶 ,原文发布时间2008-05-08
相关资源:敏捷开发V1.0.pptx