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(); }
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(); }