Sunday, December 21, 2008

Lazy List in Ruby

A Lazy List is a list that evaluates and constructs it self as it is used. Very much a functional language concept.

class LazyList
attr_accessor :head, :tail


def initialize(h, t)
@head = h
@tail = t
end

def nil?
return head.nil?
end

def self.null
return LazyList.new(nil, nil)
end

def self.seq(start, finish)
if start > finish
return LazyList.null
else
return LazyList.new(start, proc { seq( start + 1, finish) })
end
end

def self.infseq(start)
return LazyList.new(start, proc { infseq( start + 1 ) })
end


def self.constList(val)
return LazyList.new(val, proc { constList(val) })
end

def self.boolseq(start)
return LazyList.new(start, proc { boolseq(!start) })
end


def self.filter(listcontrol, listdata)
if listcontrol.nil? || listdata.nil?
return LazyList.new
end

if listcontrol.head
LazyList.new(listdata.head, proc { filter(listcontrol.tail.call, listdata.tail.call)})
else
filter(listcontrol.tail.call, listdata.tail.call)
end

end

def Nth(n)
return if nil?

if n == 0
return head
else
tail.call.Nth(n-1)
end
end

def self.filter_check(data, check)
if nil?
return
end

if data.head % check != 0
LazyList.new(data.head, proc { filter_check(data.tail.call, check)})
else
filter_check(data.tail.call, check)
end

end

def self.prime_help(list)
return LazyList.new(list.head, proc { prime_help(filter_check(list.tail.call, list.head))})
end

def self.primes
return prime_help(infseq(2))
end

def printN(n)
if nil?
return
end

puts head
if n >= 0 && !tail.nil?
tail.call.printN(n-1)
end
end
end

l = LazyList.seq(2, 8)
l.printN(34)
l = LazyList.infseq(3)
l.printN(34)
b = LazyList.boolseq(false)
b.printN(6)
f = LazyList.filter(b,l)
f.printN(6)

a = LazyList.primes()
a.printN(8)
puts "nth #{f.Nth(2)}"

No comments: