Example #1
0
        public static ListMonad <T> ToListMonad <T>(this Monad <T> value)
        {
            ListMonad <T> result = new ListMonad <T>();

            foreach (T element in value)
            {
                result.Add(element);
            }
            return(result);
        }
Example #2
0
        public static ListMonad <A> ToListMonad <A>(this IList <A> value)
        {
            ListMonad <A> result = new ListMonad <A>();

            foreach (A element in value)
            {
                result.Append(element);
            }
            return(result);
        }
Example #3
0
        /// <summary>
        /// Map the given function to each element in this ListMonad,
        /// and put the result in a new ListMonad of the result type.
        /// </summary>
        /// <typeparam name="B">Type of the value inside the result ListMonad.</typeparam>
        /// <param name="function">The function to map over the values.</param>
        /// <returns>The result ListMonad<B></returns>
        public override Monad <B> Fmap <B>(Func <A, B> function)
        {
            ListMonad <B> resultEnumerable = new ListMonad <B>();

            foreach (A element in list)
            {
                resultEnumerable.Append(function(element));
            }
            return(resultEnumerable);
        }
Example #4
0
        public override Monad <B> Fmap <B>(Func <A, int, B> function)
        {
            ListMonad <B> resultListMonad = new ListMonad <B>();
            int           index           = 0;

            foreach (A element in list)
            {
                resultListMonad.Append(function(element, index));        // Get the value of type B out of the result IMonad<B>, no matter what monad the result is.
                index++;
            }
            return(resultListMonad);
        }
Example #5
0
        public override Monad <C> Com <B, C>(Func <A, B, Monad <C> > function, Monad <B> mOther)
        {
            ListMonad <C> result = new ListMonad <C>();

            foreach (A a in list)
            {
                foreach (B b in mOther)
                {
                    result.Concatenate(function(a, b));
                }
            }

            return(result);
        }
Example #6
0
        public override Monad <C> Com <B, C>(Func <A, B, C> function, Monad <B> mOther)
        {
            ListMonad <C> resultListMonad = new ListMonad <C>();

            foreach (A elementThis in list)
            {
                foreach (B elementOther in mOther)
                {
                    resultListMonad.Append(function(elementThis, elementOther));
                }
            }

            return(resultListMonad);
        }
Example #7
0
        public override Monad <C> Com <B, C>(Monad <Func <A, B, C> > functionMonad, Monad <B> mOther)
        {
            ListMonad <C> resultListMonad = new ListMonad <C>();

            foreach (Func <A, B, C> f in functionMonad)
            {
                foreach (A a in list)
                {
                    foreach (B b in mOther)
                    {
                        resultListMonad.Append(f(a, b));
                    }
                }
            }

            return(resultListMonad);
        }
Example #8
0
        /// <summary>
        /// Map each function inside the given Monad over each element in this ListMonad,
        /// and put all the values inside the result monads into a new ListMonad of the type B.
        /// </summary>
        /// <typeparam name="B">The type inside the result ListMonad.</typeparam>
        /// <param name="functionMonad">The monad that has functions inside.</param>
        /// <returns>The new ListMonad of type B.</returns>
        public override Monad <B> App <B>(Monad <Func <A, Monad <B> > > functionMonad)
        {
            ListMonad <B> result = new ListMonad <B>();

            foreach (Func <A, Monad <B> > function in functionMonad)
            {
                // function can be null, for example when the functionMonad is a Maybe with Nothing<Func<A, IMonad<B>> then default(Func<A, IMonad<B>>) returns null
                // we could check for IMonad as Maybe and then check for isNothing, but then ListMonad have to "know" Maybe, i dont like that.
                if (function != null)
                {
                    foreach (A element in list)     // calculate function result for each element in this ListFunctor<T>
                    {
                        result.Concatenate(function(element));
                    }
                }
            }
            return(result);
        }
Example #9
0
        public override Monad <B> Fmap <B>(Func <CacheEntry <K, V>, B> function)
        {
            ListMonad <B> result = new ListMonad <B>();

            Lock.EnterWriteLock();
            try
            {
                foreach (var element in cacheDict)
                {
                    result.Add(function(element.Value));
                }
            }
            finally
            {
                Lock.ExitWriteLock();
            }
            return(result);
        }
Example #10
0
        public override Monad <C> Com <B, C>(Func <CacheEntry <K, V>, B, C> function, Monad <B> mOther)
        {
            ListMonad <C> result = new ListMonad <C>();

            Lock.EnterWriteLock();
            try
            {
                foreach (var element in cacheDict.Values)
                {
                    foreach (var elementB in mOther)
                    {
                        result.Add(function(element, elementB));
                    }
                }
            }
            finally
            {
                Lock.ExitWriteLock();
            }
            return(result);
        }
Example #11
0
        public override Monad <B> App <B>(Monad <Func <CacheEntry <K, V>, B> > functionMonad)
        {
            ListMonad <B> result = new ListMonad <B>();

            Lock.EnterWriteLock();
            try
            {
                foreach (var element in cacheDict.Values)
                {
                    foreach (var func in functionMonad)
                    {
                        result.Add(func(element));
                    }
                }
            }
            finally
            {
                Lock.ExitWriteLock();
            }
            return(result);
        }
Example #12
0
        public override Monad <B> Bind <B>(Func <CacheEntry <K, V>, Monad <B> > func)
        {
            ListMonad <B> result = new ListMonad <B>();

            Lock.EnterWriteLock();
            try
            {
                foreach (var element in cacheDict.Values)
                {
                    foreach (var fRes in func(element))
                    {
                        result.Add(fRes);
                    }
                }
            }
            finally
            {
                Lock.ExitWriteLock();
            }
            return(result);
        }
Example #13
0
        public static void ListMonadLinqAndBindPlayground()
        {
            var bindResult1 = new ListMonad <string>()
            {
                "1. ", "2. "
            }.Fmap(a =>
                   "Hello World!".ToIdentity().Fmap(b =>
                                                    (new DateTime(2010, 1, 11)).ToMaybe().Fmap(c =>
                                                                                               a + ", " + b.ToString() + ", " + c.ToShortDateString()).Return()).Return());

            Console.WriteLine(bindResult1);
            Console.ReadLine();

            var bindResult2 = from str in new ListMonad <string>()
            {
                "1. ", "2. "
            }
            from h in "Hello World!".ToIdentity()
            from b in 7.ToIdentity()
            from dt in (new DateTime(2010, 1, 11)).ToMaybe()
            select str + h + " " + b.ToString() + " " + dt.ToShortDateString();

            Console.WriteLine(bindResult2);
            Console.ReadLine();

            var bindResult3 = " This is a bind test".ToIdentity().Bind(a =>
                                                                       "Hello World!".ToIdentity().Bind(b =>
                                                                                                        (new DateTime(2010, 1, 11)).ToMaybe().Bind(c =>
                                                                                                                                                   (a + ", " + b.ToString() + ", " + c.ToShortDateString()).ToIdentity())));

            Console.WriteLine(bindResult3);

            Console.ReadLine();

            Monad <string> idString = from a in "Hello World!".ToIdentity()
                                      from b in 7.ToIdentity()
                                      from c in (new DateTime(2010, 1, 11)).ToIdentity()
                                      select a + ", " + b.ToString() + ", " + c.ToShortDateString();

            Console.WriteLine(idString);
            Console.ReadLine();

            var listMInt = new ListMonad <int>()
            {
                1, 2, 3, 4, 5
            };
            var listMDbl = new ListMonad <double> {
                1.5, 2.5, 3.5, 4.5, 5.5
            };
            var listMChar = new ListMonad <Char>()
            {
                'a', 'b', 'c', 'd', 'e'
            };

            // The query is a ListMonad<String> because the monad that calles select,
            // is a ListMonad (listMInt).
            var listMString = from i in listMInt
                              from c in listMChar
                              select i + ":" + c;

            Console.WriteLine(listMString);
            Console.ReadLine();

            var result3 = from i in listMInt
                          from d in listMDbl
                          from c in listMChar
                          select c + ") " + Math.Pow(i, d) + ", ";

            Console.WriteLine(result3);
            Console.ReadLine();

            var result4 = from i in listMInt
                          from d in listMDbl
                          from c in listMChar
                          select(c + ") " + Math.Pow(i, d) + ", ").ToIdentity();

            Console.WriteLine(result4);
            Console.ReadLine();

            var result5 = from i in listMInt
                          from d in listMDbl
                          select i + ") " + Math.Pow(i, d) + ", ";

            Console.WriteLine(result5);
            Console.ReadLine();

            var result6 = listMInt.Com((i, d) => (i + ") " + Math.Pow(i, d) + ", ").ToIdentity(), listMDbl);

            Console.WriteLine(result6);
            Console.ReadLine();

            var result7 = from i in listMInt
                          where i % 2 == 0
                          from d in new ListMonad <double>()
            {
                1.0, 2.0, 3.0, 4.0, 5.0
            }
            where d % 2 == 0
            select i + "^" + d + " = " + Math.Pow(i, d) + ", ";

            Console.WriteLine(result7);
            Console.ReadLine();
        }
Example #14
0
        public static void ListMonadOperatorPlayground()
        {
            Console.Out.WriteLine("\n-------------------------------------------------------------");
            Console.Out.WriteLine("------------------------Operator playground-------------------");
            Console.Out.WriteLine("-------------------------------------------------------------\n");

            int counter = 0;

            Console.Out.WriteLine("Create two lists [0..9]: ");
            ListMonad <double> listMonadDouble = new ListMonad <double>()
            {
                1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0
            };

            ListMonad <double> listMonadDoubleTwo = new ListMonad <double>()
            {
                1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0
            };

            // Functions for second App function.
            Func <double, Monad <double> > doubleIMonadDoubleFun1 =
                (x) => { return(new Just <double>(x * x)); };
            Func <double, Monad <double> > doubleIMonadDoubleFun2 =
                (x) => { return(new Just <double>(x * x * x)); };
            Func <double, Monad <double> > doubleIMonadDoubleFun3 =
                (x) => { return(new Just <double>(x * x * x * x)); };
            Func <double, Monad <double> > doubleIMonadDoubleFun4 =
                (x) => { return(new Just <double>(x * x * x * x * x)); };
            Func <double, Monad <double> > doubleIMonadDoubleFun5 =
                (x) => { return(new ListMonad <double>()
                {
                    x + 1, x - 1
                }); };

            var listMonadFunc1 = new ListMonad <Func <double, Monad <double> > >();

            listMonadFunc1.Append(doubleIMonadDoubleFun1);
            listMonadFunc1.Append(doubleIMonadDoubleFun2);
            listMonadFunc1.Append(doubleIMonadDoubleFun3);
            listMonadFunc1.Append(doubleIMonadDoubleFun4);
            listMonadFunc1.Append(doubleIMonadDoubleFun5);

            // Functions for combination
            Func <double, double, double> doubleDoubleDoubleFunc1 =
                (x, y) => { return(x + y); };
            Func <double, double, double> doubleDoubleDoubleFunc2 =
                (x, y) => { return(x - y); };
            Func <double, double, double> doubleDoubleDoubleFunc3 =
                (x, y) => { return(x * y); };
            Func <double, double, double> doubleDoubleDoubleFunc14 =
                (x, y) => { return(x / y); };
            Func <double, double, double> doubleDoubleDoubleFunc5 =
                (x, y) => { return(x % y); };

            var listMonadFunc2 = new ListMonad <Func <double, double, double> >()
            {
                doubleDoubleDoubleFunc1,
                doubleDoubleDoubleFunc2,
                doubleDoubleDoubleFunc3,
                doubleDoubleDoubleFunc14,
                doubleDoubleDoubleFunc5
            };


            // Functions for combination with IMonad as result.
            Func <double, double, Monad <double> > intDoubleIMonadDoubleFunc1 =
                (x, y) => { return(new Just <double>(x + y)); };

            Func <double, double, Monad <double> > intDoubleIMonadDoubleFunc2 =
                (x, y) => { return(new Just <double>(x - y)); };

            Func <double, double, Monad <double> > intDoubleIMonadDoubleFunc3 =
                (x, y) => { return(new Just <double>(x * y)); };

            Func <double, double, Monad <double> > intDoubleIMonadDoubleFunc4 =
                (x, y) => { return(new Just <double>(x / y)); };

            Func <double, double, Monad <double> > intDoubleIMonadDoubleFunc5 =
                (x, y) => { return(new ListMonad <double>()
                {
                    x % y
                }); };

            Func <double, double, Monad <double> > intDoubleIMonadDoubleFunc6 =
                (x, y) => { return(new ListMonad <double>()
                {
                    x *y *y, x *y *y *y
                }); };

            Func <double, double, Monad <double> > intDoubleIMonadDoubleFunc7 =
                (x, y) => { return(new Nothing <double>()); };

            var listMonadFunc3 = new ListMonad <Func <double, double, Monad <double> > >()
            {
                intDoubleIMonadDoubleFunc1,
                intDoubleIMonadDoubleFunc2,
                intDoubleIMonadDoubleFunc3,
                intDoubleIMonadDoubleFunc4,
                intDoubleIMonadDoubleFunc5,
                intDoubleIMonadDoubleFunc6,
                intDoubleIMonadDoubleFunc7
            };

            Console.WriteLine("fmap f(x) = x * 0.5 over [1,0..9.0] with \" / \" operator");

            var result = (listMonadDouble / ((x) => { return(x * 0.5); })).Visit((x) =>
            {
                Console.Out.Write(x + ", ");
                counter++;
                if (counter % 9 == 0)
                {
                    Console.WriteLine("");
                }
            });

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

            Console.WriteLine("App functions [x^2, x^3, x^4, x^5, [x+1, x-1]] \n" +
                              " over [1,0..9.0] with \" * \" operator");

            var resultTwo = (listMonadDouble * listMonadFunc1).Visit((x) =>
            {
                Console.Out.Write(x + ", ");
                counter++;
                if (counter % 9 == 0)
                {
                    Console.WriteLine("");
                }
            });

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

            // Create a tupel with the ListMonad with functions inside
            // and with the other ListMonad with double values inside
            // because the \"*\" operator can have only one other argument.
            // it sad there are no way for custom operators in C#
            // and there are no operator that take tree arguments and can be overloaded.
            var funcMonadTupel = new Tuple <Monad <Func <double, double, double> >,
                                            Monad <double>
                                            >(listMonadFunc2,
                                              listMonadDoubleTwo);

            counter = 0;
            Console.WriteLine("Combinate [1.0,..,9.0] with [1.0,..,9.0] and functions \n" +
                              " [x+y, x-y, x*y, x/y, x%y]");
            var resultThree = (listMonadDouble * funcMonadTupel)
                              .Visit((x) =>
            {
                Console.Out.Write(x + ", ");
                counter++;
                if (counter % 9 == 0)
                {
                    Console.WriteLine("");
                }

                if (counter % (9 * 9) == 0)
                {
                    Console.WriteLine("-------------------------------------------");
                }
            });

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


            var funcMonadTupelTwo = new Tuple <Monad <Func <double, double, Monad <double> > >,
                                               Monad <double> >
                                        (listMonadFunc3,
                                        listMonadDoubleTwo);

            Console.WriteLine("Combinate [1.0,..,9.0] with [1.0,..,9.0] and functions \n" +
                              " [x+y, x-y, x*y, x/y, x%y, [x*y^2, x*y^3]]:");
            var resultFour = (listMonadDouble * funcMonadTupelTwo)
                             .Visit((x) =>
            {
                Console.Out.Write(x + ", ");
                counter++;
                if (counter % 9 == 0)
                {
                    Console.WriteLine("");
                }

                if (counter % (9 * 9) == 0)
                {
                    Console.WriteLine("-------------------------------------------");
                }
            });

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


            Console.WriteLine("[1.0,..,9.0] + [1.0,..,9.0] + Just(1000.0) + Nothing \n" +
                              " Fmap -> App -> Com -> Com2nd -> Visit \n" +
                              " This will take a while!! Are you ready, then press enter :-D :");
            Console.ReadLine();

            // Concat both double ListMonadĀ“s to get a bigger list
            // and only to show that its possible
            // concat a Just(1000.0) and a Nothing<double> to the result list too.
            var resultFive = (listMonadDouble + listMonadDoubleTwo)
                             .Append(new Just <double>(1000.0))
                             .Append(new Nothing <double>());

            var resultSix = (ListMonad <double>)resultFive;

            // This line is done the whole operatione!
            // Without one loop.
            resultSix = resultSix / ((x) => { return(x * 100.0); }) * funcMonadTupel * funcMonadTupelTwo;

            resultSix.Visit((x) =>
            {
                Console.Out.Write(x + ", ");
                counter++;
                if (counter % 9 == 0)
                {
                    Console.WriteLine("");
                }

                if (counter % (9 * 9) == 0)
                {
                    Console.WriteLine("-------------------------------------------");
                }
            });
            Console.WriteLine("\n___________________________________________________________");

            Console.ReadLine();
        }
