Last active
November 13, 2018 11:04
-
-
Save divs1210/cc02a388e1f2f59a86b60271f7e46750 to your computer and use it in GitHub Desktop.
Lazy Seqs in Ruby
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Abstract Class | |
# ============== | |
class ISeq | |
def first | |
end | |
def rest | |
end | |
def [](idx) | |
seq = self | |
idx.times { | |
seq = seq.rest | |
} | |
seq.first | |
end | |
def to_s | |
ret = "[" | |
seq = self | |
while seq != nil | |
ret += seq.first.to_s + ", " | |
seq = seq.rest | |
end | |
ret[-2..-1] = "]" | |
ret | |
end | |
end | |
# Linked List | |
# =========== | |
class Cell < ISeq | |
def initialize(head, tail) | |
@head = head | |
@tail = tail | |
end | |
def first | |
@head | |
end | |
def rest | |
@tail | |
end | |
end | |
c_list = Cell.new(1, Cell.new(2, Cell.new(3, nil))) | |
puts "Linked List: #{c_list}" | |
# Lazy List | |
# ========= | |
class LazySeq < ISeq | |
def initialize(head, rest_fn) | |
@head = head | |
@rest_fn = rest_fn | |
end | |
def first | |
@head | |
end | |
def rest | |
@rest_fn.call | |
end | |
end | |
l_list = LazySeq.new 1, ->() { LazySeq.new 2, ->() { LazySeq.new 3, ->() { nil }} } | |
puts "Lazy List: #{l_list}" | |
# Lazy methods for ISeq | |
# ===================== | |
ISeq.class_eval do | |
def take(n) | |
if n > 0 | |
LazySeq.new first, ->() do | |
rest.take n-1 | |
end | |
else | |
nil | |
end | |
end | |
def map(f) | |
LazySeq.new f.call(first), ->() do | |
tail = rest | |
if tail | |
tail.map f | |
else | |
->() { nil } | |
end | |
end | |
end | |
end | |
# Utils | |
# ===== | |
def iterate(f, initial) | |
LazySeq.new initial, ->() { | |
iterate f, f.call(initial) | |
} | |
end | |
wholes = iterate ->(x) { x+1 }, 0 # whole numbers | |
evens = wholes.map ->(x) { 2*x } # even numbers | |
puts "Mapped Lazy List: #{evens.take 5}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment