论坛首页 编程语言技术论坛

Ruby中实现stream

浏览 1881 次
精华帖 (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)
 

 

论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics