SlideShare a Scribd company logo
1 of 50
Monadic Comprehensions and Functional Composition with Query Expressions Chris Eargle
LINQ to Objects
Oh, that’s a monad!
List Monad
LINQ to Objects from x in new[] {1, 2, 3}from y in new[] {1, 2, 3}select Tuple.Create(x, y) List Monad do x <- [1,2,3]     y <- [1,2,3]     return (x,y)
Query Expressions
var words = new[] { "the", "quick", "brown", "fox"}; IEnumerable<string> query = from word in words                                                       select word;
var query = from word in words orderbyword.Length select word;
var query = from word in words orderbyword.Length select word.Replace(‘o’, ‘a’);
var query = words.OrderBy(w => w.Length)         .Select(w => w.Replace('o', 'a'));
Monad
Functional Design Pattern
Return Bind
 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);         } }
  public static class Monad {         public static Monad<T> Create<T>(T value)         {             return new Monad<T>(value);         } }
varmonad = Monad.Create(1); varmonad2 = monad.Bind(v => Monad.Create(v)); Assert.IsInstanceOfType(monad, typeof(Monad<int>)); Assert.AreEqual(monad, monad2); Assert.AreNotSame(monad, monad2);
Identity Monad
 public struct Identity<T> {           T value;         public T Value { get { return value; } }         public Identity(T value)         { this.value = value; }  }
 public static class Identity     {         public static Identity<T> Create<T>(T value)         {             return new Identity<T>(value);         }     }
varresult = from x in Identity.Create(1) select x.ToString(); Assert.AreEqual("1", result.Value);
 public Identity<TResult> Select<TResult> 				(Func<T, TResult> selector) { return Identity.Create(selector(value)); }
var result = from x in Identity.Create(2) from y in Identity.Create(3)                       select x + y; Assert.AreEqual(5, result.Value);
 public Identity<TResult> SelectMany<U, TResult>( Func<T, Identity<U>> selector,  Func<T, U, TResult> resultSelector) {    return Identity.Create(resultSelector(value, 							     selector(value).Value)); }
var result = from x in Identity.Create(2) from y in Identity.Create(3)                       select x + y; Assert.AreEqual(5, result.Value);
Cut the Middle Man
var result = from x in 2                       from y in 3                       select x + y; Assert.AreEqual(5, result);
public static TResultSelectMany<T1, T2, TResult>(      this T1 source,  Func<T1, T2> selector,  Func<T1, T2, TResult> resultSelector) {      return resultSelector(source, selector(source)); }
Tuples
var result = from info in ConferenceInfo() from dates in ConferenceDates() select new {                              Name = info.Item1, StartDate = dates.Item1, EndDate = dates.Item3 };
Assert.AreEqual("IEEE ICCSIT", result.Name); Assert.AreEqual(july9th, result.StartDate); Assert.AreEqual(july11th, result.EndDate);
Continuation Monad
 public class Continuation<R, A> {         private readonlyFunc<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); } }
 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);         }     }
public static Continuation<R, int> Square<R>(int x){     return Continuation.Create<R, int>(() => x * x);}
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);}
Assert.AreEqual(5, Hypotenuse<double>(3, 4).Run(n => n));
Cut the Middle Man
Func<int, int> square = x => x * x; Func<int, double> squareRoot = x => Math.Sqrt(x);
varhypotenuse = from h in square from w in square select squareRoot(h + w); Assert.AreEqual(5, hypotenuse(3, 4));
 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));         }
Func<int, int> f = x => x + 2; var result = from x in f                      select x * 2; Assert.AreEqual(6, result(1));
public static Func<T, TResult2> Select   <T, TResult, TResult2>(   this Func<T, TResult> func, Func<TResult, TResult2> selector)         {             return a => selector(func(a));         }
f  
 public static Func<Int32, Double> Sum(this Func<Int32, Double> func, intstart = 0)         {             return end =>             {                 Double result = default(Double);                 for (int k = start; k <= end; k++)                 {                     result += func(k); }                 return result;             };         }
Factorial
Func<int, int> f = x => x; varfactorial = from x in f.Sum()                          where x != 0                         select x ?? 1; Assert.AreEqual(1, factorial(0)); Assert.AreEqual(6, factorial(3));
  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; }; }
