仮想的な無限列(11)
今回の主な修正点は…
- 累積的な処理を行うAccumulateWithを作成。
- それを元にしてSumOfとProductOfを作成。
- それを元にしてSumOfNaturalPlus, ProductOfNaturalPlusを作成。
class NilClass def to_s "_" end end Call = lambda {|f, *a| f[f, *a]} Sequence = lambda {|xs, *a| lambda {return a[0], Call[xs, *a]} } Zip = lambda {|op, s, t| Call[ lambda {|f, op, s, t| x, xs = s[] y, ys = t[] lambda { return op[x, y], f[f, op, xs, ys] } }, op, s, t ] } Walk = lambda {|n, xs, eachf, lastf| Call[ lambda {|fs, xs, n, eachf, lastf| if n > 0 y, ys = xs[] eachf[y, ys] Call[fs, ys, n - 1, eachf, lastf] else lastf[xs] end }, xs, n, eachf, lastf ] } Show = lambda {|xs| Walk[10, xs, lambda {|y, _| print "#{y}, "}, lambda {|_| puts "..." } ] } # Operators. Add = lambda {|x, y| x + y } Mul = lambda {|x, y| x * y } Power = lambda {|x, y| x ** y } # SequenceOf something. OfConstant = lambda {|s, *a| Sequence[s, a[0]]} OfNatural = lambda {|s, *a| Sequence[s, a[0] + 1]} OfFibonacci = lambda {|s, *a| Sequence[s, a[1], a[0] + a[1]]} OfGiven = lambda {|s, *a| Sequence[s, *a[1..-1]]} # Sequence -> Sequence ShiftOf = lambda {|s| x, xs = s[]; xs } UnshiftOf = lambda {|s, x| lambda {return x, s}} # Sequence -> Sequence DoubleOf = lambda {|s| Zip[Add, s, s]} PowerOf = lambda {|s| Zip[Power, s, Natural]} One = Sequence[OfConstant, 1] Two = Sequence[OfConstant, 2] Ten = Sequence[OfConstant, 10] Natural = Sequence[OfNatural, 0] NaturalPlus = ShiftOf[Natural] Fibonacci = Sequence[OfFibonacci, 0, 1] FibonacciOne = Zip[Add, Fibonacci, ShiftOf[Fibonacci]] Even = DoubleOf[Natural] Odd = Zip[Add, Even, One] Sample = Sequence[OfGiven, 3, 1, 4, 1, 5, 9] MinusSample = UnshiftOf[Sample, -1] PowerOfTwo = PowerOf[Two] PowerOfTen = PowerOf[Ten] puts "Sequence." Show[One] Show[Natural] Show[Fibonacci] Show[FibonacciOne] Show[NaturalPlus] Show[Even] Show[Odd] Show[Sample] Show[PowerOfTwo] Show[PowerOfTen] Show[MinusSample] puts "Meta sequence." SequenceOfOfs = Sequence[OfGiven, OfConstant, OfNatural, OfFibonacci, OfGiven] EachDo = lambda {|xs, action| Call[ lambda {|f, xs, action| y, ys = xs[] return unless y action[y] f[f, ys, action] }, xs, action ] } EachDo[SequenceOfOfs, lambda {|ofx| Show[Sequence[ofx, 0, 1, 2, 3]]}] puts "Accumulated sequence." AccumulateWith = lambda {|op, xs, xm| Call[ lambda {|f, op, xs, xm| y, ys = xs[] ym = op[xm, y] lambda { return ym, f[f, op, ys, ym] } }, op, xs, xm ] } SumOf = lambda {|xs| AccumulateWith[Add, xs, 0]} ProductOf = lambda {|xs| AccumulateWith[Mul, xs, 1]} SumOfNaturalPlus = SumOf[NaturalPlus] ProductOfNaturalPlus = ProductOf[NaturalPlus] Show[SumOfNaturalPlus] Show[ProductOfNaturalPlus]
実行結果です。
Sequence. 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, 5, 8, 13, 21, 34, 55, 89, ... 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ... 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, ... 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, ... 3, 1, 4, 1, 5, 9, _, _, _, _, ... 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, ... 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, ... -1, 3, 1, 4, 1, 5, 9, _, _, _, ... Meta sequence. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ... 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ... 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ... 0, 1, 2, 3, _, _, _, _, _, _, ... Accumulated sequence. 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ... 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, ...