仮想的な無限列(12)
今回の主な修正点は…
- AccumulateWithの引数をfold風にした。
- 念願のMapを作成。
- 無意味な同一引数渡しを省略(op, eachfなど)。
- Mapを使ってFibonacciの各項が偶数か奇数かを調べてみる。
Call = lambda {|f, *a| f[f, *a]} Zip = lambda {|op, s, t| Call[ lambda {|f, s, t| x, xs = s[] y, ys = t[] lambda { return op[x, y], f[f, xs, ys] } }, s, t ] } Sequence = lambda {|xs, *a| lambda { return a[0], Call[xs, *a] } } Walk = lambda {|n, xs, eachf, lastf, nilf| Call[ lambda {|fs, xs, n| return lastf[xs] if n <= 0 y, ys = xs[] return nilf[ys] if y.nil? eachf[y, ys] Call[fs, ys, n - 1] }, xs, n ] } Show = lambda {|xs| Walk[10, xs, lambda {|y, _| print "#{y}, "}, lambda {|_| puts "..." }, lambda {|_| puts "" } ] } AccumulatedWith = lambda {|op, xm, xs| Call[ lambda {|f, xm, xs| y, ys = xs[] ym = op[xm, y] lambda { return ym, f[f, ym, ys] } }, xm, xs ] } Map = lambda {|op, xs| Call[ lambda {|f, xs| y, ys = xs[] lambda { return op[y], f[f, ys] } }, xs ] } # Operators. Add = lambda {|x, y| x + y } Mul = lambda {|x, y| x * y } Power = lambda {|x, y| x ** y } IsEven = lambda {|x| x % 2 == 0} Increment = lambda {|x| Add[x, 1]} ParityChecker = lambda {|x| IsEven[x] ? "Even(#{x})" : "Odd(#{x})" } # 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| y, ys = xs[] return unless y action[y] f[f, ys] }, xs ] } EachDo[SequenceOfOfs, lambda {|ofx| Show[Sequence[ofx, 0, 1, 2, 3]]}] puts "Accumulated sequence." SumOf = lambda {|xs| AccumulatedWith[Add, 0, xs]} ProductOf = lambda {|xs| AccumulatedWith[Mul, 1, xs]} SumOfNaturalPlus = SumOf[NaturalPlus] ProductOfNaturalPlus = ProductOf[NaturalPlus] Show[SumOfNaturalPlus] Show[ProductOfNaturalPlus] puts "Maps." Show[Map[Increment, Natural]] Show[Map[ParityChecker, Fibonacci]]
実行結果です。
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, ... Maps. 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ... Even(0), Odd(1), Odd(1), Even(2), Odd(3), Odd(5), Even(8), Odd(13), Odd(21), Even(34), ...