4k=0∞−1k2k+1  
Func<Int32, Double> f =        k =>  4 * Math.Pow(-1, k) / (2.0 * k + 1); varcalculatePi = f.Sum(); Assert.AreEqual(3.14159, calculatePi(200000), 7);
monadic.codeplex.com

More Related Content

What's hot

Lecture08 stacks and-queues_v3
Lecture08 stacks and-queues_v3Lecture08 stacks and-queues_v3
Lecture08 stacks and-queues_v3
Hariz Mustafa
 

What's hot (20)

Priority queues
Priority queuesPriority queues
Priority queues
 
Pj01 4-operators and control flow
Pj01 4-operators and control flowPj01 4-operators and control flow
Pj01 4-operators and control flow
 
Java notes 1 - operators control-flow
Java notes   1 - operators control-flowJava notes   1 - operators control-flow
Java notes 1 - operators control-flow
 
Chapter 7 functions (c)
Chapter 7 functions (c)Chapter 7 functions (c)
Chapter 7 functions (c)
 
The Ring programming language version 1.6 book - Part 35 of 189
The Ring programming language version 1.6 book - Part 35 of 189The Ring programming language version 1.6 book - Part 35 of 189
The Ring programming language version 1.6 book - Part 35 of 189
 
New C# features
New C# featuresNew C# features
New C# features
 
Lecture08 stacks and-queues_v3
Lecture08 stacks and-queues_v3Lecture08 stacks and-queues_v3
Lecture08 stacks and-queues_v3
 
Generics
GenericsGenerics
Generics
 
Chapter 3 Arrays in Java
Chapter 3 Arrays in JavaChapter 3 Arrays in Java
Chapter 3 Arrays in Java
 
Kotlin Perfomance on Android / Александр Смирнов (Splyt)
Kotlin Perfomance on Android / Александр Смирнов (Splyt)Kotlin Perfomance on Android / Александр Смирнов (Splyt)
Kotlin Perfomance on Android / Александр Смирнов (Splyt)
 
Data structure lab manual
Data structure lab manualData structure lab manual
Data structure lab manual
 
Chapter 4 - Classes in Java
Chapter 4 - Classes in JavaChapter 4 - Classes in Java
Chapter 4 - Classes in Java
 
3. Объекты, классы и пакеты в Java
3. Объекты, классы и пакеты в Java3. Объекты, классы и пакеты в Java
3. Объекты, классы и пакеты в Java
 
Gentle Introduction to Functional Programming
Gentle Introduction to Functional ProgrammingGentle Introduction to Functional Programming
Gentle Introduction to Functional Programming
 
Generics in .NET, C++ and Java
Generics in .NET, C++ and JavaGenerics in .NET, C++ and Java
Generics in .NET, C++ and Java
 
Chapter 2 Java Methods
Chapter 2 Java MethodsChapter 2 Java Methods
Chapter 2 Java Methods
 
Lec1
Lec1Lec1
Lec1
 
Java cheatsheet
Java cheatsheetJava cheatsheet
Java cheatsheet
 
Admission for b.tech
Admission for b.techAdmission for b.tech
Admission for b.tech
 
Lec4
Lec4Lec4
Lec4
 

Viewers also liked (7)

Day3 sp3-3 georgetown-panelandreamurta_en
Day3 sp3-3 georgetown-panelandreamurta_enDay3 sp3-3 georgetown-panelandreamurta_en
Day3 sp3-3 georgetown-panelandreamurta_en
 
2015 closing remarks winter_conference_icgfm_maykoski_en
2015 closing remarks winter_conference_icgfm_maykoski_en2015 closing remarks winter_conference_icgfm_maykoski_en
2015 closing remarks winter_conference_icgfm_maykoski_en
 
Moon practical approaches to aid effectiveness
Moon practical approaches to aid effectivenessMoon practical approaches to aid effectiveness
Moon practical approaches to aid effectiveness
 
Day3 sp4 chemonics-icgfm_dec2015_en
Day3 sp4 chemonics-icgfm_dec2015_enDay3 sp4 chemonics-icgfm_dec2015_en
Day3 sp4 chemonics-icgfm_dec2015_en
 
Day3 sp4 chemonics-icgfm_dec2015_fr
Day3 sp4 chemonics-icgfm_dec2015_frDay3 sp4 chemonics-icgfm_dec2015_fr
Day3 sp4 chemonics-icgfm_dec2015_fr
 
