C# : The null object pattern and the poor man's Maybe Monad
Lots of people have re-invented the Maybe monad in C#, as a simple search will show, usually as a way of bypassing null checking if
statements and to be able to write code like
But we have the tools given to us already if we observe that null
has no type -- as we can see when
reports a length of zero!
So our Some<T>
is just a length-1 IEnumerable<T>
; and None<T>
an empty one -- the null object pattern, in fact.
For the price of having to specify types at each stage -- as we would anyway have had to in the past for declaring intermediate the values to test against null -- we can use existing methods to finesse the null check. Returning to the borrowed example, it would be
The monadic return monad extraction operation is just FirstOrDefault()
; which is fine for reference types. Value types are different in any case as we wouldn't be null checking those -- as the later steps in a chain though, stopping at the filtering to the value type and making an Any
test may be preferred.
Looking at value types, switching to this example, the code looks like:
which leaks a little bit in that we have to do the monadic return monad extraction by hand at the end, but otherwise behaves exactly as the explicit monad implementation.
1 comment :
Interestingly, I posted exactly about this just around a week ago: http://bugsquash.blogspot.com/2011/10/poor-man-option-type-in-c.html
Just a couple of minor corrections: monadic return is the lifting of pure values into the monad, so it's actually the array constructor, not FirstOrDefault() (i.e a function T -> M instead of M -> T).
First() is better here than FirstOrDefault(), as it makes more patent the partiality of the function... just like Haskell's fromJust and F#/OCaml's Option.get , it fails when there is no value.
Post a Comment