Example #15
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();
        }
Example #16
0
        public static void ListMonadPlayground()
        {
            Console.Out.WriteLine("\n-------------------------------------------------------------");
            Console.Out.WriteLine("------------------------ListMonad playground-------------------");
            Console.Out.WriteLine("-------------------------------------------------------------\n");

            Console.Out.WriteLine("Create two lists [1..5] and [J(1)..(J5)]: ");
            ListMonad <int> listMonadInt = new ListMonad <int>()
            {
                1, 2, 3, 4, 5
            };

            ListMonad <double> listMonadDouble = new ListMonad <double>()
            {
                1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0
            };

            // Because Maybe class has an implicit operator it can be written very cool and easy like a normal list.
            ListMonad <Maybe <int> > listMonadMaybeInt = new ListMonad <Maybe <int> >()
            {
                0, 1, 2, 3, 4, 5, 6, 7, 8, 9
            };

            // Functions for Fmap and first App function.
            Func <int, double> intDoubleFunc1 = (x) => { return(0.5 * x); };
            Func <int, double> intDoubleFunc2 = (x) => { return(0.7 * x); };

            Console.WriteLine("Fmap f(x) = 0.5 * x over [1,..5,]");
            int counter = 0;

            listMonadInt.Fmap(intDoubleFunc1).Visit((x) =>
            {
                Console.Out.Write(x + ", ");
                counter++;
                if (counter % 5 == 0)
                {
                    Console.WriteLine("");
                }
            });
            Console.WriteLine("\n___________________________________________________________");
            Console.ReadLine();

            Console.WriteLine("App [f(x)=0.5*x, f(x)=0.7*x] over [1,..,5]");
            var listMonadintDoubleFunc = new ListMonad <Func <int, double> >()
            {
                intDoubleFunc1, intDoubleFunc2
            };

            counter = 0;
            listMonadInt.App(listMonadintDoubleFunc).Visit((x) =>
            {
                Console.Out.Write(x + ", ");
                counter++;
                if (counter % 5 == 0)
                {
                    Console.WriteLine("");
                }
                if (counter % (5 * 5) == 0)
                {
                    Console.WriteLine("-----------------------------------------");
                }
            });
            Console.WriteLine("\n___________________________________________________________");
            Console.ReadLine();

            // Functions for second App function.
            Func <int, Monad <double> > intIMonadIntDoubleFunc1 =
                (x) => { return(new Just <double>(x * x)); };
            Func <int, Monad <double> > intIMonadIntDoubleFunc2 =
                (x) => { return(new Just <double>(x * x * x)); };
            Func <int, Monad <double> > intIMonadIntDoubleFunc3 =
                (x) => { return(new Just <double>(x * x * x * x)); };
            Func <int, Monad <double> > intIMonadIntDoubleFunc4 =
                (x) => { return(new Just <double>(x * x * x * x * x)); };
            Func <int, Monad <double> > intIMonadIntDoubleFunc5 =
                (x) => { return(new ListMonad <double>()
                {
                    x + 1, x - 1
                }); };

            var listMonadIMonadIntDoubleFunc = new ListMonad <Func <int, Monad <double> > >();

            listMonadIMonadIntDoubleFunc.Append(intIMonadIntDoubleFunc1);
            listMonadIMonadIntDoubleFunc.Append(intIMonadIntDoubleFunc2);
            listMonadIMonadIntDoubleFunc.Append(intIMonadIntDoubleFunc3);
            listMonadIMonadIntDoubleFunc.Append(intIMonadIntDoubleFunc4);
            listMonadIMonadIntDoubleFunc.Append(intIMonadIntDoubleFunc5);

            Console.WriteLine("App [Just(x^2), Just(x^3), Just(x^4), Just(x^5) ListMonad{x+1, x-1} over [1,..,5]");
            listMonadInt.App(listMonadIMonadIntDoubleFunc).Visit((x) =>
            {
                Console.Out.Write(x + ", ");
                counter++;
                if (counter % 5 == 0)
                {
                    Console.WriteLine("");
                }
            });
            Console.WriteLine("\n___________________________________________________________");
            Console.ReadLine();

            // Functions for combination
            Func <int, double, double> intDoubleDoubleFunc1 =
                (x, y) => { return((double)x + y); };
            Func <int, double, double> intDoubleDoubleFunc2 =
                (x, y) => { return((double)x - y); };
            Func <int, double, double> intDoubleDoubleFunc3 =
                (x, y) => { return((double)x * y); };
            Func <int, double, double> intDoubleDoubleFunc4 =
                (x, y) => { return((double)x / y); };
            Func <int, double, double> intDoubleDoubleFunc5 =
                (x, y) => { return((double)x % y); };

            var listMonadIntDoubleDoubleFunc = new ListMonad <Func <int, double, double> >()
            {
                intDoubleDoubleFunc1,
                intDoubleDoubleFunc2,
                intDoubleDoubleFunc3,
                intDoubleDoubleFunc4,
                intDoubleDoubleFunc5
            };

            Console.WriteLine("Combinate [1..5] and [1.0,..,9.0] with 'normal' result value and function +:");
            counter = 0;
            listMonadInt.Com(intDoubleDoubleFunc1, listMonadDouble)
            .Visit((x) =>
            {
                Console.Out.Write(x + ", ");
                counter++;
                if (counter % 9 == 0)
                {
                    Console.WriteLine("");
                }
            });
            Console.WriteLine("\n___________________________________________________________");
            Console.ReadLine();

            Console.WriteLine("Combinate [1..5] and [1.0,..,9.0] 'normal' result value and functions [+, -, *, /, %]: ");
            counter = 0;
            listMonadInt.Com(listMonadIntDoubleDoubleFunc, listMonadDouble)
            .Visit((x) =>
            {
                Console.Out.Write(x + ", ");
                counter++;
                if (counter % 9 == 0)
                {
                    Console.WriteLine("");
                }
                if (counter % (5 * 9) == 0)
                {
                    Console.WriteLine("------------------------------------------------");
                }
            });
            Console.WriteLine("\n___________________________________________________________");
            Console.ReadLine();

            // Functions for combination with IMonad as result.
            Func <int, double, Monad <double> > intDoubleIMonadDoubleFunc1 =
                (x, y) => { return(new Just <double>((double)x + y)); };

            Func <int, double, Monad <double> > intDoubleIMonadDoubleFunc2 =
                (x, y) => { return(new Just <double>((double)x - y)); };

            Func <int, double, Monad <double> > intDoubleIMonadDoubleFunc3 =
                (x, y) => { return(new Just <double>((double)x * y)); };

            Func <int, double, Monad <double> > intDoubleIMonadDoubleFunc4 =
                (x, y) => { return(new Just <double>((double)x / y)); };

            Func <int, double, Monad <double> > intDoubleIMonadDoubleFunc5 =
                (x, y) => { return(new ListMonad <double>()
                {
                    (double)x % y
                }); };

            Func <int, double, Monad <double> > intDoubleIMonadDoubleFunc6 =
                (x, y) => { return(new ListMonad <double>()
                {
                    (double)x * y * y, (double)x * y * y * y
                }); };

            Func <int, double, Monad <double> > intDoubleIMonadDoubleFunc7 =
                (x, y) => { return(new Nothing <double>()); };

            var listMonadIntDoubleIMonadDoubleFunc = new ListMonad <Func <int, double, Monad <double> > >()
            {
                intDoubleIMonadDoubleFunc1,
                intDoubleIMonadDoubleFunc2,
                intDoubleIMonadDoubleFunc3,
                intDoubleIMonadDoubleFunc4,
                intDoubleIMonadDoubleFunc5,
                intDoubleIMonadDoubleFunc6,
                intDoubleIMonadDoubleFunc7
            };

            Console.WriteLine("Combination with IMonad function results.");
            Console.WriteLine("List1[1,..,5], List2[1.0,..,9.0] and function +");
            counter = 0;
            listMonadInt.Com(intDoubleIMonadDoubleFunc1, listMonadDouble)
            .Visit((x) =>
            {
                Console.Out.Write(x + ", ");
                counter++;
                if (counter % 9 == 0)
                {
                    Console.WriteLine("");
                }
                if (counter % (5 * 9) == 0)
                {
                    Console.WriteLine("------------------------------------------------");
                }
            });
            Console.WriteLine("\n___________________________________________________________");
            Console.ReadLine();

            Console.WriteLine("Combination with IMonad function results.");
            Console.WriteLine("List1[1,..,5], List2[1.0,..,9.0] and " +
                              "functions [+, -, *, /, %, [x*y*y, x*y*y*y], Nothing]");
            counter = 0;
            listMonadInt.Com(listMonadIntDoubleIMonadDoubleFunc, listMonadDouble)
            .Visit((x) =>
            {
                Console.Out.Write(x + ", ");
                counter++;
                if (counter % 9 == 0)
                {
                    Console.WriteLine("");
                }
                if (counter % (5 * 9) == 0)
                {
                    Console.WriteLine("------------------------------------------------");
                }
            });
            Console.WriteLine("\n___________________________________________________________");
            Console.ReadLine();

            // Visit with other IMonad
            Console.WriteLine("Visit with other IMonad and add (+) values in output.");
            counter = 0;
            listMonadInt.Visit <double>((x, y) =>
            {
                Console.Write(x * y + ", ");
                counter++;
                if (counter % 9 == 0)
                {
                    Console.WriteLine("");
                }
            }, listMonadDouble);
            Console.WriteLine("\n___________________________________________________________");
            Console.ReadLine();

            Console.WriteLine("Function applying with Linq: \n" +
                              " from f in [+, -, *, %]\n" +
                              " from x in [1,..,5]\n" +
                              " from y in [1.0,..,9.0] \n" +
                              " select f(x,y) \n");
            var query = from f in listMonadIntDoubleDoubleFunc
                        from x in listMonadInt
                        from y in listMonadDouble
                        select f(x, y);

            counter = 0;
            query.Visit((x) =>
            {
                Console.Out.Write(x + ", ");
                counter++;
                if (counter % 9 == 0)
                {
                    Console.WriteLine("");
                }
                if (counter % (5 * 9) == 0)
                {
                    Console.WriteLine("------------------------------------------------");
                }
            });
            Console.WriteLine("\n___________________________________________________________");
            Console.ReadLine();

            Console.WriteLine("Function applying with Linq: ");
            var query2 = from f in listMonadIntDoubleIMonadDoubleFunc
                         from x in listMonadInt
                         from y in listMonadDouble
                         select f(x, y);

            counter = 0;
            query2.Visit((x) =>
            {
                Console.Out.Write(x + ", ");
                counter++;
                if (counter % 9 == 0)
                {
                    Console.WriteLine("");
                }
                if (counter % (5 * 9) == 0)
                {
                    Console.WriteLine("------------------------------------------------");
                }
            });
            Console.WriteLine("\n___________________________________________________________");
            Console.ReadLine();
        }