2015 closing remarks_winter_conference_icgfm_maykoski_sp
2015 closing remarks_winter_conference_icgfm_maykoski_sp2015 closing remarks_winter_conference_icgfm_maykoski_sp
2015 closing remarks_winter_conference_icgfm_maykoski_sp
 
2015 closing remarks_winter_conference_icgfm_maykoski_fr
2015 closing remarks_winter_conference_icgfm_maykoski_fr2015 closing remarks_winter_conference_icgfm_maykoski_fr
2015 closing remarks_winter_conference_icgfm_maykoski_fr
 

Similar to Monadic Comprehensions and Functional Composition with Query Expressions

Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mark Needham
 
Linq Sanjay Vyas
Linq   Sanjay VyasLinq   Sanjay Vyas
Linq Sanjay Vyas
rsnarayanan
 
Lambda expressions
Lambda expressionsLambda expressions
Lambda expressions
Yuriy Seniuk
 
関数潮流(Function Tendency)
関数潮流(Function Tendency)関数潮流(Function Tendency)
関数潮流(Function Tendency)
riue
 
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Mario Fusco
 
TI1220 Lecture 6: First-class Functions
TI1220 Lecture 6: First-class FunctionsTI1220 Lecture 6: First-class Functions
TI1220 Lecture 6: First-class Functions
Eelco Visser
 

Similar to Monadic Comprehensions and Functional Composition with Query Expressions (20)

Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...
 
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
 
Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#Mixing Functional and Object Oriented Approaches to Programming in C#
Mixing Functional and Object Oriented Approaches to Programming in C#
 
TDC2016POA | Trilha .NET - C# como você nunca viu: conceitos avançados de pro...
TDC2016POA | Trilha .NET - C# como você nunca viu: conceitos avançados de pro...TDC2016POA | Trilha .NET - C# como você nunca viu: conceitos avançados de pro...
TDC2016POA | Trilha .NET - C# como você nunca viu: conceitos avançados de pro...
 
Linq Sanjay Vyas
Linq   Sanjay VyasLinq   Sanjay Vyas
Linq Sanjay Vyas
 
C++ extension methods
C++ extension methodsC++ extension methods
C++ extension methods
 
Let Us Learn Lambda Using C# 3.0
Let Us Learn Lambda Using C# 3.0Let Us Learn Lambda Using C# 3.0
Let Us Learn Lambda Using C# 3.0
 
Lambda expressions
Lambda expressionsLambda expressions
Lambda expressions
 
Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#
 
関数潮流(Function Tendency)
関数潮流(Function Tendency)関数潮流(Function Tendency)
関数潮流(Function Tendency)
 
Les nouveautés de C# 6
Les nouveautés de C# 6Les nouveautés de C# 6
Les nouveautés de C# 6
 
Scala 2 + 2 > 4
Scala 2 + 2 > 4Scala 2 + 2 > 4
Scala 2 + 2 > 4
 
Mixing functional programming approaches in an object oriented language
Mixing functional programming approaches in an object oriented languageMixing functional programming approaches in an object oriented language
Mixing functional programming approaches in an object oriented language
 
Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
 
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...
 
The STL
The STLThe STL
The STL
 
TechTalk - Dotnet
TechTalk - DotnetTechTalk - Dotnet
TechTalk - Dotnet
 
An Introduction to Part of C++ STL
An Introduction to Part of C++ STLAn Introduction to Part of C++ STL
An Introduction to Part of C++ STL
 
Functional Programming In Java
Functional Programming In JavaFunctional Programming In Java
Functional Programming In Java
 
TI1220 Lecture 6: First-class Functions
TI1220 Lecture 6: First-class FunctionsTI1220 Lecture 6: First-class Functions
TI1220 Lecture 6: First-class Functions
 

More from Chris Eargle

Bring your existing .net skills to a cms
Bring your existing .net skills to a cmsBring your existing .net skills to a cms
Bring your existing .net skills to a cms
Chris Eargle
 
Esoteric LINQ and Structural Madness
Esoteric LINQ and Structural MadnessEsoteric LINQ and Structural Madness
Esoteric LINQ and Structural Madness
Chris Eargle
 
Building a multi touch enabled windows 7 point of sale system
Building a multi touch enabled windows 7 point of sale systemBuilding a multi touch enabled windows 7 point of sale system
Building a multi touch enabled windows 7 point of sale system
Chris Eargle
 

More from Chris Eargle (11)

