Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Don't Fear the Monads

Don't Fear the Monads

Love functional programming for the simplicity that it brings.

But at the same time, I realize that learning functional programming is a challenging process. FP comes with a baggage of unfamiliar vocabulary that can be daunting for somebody coming from an object-oriented language like C#.

Numerous attempts were made to explain monads in simple definitions; and monad tutorials have become a genre of its own. And yet, times and times again, they fail to enlighten the readers, this is my attempt to fix that.

Fernando Franco Gíraldez

December 03, 2018
Tweet

More Decks by Fernando Franco Gíraldez

Other Decks in Programming

Transcript

  1. 3

  2. Functional programing is a style of building the structure and

    elements of programs that threads computation as evaluation of mathematical functions and avoid changing-state and mutable data What is Functional Programming 5 • Higher Order Fuctions • Referencial Transparency • Lazy evaluation • Inmutable data • Abstractions
  3. Show me the code 6 namespace Core.Monad { public class

    Speaker { Talk NextTalk() => /* ... */ } public class Talk { Conference GetConference() => /* ... */ } public class Conference { City GetCity() => /* ... */ } public class City { } }
  4. Show me the code - Imperative form 7 static City

    NextTalkCity(Speaker speaker) { Talk talk = speaker.NextTalk(); Conference conf = talk.GetConference(); City city = conf.GetCity(); return city; }
  5. Show me the code - fluent form 8 static City

    NextTalkCity(Speaker speaker) { return speaker .NextTalk() .GetConference() .GetCity(); }
  6. 9

  7. Null Handling 10 namespace Core.Monad { public struct Speaker {

    public Nullable<Talk> NextTalk() => /* ... */ } public struct Talk { public Nullable<Conference> GetConference() => /* ... */ } public struct Conference { public Nullable<City> GetCity() => /* ... */ } public struct City { }
  8. Null Handling – Ugly as hell 11 static Nullable<City> NextTalkCity(Speaker

    speaker) { Nullable<Talk> talk = speaker.NextTalk(); if (!talk.HasValue) return null; Nullable<Conference> conf = talk.Value.GetConference(); if (!conf.HasValue) return null; Nullable<City> city = conf.Value.GetCity(); return city; }
  9. Null Handling – Null Propagation Operator 12 static Nullable<City> NextTalkCity(Speaker

    speaker) { return speaker .NextTalk() ?.GetConference() ?.GetCity(); }
  10. Collections 13 namespace Core.Monad { public class Speaker { public

    List<Talk> NextTalk() => /* ... */ } public class Talk { public List<Conference> GetConference() => /* ... */ } public class Conference { public List<City> GetCity() => /* ... */ } public class City { } }
  11. Collections - foreach version 14 static List<City> NextTalkCity(Speaker speaker) {

    var cities = new List<City>(); foreach (Talk talk in speaker.NextTalk()) foreach (Conference conference in talk.GetConference()) foreach (City city in conference.GetCity()) cities.Add(city); return cities; }
  12. Collections - LINQ version 15 static List<City> NextTalkCity(Speaker speaker) {

    return speaker .NextTalk() .SelectMany(talk => talk.GetConference()) .SelectMany(conference => conference.GetCity()) .ToList(); }
  13. Collections - LINQ version 16 static List<City> NextTalkCity(Speaker speaker) {

    return speaker .NextTalk() .SelectMany(talk => talk .GetConference() ).SelectMany(conference => conference .GetCity() ).ToList(); }
  14. Asynchrony 17 namespace Core.Monad { public struct Speaker { public

    Task<Talk> NextTalk() => /* ... */ } public struct Talk { public Task<Conference> GetConference() => /* ... */ } public struct Conference { public Task<City> GetCity() => /* ... */ } public struct City { } }
  15. Asynchrony - ContinueWith 18 static Task<City> NextTalkCity(Speaker speaker) { return

    speaker .NextTalk() .ContinueWith(task => task.Result.GetConference()) .Unwrap() .ContinueWith(conference => conference.Result.GetCity()) .Unwrap(); }
  16. Asynchrony - ContinueWith 19 static Task<City> NextTalkCity(Speaker speaker) { return

    speaker .NextTalk() .ContinueWith(task => task.Result .GetConference() ).Unwrap().ContinueWith(x => x.Result .GetCity() ).Unwrap(); }
  17. Null Handling – Null Propagation Operator 20 static Nullable<City> NextTalkCity(Speaker

    speaker) { return speaker .NextTalk() ? .GetConference() ? .GetCity(); }
  18. Collections - LINQ version 21 static List<City> NextTalkCity(Speaker speaker) {

    return speaker .NextTalk() .SelectMany(talk => talk .GetConference() ).SelectMany(x => x .GetCity() ).ToList(); }
  19. Chainnable 24 static Chainable<City> NextTalkCity(Speaker speaker) { return speaker .NextTalk()

    .AddStep(talk => talk.GetConference()) .AddStep(conference => conference.GetCity()); }
  20. 26

  21. Monads! 27 static Monad<City> NextTalkCity(SpeakerRepository repository) { return repository.loadSpeaker() .FlatMap(speaker

    => speaker.NextTalk()) .FlatMap(talk => talk.GetConference()) .FlatMap(conference => conference.GetCity()); }
  22. Abstractions - Imperative Programing 28 • simple data values •

    Sentences one after the other • Functions as remove duplication public void HandleData(String data) { data = ""; }
  23. Abstractions - Object Oriented Programming 29 • Object • Abstraction

    and Encapsulation • Generics public class List<T> : ICollection<T>, IEnumerable<T>, IList<T
  24. • monads explained in C# -> https://tinyurl.com/y77wmpvv • F# for

    fun and profit -> https://tinyurl.com/hha9ozu • Functional error handling -> https://tinyurl.com/yaynoq8v • Category Theory for programers -> https://tinyurl.com/y8zehgas References 31