C# の例(13)
続いて「仮想サーバー」の NumbersGenerator クラスについても考えていきます。時刻 time を導入して、時刻 time ごとに「仮想サーバー」が存在すると考えます。そして求める桁と時刻 time が対応していると考えます。ある桁を計算するときは、その桁に対応している時刻の「仮想サーバー」でその桁まで計算することにします。参照透過性がある場合は同じ計算を一度しか行わないようにすることができるので、そのような処理系であればこのように計算しても「仮想サーバー」が状態を持っている場合とやっていることは同じということになります。
internal class NumbersGenerator { public NumbersGenerator(int time) { generator = GenerateDecimal(time).GetEnumerator(); } private readonly IEnumerator<int> generator; public int GetNextDecimalDigit() { generator.MoveNext(); return generator.Current; } // 時刻 time のときの値を返すバージョン public IEnumerable<int> GenerateDecimal(int time) { IEnumerable<int> RepeatByTime(Numbers nums, int t, int time) { if (t < time) { Tuple<int, Numbers> d_ns = nums.GetNextDecimalDigitAndNumbers(); return ImmutableList<int>.Empty.Add(d_ns.Item1).AddRange(RepeatByTime(d_ns.Item2, t + 1, time)); } return ImmutableList<int>.Empty; } LongDecimal number = new LongDecimal(); LongDecimal square_difference = new LongDecimal(3); Numbers nums = new Numbers(number, square_difference, 0); return RepeatByTime(nums, 0, time); } }
Calc クラスの IterateGenerator は以下のようになります。
public string IterateGenerator() { return new LongDecimal(generator.GenerateDecimal(count).Take(count)).Print(); }