Bring your existing .net skills to a cms
Bring your existing .net skills to a cmsBring your existing .net skills to a cms
Bring your existing .net skills to a cms
 
Hidden Gems of the Sitefinity API Webinar
Hidden Gems of the Sitefinity API WebinarHidden Gems of the Sitefinity API Webinar
Hidden Gems of the Sitefinity API Webinar
 
Amp Up Your Visual Studio Productivity
Amp Up Your Visual Studio ProductivityAmp Up Your Visual Studio Productivity
Amp Up Your Visual Studio Productivity
 
Esoteric LINQ and Structural Madness
Esoteric LINQ and Structural MadnessEsoteric LINQ and Structural Madness
Esoteric LINQ and Structural Madness
 
Easier with visual studio productivity tools
Easier with visual studio productivity toolsEasier with visual studio productivity tools
Easier with visual studio productivity tools
 
One Engine Two Tools
One Engine Two ToolsOne Engine Two Tools
One Engine Two Tools
 
Evolution of Patterns
Evolution of PatternsEvolution of Patterns
Evolution of Patterns
 
2012 Q1 Tools for Better Code
2012 Q1 Tools for Better Code2012 Q1 Tools for Better Code
2012 Q1 Tools for Better Code
 
Deep Dive: MVC Controller Architecture
Deep Dive: MVC Controller ArchitectureDeep Dive: MVC Controller Architecture
Deep Dive: MVC Controller Architecture
 
Building a multi touch enabled windows 7 point of sale system
Building a multi touch enabled windows 7 point of sale systemBuilding a multi touch enabled windows 7 point of sale system
Building a multi touch enabled windows 7 point of sale system
 
C# Ninjitsu
C# NinjitsuC# Ninjitsu
C# Ninjitsu
 

Recently uploaded

Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 

Recently uploaded (20)

TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 

Monadic Comprehensions and Functional Composition with Query Expressions

  • 1. Monadic Comprehensions and Functional Composition with Query Expressions Chris Eargle
  • 3. Oh, that’s a monad!
  • 5. LINQ to Objects from x in new[] {1, 2, 3}from y in new[] {1, 2, 3}select Tuple.Create(x, y) List Monad do x <- [1,2,3]    y <- [1,2,3]    return (x,y)
  • 7. var words = new[] { "the", "quick", "brown", "fox"}; IEnumerable<string> query = from word in words select word;
  • 8. var query = from word in words orderbyword.Length select word;
  • 9. var query = from word in words orderbyword.Length select word.Replace(‘o’, ‘a’);
  • 10. var query = words.OrderBy(w => w.Length) .Select(w => w.Replace('o', 'a'));
  • 11. Monad
  • 14. 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); } }
  • 15. public static class Monad { public static Monad<T> Create<T>(T value) { return new Monad<T>(value); } }
  • 16. varmonad = Monad.Create(1); varmonad2 = monad.Bind(v => Monad.Create(v)); Assert.IsInstanceOfType(monad, typeof(Monad<int>)); Assert.AreEqual(monad, monad2); Assert.AreNotSame(monad, monad2);
  • 18. public struct Identity<T> { T value; public T Value { get { return value; } } public Identity(T value) { this.value = value; } }
  • 19. public static class Identity { public static Identity<T> Create<T>(T value) { return new Identity<T>(value); } }
  • 20. varresult = from x in Identity.Create(1) select x.ToString(); Assert.AreEqual("1", result.Value);
  • 21. public Identity<TResult> Select<TResult> (Func<T, TResult> selector) { return Identity.Create(selector(value)); }
  • 22. var result = from x in Identity.Create(2) from y in Identity.Create(3) select x + y; Assert.AreEqual(5, result.Value);
  • 23. public Identity<TResult> SelectMany<U, TResult>( Func<T, Identity<U>> selector, Func<T, U, TResult> resultSelector) { return Identity.Create(resultSelector(value, selector(value).Value)); }
  • 24. var result = from x in Identity.Create(2) from y in Identity.Create(3) select x + y; Assert.AreEqual(5, result.Value);
  • 26. var result = from x in 2 from y in 3 select x + y; Assert.AreEqual(5, result);
  • 27. public static TResultSelectMany<T1, T2, TResult>( this T1 source, Func<T1, T2> selector, Func<T1, T2, TResult> resultSelector) { return resultSelector(source, selector(source)); }
  • 29. var result = from info in ConferenceInfo() from dates in ConferenceDates() select new { Name = info.Item1, StartDate = dates.Item1, EndDate = dates.Item3 };
  • 30. Assert.AreEqual("IEEE ICCSIT", result.Name); Assert.AreEqual(july9th, result.StartDate); Assert.AreEqual(july11th, result.EndDate);
  • 32. public class Continuation<R, A> { private readonlyFunc<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); } }
  • 33. 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); } }
  • 34. public static Continuation<R, int> Square<R>(int x){ return Continuation.Create<R, int>(() => x * x);}
  • 35. 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);}
  • 38. Func<int, int> square = x => x * x; Func<int, double> squareRoot = x => Math.Sqrt(x);
  • 39. varhypotenuse = from h in square from w in square select squareRoot(h + w); Assert.AreEqual(5, hypotenuse(3, 4));
  • 40. 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)); }
  • 41. Func<int, int> f = x => x + 2; var result = from x in f select x * 2; Assert.AreEqual(6, result(1));
  • 42. public static Func<T, TResult2> Select <T, TResult, TResult2>( this Func<T, TResult> func, Func<TResult, TResult2> selector) { return a => selector(func(a)); }
  • 43. f  
  • 44. public static Func<Int32, Double> Sum(this Func<Int32, Double> func, intstart = 0) { return end => { Double result = default(Double); for (int k = start; k <= end; k++) { result += func(k); } return result; }; }
  • 46. Func<int, int> f = x => x; varfactorial = from x in f.Sum() where x != 0 select x ?? 1; Assert.AreEqual(1, factorial(0)); Assert.AreEqual(6, factorial(3));
  • 47. 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; }; }
  • 49. Func<Int32, Double> f = k => 4 * Math.Pow(-1, k) / (2.0 * k + 1); varcalculatePi = f.Sum(); Assert.AreEqual(3.14159, calculatePi(200000), 7);

