仮想的な無限列(4)
仮想的な無限列シリーズです。オブジェクト指向ベースではなく、関数ベースを試してみます。
SelfCall = lambda {|f, *a| lambda { f.call(f, *a) } } Show = lambda {|xs| SelfCall.call( lambda {|f, xs, n| if n == 0 puts "..." else y, ys = xs.call() print "#{y}, " f.call(f, ys, n - 1) end }, xs, 10 ).call() } Sequence = lambda {|f, *a| lambda { return a[0], f.call(f, *a) } } Constant = lambda {|f, a| Sequence.call(f, a)} Natural = lambda {|f, a| Sequence.call(f, a + 1)} Fibonacci = lambda {|f, a, b| Sequence.call(f, b, a + b)} Show.call(Sequence.call(Constant, 1)) Show.call(Sequence.call(Natural, 0)) Show.call(Sequence.call(Fibonacci, 0, 1)) Drop = lambda {|xs, n| SelfCall.call( lambda {|f, xs, n| if n == 0 xs else y, ys = xs.call() f.call(f, ys, n - 1) end }, xs, n ).call() } NaturalPlus = Drop.call(Sequence.call(Natural, 0), 1) Show.call(NaturalPlus)
実行結果です。順番に定数列、0オリジンの自然数、0オリジンのフィボナッチ数列、それから1オリジンの自然数です。
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ... 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ... 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ... 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...