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

Monads in .NET

Matt Stasch
November 06, 2018

Monads in .NET

Matt Stasch

November 06, 2018
Tweet

More Decks by Matt Stasch

Other Decks in Programming

Transcript

  1. Duty duty = null; var cm = bad.FindCrewMember(crewMemberId); if (null

    != cm?.MusterListId) { var musterList = bad.FindMusterList(cm.MusterListId); if (null != musterList) { duty = bad.FindDuty(musterList.DutyId); } }
  2. public class Maybe<T> { private readonly T value; public bool

    HasValue { get; } public Maybe(T value) { this.value = value; this.HasValue = true; } public Maybe() { this.HasValue = false; } public Maybe<U> Bind<U>(Func<T, Maybe<U>> f) { if (HasValue) return f(value); return Maybe.None<U>(); } public T Get() { if(!HasValue) throw new InvalidOperationException(); return value; }
  3. • Lack of NULLs in code! → better! • NULL

    is always a bug → cleaner! • Explicite expression that something can have no value • Easier code to reason about - even with monad :)
  4. • Nullable<T> — represents a T that could be null

    (almost Maybe<T>) • Func<T> — represents a T that can be computed on demand • Lazy<T> — represents a T that can be computed on demand once, then cached • Task<T> — represents a T that is being computed asynchronously and will be available in the future, if it isn’t already https://ericlippert.com/2013/02/25/monads-part-two/
  5. public static Nullable<U> Bind<T,U>(Nullable<T> source, Func<T, Nullable<U>> func) where T:

    struct where U: struct { if(source == null || !source.HasValue) { return new Nullable<U>(); } return func(source.Value); }
  6. Monad is an “Amplifier”. An “amplifier” is something that increases

    the representational power of their “underlying” type. - Wes Dyer
  7. • Maybe • Either (or ValidationMonad) • Try • State,

    Writer, Reader • Monadic Parsers • ... https://github.com/louthy/csharp-monad
  8. var duty = from cm in better.FindCrewMember(crewMemberId) from id in

    cm.MaybeMusterListId from ml in better.FindMusterList(id, cm) from dt in better.FindDuty(ml.DutyId) select dt;
  9. Links • https://www.slideshare.net/mariofusco/monadic-java • https://mikhail.io/2018/07/monads-explained-in-csharp-again/ • https://channel9.msdn.com/shows/Going+Deep/Brian-Beckman-The-Zen-of-Expressing-State-The-State-Monad/ • https://lorgonblog.wordpress.com/2007/12/02/c-3-0-lambda-and-the-first-post-of-a-series-about-monadic-parser-c ombinators/

    • https://miklos-martin.github.io/learn/fp/2016/03/10/monad-laws-for-regular-developers.html • https://fsharpforfunandprofit.com/rop/ • https://ericlippert.com/category/monads/ • https://stackoverflow.com/questions/2704652/monad-in-plain-english-for-the-oop-programmer-with-no-fp-backgr ound