Ruby中实现stream

    流是通过延时求值实现的,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)



你可能感兴趣的:(Ruby中实现stream)