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

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

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

C# の例(9)

Channel を使ったバージョンは以下のようになります。

NumbersGenerator クラスの GenerateDecimal メソッドは以下のようになります。

        public IteratorChannelImpl<int> GenerateDecimal()
        {
            bool SetToChannel(Channel<int> ch, int n)
            {
                async Task<bool> SetToChannel_a(Channel<int> ch, int n)
                {
                    if (!await ch.Writer.WaitToWriteAsync().ConfigureAwait(false))
                    {
                        return false;
                    }
                    if (!ch.Writer.TryWrite(n))
                    {
                        return false;
                    }
                    return true;
                }
                return SetToChannel_a(ch, n).Result;
            }
            async Task serv(Channel<int> ch_get)
            {
                LongDecimal number = new LongDecimal();
                LongDecimal square_difference = new LongDecimal(3);
                Numbers nums = new Numbers(number, square_difference, 0);
                for (; ; )
                {
                    int dd = nums.GetNextDecimalDigit();
                    if (!SetToChannel(ch_get, dd))
                    {
                        break;
                    }
                }
            }
            Channel<int> ch_get = Channel.CreateBounded<int>(1);
            Task.Run(() => serv(ch_get));
            return new IteratorChannelImpl<int>(ch_get);
        }

NumbersServer クラスの GenerateDecimalServerメソッドは以下のようになります。

        public IteratorChannelIOImpl<Numbers> GenerateDecimalServer()
        {
            Numbers numbers = new Numbers(new LongDecimal(), new LongDecimal(), 0);
            bool GetFromChannel(Channel<Numbers> ch)
            {
                async Task<bool> GetFromChannel_a(Channel<Numbers> ch)
                {
                    if (!await ch.Reader.WaitToReadAsync().ConfigureAwait(false))
                    {
                        return false;
                    }
                    if (!ch.Reader.TryRead(out numbers))
                    {
                        return false;
                    }
                    return true;
                }
                return GetFromChannel_a(ch).Result;
            }
            bool SetToChannel(Channel<Numbers> ch, Numbers n)
            {
                async Task<bool> SetToChannel_a(Channel<Numbers> ch, Numbers n)
                {
                    if (!await ch.Writer.WaitToWriteAsync().ConfigureAwait(false))
                    {
                        return false;
                    }
                    if (!ch.Writer.TryWrite(n))
                    {
                        return false;
                    }
                    return true;
                }
                return SetToChannel_a(ch, n).Result;
            }
            async Task serv(Channel<Numbers> ch_get, Channel<Numbers> ch_set)
            {
                LongDecimal number = new LongDecimal();
                LongDecimal square_difference = new LongDecimal(3);
                Numbers current_numbers = new Numbers(number, square_difference, 0);
                for (; ; )
                {
                    if (!SetToChannel(ch_get, current_numbers))
                    {
                        break;
                    }
                    if (!GetFromChannel(ch_get))
                    {
                        break;
                    }
                    current_numbers = numbers;
                }
            }
            Channel<Numbers> ch_get = Channel.CreateBounded<Numbers>(1);
            Channel<Numbers> ch_set = Channel.CreateBounded<Numbers>(1);
            Task.Run(() => serv(ch_get, ch_set));
            return new IteratorChannelIOImpl<Numbers>(ch_get, ch_set);
        }