仮想的な無限列(3)
昨日の続きで、無限列を考えています。zipの意味を変えて少し整理しました。
class Sequence < Proc def self.create(*a, &block) self.new(&block).define(*a) end def define(*a) lambda { return a[0], self.call(self, *a) } end end class Proc def to_s(n=10) return "..." if n == 0 x, xs = self.call() x.to_s + ", " + xs.to_s(n - 1) end def drop(n) return self if n == 0 _, s = self.call() s.drop(n - 1) end def zip(s, t) x, xs = s.call() y, ys = t.call() lambda { return self.call(x, y), self.zip(xs, ys) } end end puts (Ones = Sequence.create(1) {|f, a| f.define(a) }) puts (Natural = Sequence.create(0) {|f, a| f.define(a + 1)}) puts (NaturalPlus = Natural.drop(1)) puts (Fibonacci = Sequence.create(1, 1) { |f, a, b| f.define(b, a + b) }) Add = lambda {|a, b| a + b} puts (Evens = Add.zip(Natural, Natural)) puts (Odds = Add.zip(Evens, Ones))
実行結果です。
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ... 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ... 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ... 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ... 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, ... 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, ...
ああ楽しい。
追記:jitteさんからのご指摘で、constantのf.define(a, a)をf.define(a)に修正しました。