Пример #1
0
        public override Monad <C> Com <B, C>(Func <A, B, C> function, Monad <B> mOther)
        {
            Monad <C> resultMonad = new Nothing <C>();  // New Nothing<B> maybe

            if (!isNothing && !(mOther is Nothing <B>))
            {
                foreach (var otherValue in mOther)
                {
                    resultMonad = new Just <C>(function(aValue, otherValue));
                }
            }
            return(resultMonad);
        }
Пример #2
0
        public override Monad <B> App <B>(Monad <Func <A, B> > functionMonad)
        {
            Maybe <B> result = new Nothing <B>();

            if (this is Just <A> && functionMonad != null)
            {
                foreach (var function in functionMonad)
                {
                    if (function != null)
                    {
                        result = new Just <B>(functionMonad.Return()(aValue));
                    }
                }
                if (result == null)
                {
                    result = new Nothing <B>();
                }
            }
            return(result);
        }
Пример #3
0
        public static void MaybePlayaround()
        {
            Console.Out.WriteLine("\n-------------------------------------------------------------");
            Console.Out.WriteLine("------------------------Maybe playground-----------------------");
            Console.Out.WriteLine("-------------------------------------------------------------\n");

            // Just 5, use implicit operator for *Maybe* to make a Just directly.
            Maybe <int> justInt = 5;

            Console.WriteLine("A new Just<double>: " + justInt.ToString());
            Maybe <int> nothingInt = 0;      // same as nothingInt = new Nothing<int>();

            Console.WriteLine("A new Nothing<double>: " + nothingInt.ToString());

            // justInt = 0; or justInt = new Nothing<int>() would make a Nothing out of the justInt

            Console.WriteLine("A new ListMonad<char>: ");
            var listMonadChar = new ListMonad <char>()
            {
                'a', 'b', 'c', 'd', 'e', 'f', 'g'
            }
            .Visit((x) => { Console.Out.Write(x + ", "); });

            Console.WriteLine("\n___________________________________________________________");

            Console.WriteLine("A new ListMonad<int>: ");
            var listMonadInt = new ListMonad <int>()
            {
                0, 1, 2, 3, 4, 5, 6, 7, 8, 9
            }
            .Visit((x) => { Console.Out.Write(x + ", "); });

            Console.WriteLine("\n___________________________________________________________");

            Console.WriteLine("A new ListMonad<double>: ");
            var listMonadDouble = new ListMonad <double>()
            {
                0, 1, 2, 3, 4, 5, 6, 7, 8, 9
            }
            .Visit((x) => { Console.Out.Write(x + ", "); });

            Console.WriteLine("\n___________________________________________________________");

            var intToDoubleFunction = new Func <int, double>(x => { return(x * 0.5); });

            Console.WriteLine("A new Just with a function inside: f(x) = x * 0.5 ");
            var justFunction = new Just <Func <int, double> >(intToDoubleFunction);

            Console.WriteLine(justFunction.ToString());
            Console.WriteLine("___________________________________________________________");
            Console.ReadLine();

            Console.WriteLine("Visits each combination of the Just 5 and the ListMonad<char>" +
                              "using a lambda and Console.Write inside: ");
            justInt.Visit((i, c) => { Console.Out.Write(i + "" + c + ", "); }, listMonadChar);
            Console.WriteLine("\n___________________________________________________________");
            Console.ReadLine();
            // Outputs: 1a, 1b, 1c, 1d, 1e,

            Console.WriteLine("Same with Nothing<int> will output nothing: ");
            nothingInt.Visit((i, c) => { Console.Out.Write(i + "" + c + ", "); }, listMonadChar);
            Console.WriteLine("___________________________________________________________");
            Console.ReadLine();

            Console.WriteLine("Visits each combination of the Just 5 and the ListMonad<int> \n" +
                              "using a lambda and Console.Write inside. Add both values in print out: ");
            justInt.Visit((x, y) => { Console.Out.Write(x + y + ", "); }, listMonadInt);

            Console.WriteLine("\nSame with Nothing<int>:");
            nothingInt = (Maybe <int>)nothingInt
                         .Visit((x, y) => { Console.Out.Write(x + y + ", "); }, listMonadInt);
            Console.WriteLine(nothingInt.ToString());
            Console.WriteLine("___________________________________________________________");
            Console.ReadLine();


            Console.Write("Fmap f(x) = x * 0.5 over the Just<int>(5): ");
            var justDouble = justInt.Fmap(intToDoubleFunction).Visit((x) => { Console.Out.Write(x + "\n"); });

            Console.WriteLine("___________________________________________________________");
            Console.ReadLine();

            Console.Write("App Just<Func>(f(x) = x * 0.5) over the Just<int>(5): ");
            justDouble = justInt.App(justFunction).Visit((x) => { Console.Out.Write(x + "\n"); });
            Console.WriteLine("___________________________________________________________");
            Console.ReadLine();

            Console.Write("App Just<Func> over the Just<int>(5), \n where the functions returns a new " +
                          "ListMonad<int>() \n with two times the value inside the Just 5. Output: ");
            var function     = new Just <Func <int, Monad <int> > >((x) => { return(new ListMonad <int>()
                {
                    x, x
                }); });
            var intListMonad = justInt.App(function).Visit((x) => { Console.Out.Write(x + ", "); });

            Console.WriteLine("\n___________________________________________________________");
            Console.ReadLine();
            // The result is a ListMonad<int>
            // Output: 5, 5,

            Console.WriteLine("Create a new ListMonad with Func<int, int, double> (x*y, x/y, x%y) inside.");
            Console.WriteLine("Combinate Just 5 and that functions. Result is Just<int>.");
            Console.WriteLine("Only last value is returned because this Com function cannot break out of the Just.");
            Console.WriteLine();
            var functionListMonad = new ListMonad <Func <int, int, double> >();

            functionListMonad.Append((x, y) => { return(x * y); });
            functionListMonad.Append((x, y) => { return(x / (y == 0 ? 1 : y)); });
            functionListMonad.Append((x, y) => { return(x % (y == 0 ? 1 : y)); });
            functionListMonad.Visit((x) => { Console.Out.WriteLine("Func: " + x); });
            var result = justInt.Com(functionListMonad, listMonadInt).Visit((x) => { Console.Out.Write(x + ", "); });

            Console.WriteLine("\n___________________________________________________________");
            Console.ReadLine();
            // Output: 5

            Console.WriteLine("Create a new ListMonad with \n" +
                              "Func<int, int, IMonad<double>> (x+y, x-y, x*y, x/y, x%y) inside.\n" +
                              "Where every function packs the result in a new ListMonad<double>.\n" +
                              "Combine the Just 5 and the ListMonad<double> with all the functions.\n" +
                              "The result ListMonad´s are flattned out, and only one result ListMonad<double> \n" +
                              " with all result values is returned: ");
            Console.WriteLine();
            var functionListMonadTwo = new ListMonad <Func <int, double, Monad <double> > >();

            functionListMonadTwo.Append((x, y) => { return(new ListMonad <double>()
                {
                    x + y
                }); });
            functionListMonadTwo.Append((x, y) => { return(new ListMonad <double>()
                {
                    x - y
                }); });
            functionListMonadTwo.Append((x, y) => { return(new ListMonad <double>()
                {
                    x *y
                }); });
            functionListMonadTwo.Append((x, y) => { return(new ListMonad <double>()
                {
                    x / (y == 0 ? 1 : y)
                }); });
            functionListMonadTwo.Append((x, y) => { return(new ListMonad <double>()
                {
                    x % (y == 0 ? 1 : y)
                }); });
            functionListMonadTwo.Append((x, y) => { return(new Nothing <double>()); });
            int counter   = 0;
            var resultTwo = justInt.Com(functionListMonadTwo, listMonadDouble)
                            .Visit((x) => {
                Console.Out.Write(x + ", ");
                counter++;
                if (counter % 10 == 0)
                {
                    Console.WriteLine("");
                }
            });

            // Output: 5*0, 5*1, 5*2,... 5*1, 5/1, 5/2, 5/3, ... 5%1, 5%1, 5%2, 5%3,....
            Console.WriteLine("\n___________________________________________________________");
            Console.ReadLine();

            Console.WriteLine("Do the same with the Nothing<int>: ");
            resultTwo = nothingInt.Com(functionListMonadTwo, listMonadDouble)
                        .Visit((x) => { Console.Out.Write(x + ", "); });
            // Output: 5*0, 5*1, 5*2,... 5*1, 5/1, 5/2, 5/3, ... 5%1, 5%1, 5%2, 5%3,....
            Console.WriteLine("___________________________________________________________");
            Console.ReadLine();

            Console.WriteLine("Combinate Just 5 and the ListMonad<int> with only one function ( f(x,y) = x+y ): ");
            var resultThree = justInt.Com((x, y) => { return(x + y); }, intListMonad)
                              .Visit((x) => { Console.Out.WriteLine(x); });

            Console.WriteLine("\n___________________________________________________________");
            Console.ReadLine();

            Console.WriteLine("Maping a f(x, y) = x*y over the Just 5 and a new Just<int>(10) using LINQ: ");
            var query = from f in new Just <Func <int, int, int> >((x, y) => { return(x * y); })
                        from x in justInt
                        from y in new Just <int>(10)
                        select f(x, y);

            query.Visit((x) => { Console.Out.WriteLine(x + ", "); });
            Console.WriteLine("\n___________________________________________________________");
            Console.ReadLine();
        }