Transcript
Page 1: Monadic Comprehensions and Functional Composition with Query Expressions

Monadic Comprehensions and Functional Composition with

Query Expressions

Chris Eargle

Page 2: Monadic Comprehensions and Functional Composition with Query Expressions

LINQ to Objects

Page 3: Monadic Comprehensions and Functional Composition with Query Expressions

Oh, that’s a monad!

Page 4: Monadic Comprehensions and Functional Composition with Query Expressions

List Monad

Page 5: Monadic Comprehensions and Functional Composition with Query Expressions

LINQ to Objectsfrom x in new[] {1, 2, 3}from y in new[] {1, 2, 3}select Tuple.Create(x, y)

List Monaddo x <- [1,2,3] y <- [1,2,3] return (x,y)

Page 6: Monadic Comprehensions and Functional Composition with Query Expressions

Query Expressions

Page 7: Monadic Comprehensions and Functional Composition with Query Expressions

var words = new[] { "the", "quick", "brown", "fox"};

IEnumerable<string> query = from word in words select word;

Page 8: Monadic Comprehensions and Functional Composition with Query Expressions

var query = from word in words orderby word.Length select word;

Page 9: Monadic Comprehensions and Functional Composition with Query Expressions

var query = from word in words orderby word.Length select word.Replace(‘o’, ‘a’);

Page 10: Monadic Comprehensions and Functional Composition with Query Expressions

var query = words.OrderBy(w => w.Length) .Select(w => w.Replace('o', 'a'));

Page 11: Monadic Comprehensions and Functional Composition with Query Expressions

Monad

Page 12: Monadic Comprehensions and Functional Composition with Query Expressions

Functional Design Pattern

Page 13: Monadic Comprehensions and Functional Composition with Query Expressions

ReturnBind

Page 14: Monadic Comprehensions and Functional Composition with Query Expressions

public struct Monad<T> { private T value;

public Monad(T value) { this.value = value; }

public Monad<U> Bind<U>(Func<T, Monad<U>> func) { return func(value); } }

Page 15: Monadic Comprehensions and Functional Composition with Query Expressions

public static class Monad { public static Monad<T> Create<T>(T value) { return new Monad<T>(value); } }

Page 16: Monadic Comprehensions and Functional Composition with Query Expressions

var monad = Monad.Create(1);var monad2 = monad.Bind(v => Monad.Create(v));

Assert.IsInstanceOfType(monad, typeof(Monad<int>));Assert.AreEqual(monad, monad2);Assert.AreNotSame(monad, monad2);

Page 17: Monadic Comprehensions and Functional Composition with Query Expressions

Identity Monad

Page 18: Monadic Comprehensions and Functional Composition with Query Expressions

public struct Identity<T> { T value; public T Value { get { return value; } } public Identity(T value) { this.value = value; } }

Page 19: Monadic Comprehensions and Functional Composition with Query Expressions

public static class Identity { public static Identity<T> Create<T>(T value) { return new Identity<T>(value); } }

Page 20: Monadic Comprehensions and Functional Composition with Query Expressions

var result = from x in Identity.Create(1) select x.ToString();

Assert.AreEqual("1", result.Value);

Page 21: Monadic Comprehensions and Functional Composition with Query Expressions

public Identity<TResult> Select<TResult>(Func<T, TResult> selector)

{ return Identity.Create(selector(value)); }

Page 22: Monadic Comprehensions and Functional Composition with Query Expressions

var result = from x in Identity.Create(2) from y in Identity.Create(3) select x + y;

Assert.AreEqual(5, result.Value);

Page 23: Monadic Comprehensions and Functional Composition with Query Expressions

public Identity<TResult> SelectMany<U, TResult>( Func<T, Identity<U>> selector, Func<T, U, TResult> resultSelector){ return Identity.Create(resultSelector(value,

selector(value).Value));}

Page 24: Monadic Comprehensions and Functional Composition with Query Expressions

var result = from x in Identity.Create(2) from y in Identity.Create(3) select x + y;

Assert.AreEqual(5, result.Value);

Page 25: Monadic Comprehensions and Functional Composition with Query Expressions

Cut the Middle Man

Page 26: Monadic Comprehensions and Functional Composition with Query Expressions

var result = from x in 2 from y in 3 select x + y;

Assert.AreEqual(5, result);

Page 27: Monadic Comprehensions and Functional Composition with Query Expressions

public static TResult SelectMany<T1, T2, TResult>( this T1 source, Func<T1, T2> selector, Func<T1, T2, TResult> resultSelector){ return resultSelector(source, selector(source));}

Page 28: Monadic Comprehensions and Functional Composition with Query Expressions

Tuples

