仮想的な無限列(5)
仮想的な無限列(4)では、ShowとDropが似ていたので、無限列のはじめからn歩あるくWalkを作って統合しました。
Call = lambda {|f, *a| lambda { f.call(f, *a) } } Walk = lambda {|n, xs, eachf, lastf| Call.call( lambda {|fs, xs, n, eachf, lastf| if n > 0 y, ys = xs.call() eachf.call(y, ys) fs.call(fs, ys, n - 1, eachf, lastf) else lastf.call(xs) end }, xs, n, eachf, lastf ) } Show = lambda {|xs| Walk.call(10, xs, lambda {|y, ys| print "#{y}, "}, lambda {|ys| puts "..." } ).call() } Drop = lambda {|xs, n| Walk.call(n, xs, lambda {|y, ys|}, lambda {|ys| ys} ).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)) Show.call(Drop.call(Sequence.call(Natural, 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, ...