Thursday, February 20, 2014

In Search of Maybe in C# - Part II

In my last post I wrote that I'd like to have an implementation of the Maybe monad in C#, and I explored how to use the F# implementation - FSharpOption in C#.

In this post I'll show a quick implementation of Maybe in C#, I'll call it Option - as was noted in some of the comments on the last post this turns out to be quite simple. I left off last time mentioning that it's nice when Option can act somewhat as a collection. That turns out to be easy too. Just watch as I walk through it.

Implementing basic Option
First of all the Option type is a type that can either be Some or None. That is simply:


which allows for creating options like this:


So far so good. This all there is to a basic Maybe monad in C#.

Simulate pattern matching on Option
As argued in the last post I'd like be able to do something similar to pattern matching over my Option type. It's not going be nearly as strong as F#s or Scalas pattern matcing, but it's pretty easy to support these scenarios:


All that takes is adding to simple methods on the Option type that each check the value of the Option instance and calls the right callback. In other words just add these two methods to the Option class above:


That's matching sorted.

Act like a collection
Now I also want Option to be usable as though it was a collection. I want that in order to be able to write chains of linq transformations and then just pass Options through that. To illustrate, I want to able to do this:


This means that Option must now implement IEnumerable<T>, which is done like so:


And to be able to get back an option from a IEnumerable with 0 or 1 element:


which is useful in order to be able to do the matching from above.

All together
Putting it all together the Option type becomes:


Not too hard.

Wednesday, January 29, 2014

In Search of Maybe in C#

One of the things working in Scala has taught me about C# is that the maybe monad is nicer than null.

In case you're not sure what the maybe monad is: It's a generic type that either contains a value or not. In Scala as well as in F# this type is called Option and can be either Some - in which case it contains a value - or None - in which case it doesn't. This allows you to represent the absence of a value in an explicit way visible to the compiler, since Option<T> is a separate type from T. This turns out to be a whole lot stronger than relying on null to represent the absence of a value. I'll point you to an article about F#'s Option for more explanation on why.

Functional languages will usually let you pattern match over Option, making it very easy to clearly differentiate the case of Some from the case of None. In F# this look like so:


In C# we don't have this. The closest thing is Nullable<T>, but that doesn't work over reference types. But is Nullable<T> really the closest thing in C# to Option? - NO. As was pointed out to me in a recent email exchange the F# Option type is available in C# too.

Let's see if we can redo the above F# code in C#. First the declaration the name variable:


The F# Option type is part of the FSharp.Core assembly and the is actually called FSharpOption. Hence the line above.
On to the nameOrApology variable:


Not nearly as clear as the F# counterpart. What's in the if part; what's in the else part. Not nearly as clear to me as the pattern matching in F#.
We can do better, using this little helper extension function:


Which let's us initialize nameOrApology like this:


Now the two outcomes - a value inside the Option or no value - are much more clear to me.

This is OK. Although the name, FSharpOption, is not too nice. Some of the method names - e.g. get_IsSome - aren't nice either. More importantly: Another thing Scala taught me is that it's nice if Option can be used in place of a collection. But that's for another post.

Sunday, January 19, 2014

Slides from Warm Crocodile Talk

At the awesome Warm Crocodile Developers Conference I did a talk under the title "Does Your Architecture Enable Flow?". These are the slides from my talk. As always the slides make less sense without the words, so YMMV.