Page 29: Monadic Comprehensions and Functional Composition with Query Expressions

var result = from info in ConferenceInfo() from dates in ConferenceDates() select new { Name = info.Item1, StartDate = dates.Item1, EndDate = dates.Item3 };

Page 30: Monadic Comprehensions and Functional Composition with Query Expressions

Assert.AreEqual("IEEE ICCSIT", result.Name);

Assert.AreEqual(july9th, result.StartDate);

Assert.AreEqual(july11th, result.EndDate);

Page 31: Monadic Comprehensions and Functional Composition with Query Expressions

Continuation Monad

Page 32: Monadic Comprehensions and Functional Composition with Query Expressions

public class Continuation<R, A> { private readonly Func<Func<A, R>, R> value; internal Continuation(Func<Func<A, R>, R> func) { this.value = func; } public R Run(Func<A, R> k) { return value(k); }}

Page 33: Monadic Comprehensions and Functional Composition with Query Expressions

public static class Continuation { public static Continuation<R, A> Create<R, A>(Func<A> func) { return Continuation.Create<R, A>(k => k(func())); } public static Continuation<R, A> Create<R, A>(Func<Func<A, R>, R> func) { return new Continuation<R, A>(func); } }

Page 34: Monadic Comprehensions and Functional Composition with Query Expressions

public static Continuation<R, int> Square<R>(int x){ return Continuation.Create<R, int>(() => x * x);}

Page 35: Monadic Comprehensions and Functional Composition with Query Expressions

public static Continuation<R, double> Hypotenuse<R>(int x, int y)

{ return from h in Square<R>(x) from w in Square<R>(y) select Math.Sqrt(h + w);}

Page 36: Monadic Comprehensions and Functional Composition with Query Expressions

Assert.AreEqual(5, Hypotenuse<double>(3, 4).Run(n => n));

Page 37: Monadic Comprehensions and Functional Composition with Query Expressions

Cut the Middle Man

Page 38: Monadic Comprehensions and Functional Composition with Query Expressions

Func<int, int> square = x => x * x;Func<int, double> squareRoot = x => Math.Sqrt(x);

Page 39: Monadic Comprehensions and Functional Composition with Query Expressions

var hypotenuse = from h in square from w in square select squareRoot(h + w);

Assert.AreEqual(5, hypotenuse(3, 4));

Page 40: Monadic Comprehensions and Functional Composition with Query Expressions

public static Func<T1, T2, TResult3>SelectMany<T1, T2, TResult, TResult2, TResult3>( this Func<T1, TResult> leftFunc, Func<T1, Func<T2, TResult2>> rightFunc, Func<TResult, TResult2, TResult3> selector) { return (x, y) => selector(leftFunc(x), rightFunc(x)(y)); }

Page 41: Monadic Comprehensions and Functional Composition with Query Expressions

Func<int, int> f = x => x + 2;

var result = from x in f select x * 2;

Assert.AreEqual(6, result(1));

Page 42: Monadic Comprehensions and Functional Composition with Query Expressions

public static Func<T, TResult2> Select <T, TResult, TResult2>( this Func<T, TResult> func, Func<TResult, TResult2> selector) { return a => selector(func(a)); }

Page 43: Monadic Comprehensions and Functional Composition with Query Expressions
Page 44: Monadic Comprehensions and Functional Composition with Query Expressions

public static Func<Int32, Double> Sum(this Func<Int32, Double> func, int start = 0) { return end => { Double result = default(Double); for (int k = start; k <= end; k++) { result += func(k); } return result; }; }

Page 45: Monadic Comprehensions and Functional Composition with Query Expressions

Factorial

Page 46: Monadic Comprehensions and Functional Composition with Query Expressions

Func<int, int> f = x => x;

var factorial = from x in f.Sum() where x != 0 select x ?? 1;

Assert.AreEqual(1, factorial(0)); Assert.AreEqual(6, factorial(3));

Page 47: Monadic Comprehensions and Functional Composition with Query Expressions

public static Func<T, dynamic> Where<T, TResult>( this Func<T, TResult> func, Func<TResult, bool> predicate){ return a => { TResult result = func(a); return predicate(result) ? result as dynamic : null; };}

Page 48: Monadic Comprehensions and Functional Composition with Query Expressions
Page 49: Monadic Comprehensions and Functional Composition with Query Expressions

Func<Int32, Double> f = k => 4 * Math.Pow(-1, k) / (2.0 * k + 1); var calculatePi = f.Sum(); Assert.AreEqual(3.14159, calculatePi(200000), 7);

Page 50: Monadic Comprehensions and Functional Composition with Query Expressions

monadic.codeplex.com


Top Related