Skip to content

Instantly share code, notes, and snippets.

@odf
Created October 7, 2011 12:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save odf/1270196 to your computer and use it in GitHub Desktop.
Save odf/1270196 to your computer and use it in GitHub Desktop.
Fun with lazy sequences in Ruby
class Seq
attr_reader :first
def initialize(first, &rest)
@first = first
@rest = rest
end
def rest
@rest = @rest.call()
class << self; def rest; @rest end end
@rest
end
def self.fromArray(a, i = 0)
Seq.new(a[i]) { fromArray a, i+1 } if i < a.length
end
def each(&f)
s = self
while not s.nil?
f.call(s.first)
s = s.rest
end
end
def subseqs
Seq.new(self) { rest.subseqs unless rest.nil? }
end
def take(n)
Seq.new(self.first) { rest.take n-1 unless rest.nil? } if n > 0
end
def map(&f)
Seq.new(f.call self.first) { rest.map(&f) unless rest.nil? }
end
def to_a
a = []
each { |x| a.push x }
a
end
def to_s
map(&:to_s).to_a.join ' -> '
end
def consec(n, &f)
subseqs.map { |s| s.take(n).to_a }
end
end
if __FILE__ == $0
s = Seq.fromArray %w{the quick brown fox}
puts s.subseqs.map { |sub| sub.rest.nil? ? sub.first.upcase : sub.first }
puts Seq.fromArray([1,2,3,4,5]).consec(3)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment