Maybe Monad Extensions
I learned a lot from my last foray into implementing my own Maybe Monad. Apparently, it got noticed by and was actually useful to Derick Bailey, as it was one of the resources he used in his own personal exploration into Monads. Of course, Derick did the topic a bit more justice, as he has a propensity to do.
Nonetheless, I have done as I said I would and reworked my Murray Monads into a cleaner, more concise implementation using extension methods, much like the implementation I introduced from Dmitri Nesteruk in the last post. So without further ado, I’d like to introduce you to the MaybeMonadExtensions.
Monads 2.0 - “These Go To Eleven”
If you want to get an introduction to what Monads are and how I got to where I am today with this little library, then you really should check out the previous post on this topic. I will however give a few brief code samples to show you what it can do to tidy up all those null checks using the Maybe Monad.
Here is code we tend to write all the time:
string postCode; if (person != null) { if (HasMedicalRecord(person) && person.Address != null) { CheckAddress(person.Address); if (person.Address.PostCode != null) postCode = person.Address.PostCode.ToString(); else postCode = "UNKNOWN"; } }
It can look like this with some Maybe Monad love:
string postalCode = person.If(HasMedicalRecord) .Access(p => p.Address) .Apply(CheckAddress) .Access(a => a.PostCode) .Convert(pc => pc.ToString(), "UNKNOWN");
I know! Groovy, huh?!
The source can be found here: http://bitbucket.org/murrayondotnet/maybemonadextensions/
Let me know if you put this to good use!
However, even Rx is sharing many LINQ operators with its IObservable & IQbservable monads.
So we already have 4 different monads (IEnumerable, IQueryable, IObservable, IQbservable) using those operators. I don't think any more would hurt :-)
Great point though, and it does make me second guess my chosen names a bit. I did like Derick's method names too (especially just plain old "Get"). Thanks for posting!
Why didn't you choose the Linq terminology here?
I'd write your example as this (Linq + Rx's Do operator):
string postalCode = person.Where(HasMedicalRecord)
.Select(p => p.Address)
.Do(CheckAddress)
.Select(a => a.PostCode)
.Select(pc => pc.ToString(), "UNKNOWN");