Editor's Notes

  1. I am Chris Eargle, C# MVP and INETA Community Champion from Columbia, South Carolina, USA.This presentation takes a functional paradigm and applies it to the C# language, utilizing that language’s features to innovate upon the original pattern. In doing so, we will discover that sometimes strict adherence to a pattern’s construct is not the best route to take. While assimilating ideas from one style of programming into another, we can sometimes find gems that go beyond our original intent.
  2. LINQ, the acronym for Language Integrated Queries, was introduced in .NET 3.5 with Visual Studio 2008; corresponding with C# 3.0. This added native data querying to language through a set of standard query operators implemented through a language feature known as extension methods.
  3. I happen to write a lot about LINQ, and I will occasionally have someone write a comment like this.
  4. What they’re typically comparing LINQ to is the List Monad from Haskell.
  5. This is a comparison between LINQ to Objects in C# and the List Monad in Haskell. C# is wordier than Haskell, but these two statements represent essentially the same functionality.
  6. If you’re unfamiliar with the C# language since the release of 3.0, the syntax on the previous slide may be confusing. It looked more like a SQL query rather than object-oriented code. Query Expressions are a domain specific language within the general purpose language of C#. Some queries are easier read in a SQL syntax, and this DSL provides that.
  7. The first statement creates an array of strings. LINQ to Objects works with any IEnumerable&lt;T&gt;, and the array provides the interface. The query line is an identity query: it returns an identical sequence of strings. Note the return type is IEnumerable&lt;string&gt;.
  8. We can modified the query to sort the returned sequence. Since we don’t want to keep track of the returned type, it’s still IEnumerable&lt;string&gt;, we will use the var keyword and let the compiler figure it out.
  9. In the previous examples, the select statement is required but optimized out by the compiler. We can project the sequence of strings so the strings returned have their o’s replaced with a’s, changing brown to brawn and fox to fax.
  10. The same query can be represented using extension methods rather than a query expression. Note this has a fluent interface. Each method returns an IEnumerable&lt;T&gt; than can then be further operated upon.
  11. LINQ to Objects are often compared to monads, but this term is not very prevalent in the object-oriented world. It stems from category theory, and there are implementations in several languages with specific rules.
  12. However, from a programming perspective I feel it is most useful to look at a monad as a functional design pattern. A monad’s purpose is to provide more functionality to a value. This is sometimes referred to as amplifying. As seen with LINQ to Objects, this pattern provides a data processing chain using a fluent interface.
  13. The two things a monad must implement are the Return and Bind operations. Return amplifies a value to a Monad, and a Bind operation passes the value into a function. It is requisite that a Monad is returned from a Bind operation.
  14. This is a basic representation of a Monad. I used a struct since it represents a value and a series of operations on that value. I implemented a Bind operation which has one parameter: a function that takes in the value type T and returns a Monad of a different type. This means a Monad of type int could return a monad of type string.
  15. In C#, we name out factory methods Create. This Create methods represents the Return operation required by the monad definition. By having this in a separate static class, we can take advantage of generic inference: the compiler will figure out the type by the passed in value.
  16. Explain the code
  17. The identity monad is a canonical monad. It doesn’t do much besides represent the value passed. Unlike the formal definition of a monad, it allows you to retrieve the value it contains.
  18. Here is our initial struct for the Identity monad. It has a read-only property for Value. Please note that monads are meant to be immutable.
  19. Again, we have our Create method representing the Return requirement.
  20. Now, I want to use a binding operation on Identity so that I can use a query expression like this, allowing the projection from an integer Identity to a string Identity.
  21. I can do so by adding this method to the struct. Recall in the previous slides how the syntax changed from the query expression to the method style. We’re providing the method so the compiler can figure out how to interpret the query expression.
  22. Here we have a query expression pulling from two Identities then doing something with their values.
  23. This is implemented by providing the SelectMany method.
  24. Look at this mess though. When we were working with LINQ to objects, it was not necessary to convert things to a List Monad. It appears to me there is a lot of work here for no gain. LINQ to Objects works on any IEnumerable&lt;T&gt;.
  25. I say we refactor by cutting the middle man, and go directly to the source.
  26. By doing so, you can represent any object in a query expression.
  27. This is done by implementing an extension method for any type of T. This method must exist in a static class, and the first parameter is the class it’s extending: T1; which is anything since there are no constraints. Now, I know you’re thinking that expression wasn’t very useful.
  28. But is useful when deal with Tuples. Tuples were introduced in .NET 4, but C# 4 provides no functionality for tuple processing.
  29. With our new extension method, we can retrieve tuples from two methods and construct an anonymous type representing data in a strong fashion within one query expression.
  30. The result is a strongly-typed object.
  31. The continuation monad is more-advanced. It performs some function composition by using continuation-style passing: it passes the results of one function into another.
  32. Here is our definition.
  33. We have a couple of Create methods to get our desired results.
  34. This method is required to set up the test I will show you. It defines a square continuation based upon the passed in value.
  35. This method required for our test contains the query expression. It is creating a continuation for a hypoteneuse.
  36. Our test creates the continuation and runs it, checking the result. The hypoteneuse of 3 and 4 is 5.
  37. The continuation is useful, but that’s a lot of work to set up functional composition. It actually isn’t all that versatile. I say cut the middle man.
  38. I’m going to define the functions for square and squareRoot.
  39. Then I’m going to create a hypotenuse function. We are now achieving functional composition with query expressions. This function can easily be composed again with other functions using other query expressions.
  40. The implementation may appear more difficult, but it is essentially the same as the previous implementation on object. The difference, of course, is that it extends Func&lt;T1, TResult&gt; and returns a function with more parameters.
  41. Let’s try something more simple. This composes two functions together and retains the number of parameters. It is a projection. 1 + 2 = 3 * 2 = 6.
  42. We start with a Func&lt;T, TResult&gt; and end with a Func&lt;T, TResult2&gt;.
  43. Let’s try something more fun. There is no query expression for this in C# but it should work in VB. I will demonstrate it using the method format.
  44. Here is our extension method that create the summation of the function. Since we need observe the value at some point instead of going to infinity, we will request an end parameter for the function.
  45. We can use the summation function to create a factorial.
  46. We take the identity function, x, then create this query expression. The interesting thing to note here is that 0 factorial is actually 1. If x is 0, then it will be null, so we project it to 1 with the null coalescing operator.
  47. This is implemented with the Where extension method. The return type is now dynamic.
  48. Let’s create this function! This function calculates pi.
  49. First, we create the inner function. Then we create the calculatePi function by calling Sum on f. By calling it to k of 200,000, we can accuracy to 5 decimal places very quickly on todays processors.
  50. I began experimenting with this ideas very recently, and released the source code to monadic.codeplex.com. If you’re interested in this, please take a look.