エレファント・ビジュアライザー調査記録

ビジュアルプログラミングで数式の変形を表すことを考えていくブロクです。

関数プログラミングと無限論理多項式(10)

C# の例(5)

次にイテレーターとなるクラスを(IEnumerable インターフェイスとは関係なく)作って実装します。イテレーターに対する入力もできるようにします。

サーバーで無限に計算する場合

NumbersGenerator クラスの GenerateDecimal と コンストラクターイテレーターを保持する変数の定義は以下のようになります。next と getCurrent と setCurrent がクロージャーで、new IteratorSimpleImpl(next, getCurrent, setCurrent) でイテレーターを作成します。current_digit に値を保存しています。このクラスではイテレーターに対する入力は行いません。

        public NumbersGenerator()
        {
            generator = GenerateDecimal();
        }
        private IteratorSimpleImpl<int> generator;
        public IteratorSimpleImpl<int> GenerateDecimal()
        {
            LongDecimal number = new LongDecimal();
            LongDecimal square_difference = new LongDecimal(3);
            Numbers nums = new Numbers(number, square_difference, 0);
            int current_digit = 0;
            bool next()
            {
                current_digit = nums.GetNextDecimalDigit();
                return true;
            }
            int getCurrent()
            {
                return current_digit;
            }
            void setCurrent(int val)
            {
            }
            return new IteratorSimpleImpl<int>(next, getCurrent, setCurrent);
        }

イテレーターとなるクラス IteratorSimpleImpl クラスは以下のようになります。

    internal class IteratorSimpleImpl<T>
    {
        private Func<bool> next;
        private Func<T> getCurrent;
        private Action<T> setCurrent;
        public IteratorSimpleImpl(Func<bool> next, Func<T> getCurrent, Action<T> setCurrent)
        {
            this.next = next;
            this.getCurrent = getCurrent;
            this.setCurrent = setCurrent;
        }
        public T Current
        {
            get
            {
                return getCurrent();
            }
            set
            {
                setCurrent(value);
            }
        }
        public bool MoveNext()
        {
            return next();
        }
        public IEnumerable<T> Take(int count)
        {
            IteratorSimpleImpl<T> it = this;
            for (int i = 0; i < count && it.MoveNext(); i++)
            {
                yield return it.Current;
            }
        }
    }

ブラウザーで計算する場合

NumbersServer クラスの GenerateDecimalServer と コンストラクターイテレーターを保持する変数の定義は以下のようになります。next と getCurrent と setCurrent がクロージャーで、IteratorSimpleImpl(next, getCurrent, setCurrent) でイテレーターを作成します。current_numbers に値を保存しています。このクラスでは setCurrent でイテレーターに対する入力を行うことができます。

        public NumbersServer()
        {
            generator_server = GenerateDecimalServer();
        }
        private IteratorSimpleImpl<Numbers> generator_server;
        public IteratorSimpleImpl<Numbers> GenerateDecimalServer()
        {
            LongDecimal number = new LongDecimal();
            LongDecimal square_difference = new LongDecimal(3);
            Numbers current_numbers = new Numbers(number, square_difference, 0);
            bool next()
            {
                return true;
            }
            Numbers getCurrent()
            {
                return current_numbers;
            }
            void setCurrent(Numbers numbers)
            {
                current_numbers = numbers;
            }
            return new IteratorSimpleImpl<Numbers>(next, getCurrent, setCurrent);
        }

実行結果

1.73205080756887729352
1.73205080756887729352
1.73205080756887729352
1.73205080756887729352