Maybe with Linq

Not long ago I wrote a post on using Maybe not null. In that post however I did not provide an implementation of the Maybe monad. There are a few floating around the internet (including the Maybe package on nuget) but it’s fun and I think it’s worth showing my own just for the sake of it. Here is my simplified version of the Maybe monad in C#:

Download on skydrive

using System;

namespace System.Monads
{
public interface IMaybe<T>
{
bool HasValue { get; }
T Value { get; }
}

public class Maybe<T> : IMaybe<T>
{
public static readonly Maybe<T> Nothing = new Maybe<T>();

public bool HasValue { get; private set; }
public T Value { get; private set; }

private Maybe()
{
HasValue = false;
Value = default(T);
}

internal Maybe(T value)
{
HasValue = !object.Equals(value, null);
Value = value;
}

public static implicit operator Maybe<T>(T value)
{
return new Maybe<T>(value);
}
}

public static class Maybe
{
public static IMaybe<T> ToMaybe<T>(this T value)
{
IMaybe<T> maybe = value as IMaybe<T>;
if (maybe != null)
return maybe;

return new Maybe<T>(value);
}

// Monadic Bind operator
public static IMaybe<TResult> Bind<TSource, TResult>(this IMaybe<TSource> m, Func<TSource, IMaybe<TResult>> f)
{
if (!m.HasValue)
return Maybe<TResult>.Nothing;

return f(m.Value);
}

public static IMaybe<TResult> Select<TSource, TResult>(this IMaybe<TSource> m, Func<TSource, TResult> f)
{
return m.Bind(x => f(x).ToMaybe());
}

public static IMaybe<TResult> SelectMany<TSource, TResult>(this IMaybe<TSource> m, Func<TSource, TResult> f)
{
return m.Bind(x => f(x).ToMaybe());
}

public static IMaybe<TResult> SelectMany<TSource, TMaybe, TResult>(this IMaybe<TSource> m, Func<TSource, IMaybe<TMaybe>> f, Func<TSource, TMaybe, TResult> g)
{
return m.Bind(x => f(x).Bind(y => g(x, y).ToMaybe()));
}

// Simplified form, check for null or use Nullable<T>.HasValue instead of Maybe.
// This form is not as strictly correct but it results in a more useable syntax in C#.
public static TResult Select<TSource, TResult>(this TSource m, Func<TSource, TResult> f)
{
return m.ToMaybe().Bind(x => f(x).ToMaybe()).Value;
}

public static TResult SelectMany<TSource, TResult>(this TSource m, Func<TSource, TResult> f)
{
return m.ToMaybe().Bind(x => f(x).ToMaybe()).Value;
}

public static TResult SelectMany<TSource, TMaybe, TResult>(this TSource m, Func<TSource, TMaybe> f, Func<TSource, TMaybe, TResult> g)
{
return m.ToMaybe().Bind(x => f(x).ToMaybe().Bind(y => g(x, y).ToMaybe())).Value;
}
}
}

It’s a pretty simple implementation, I tried to stay true to it’s monadic nature by creating the Bind method with the correct function signature but I also created a number of Select and SelectMany functions which allow you to use Linq syntax to bind to your Maybe monad.
 
I also created a few non-maybe functions which allow you to bind to regular objects without needing to wrap it in a maybe object. If your object is a value type then it will never be null anyway and if you use a reference type (including Nullable<T>) then you do a null check on the result instead of HasValue check. Strictly speaking that isn’t the purest version of a Monad but with the syntax limitations of C# I think it results in the cleanest usage possible. It’s a reasonable compromise.
 
Here are some examples of how you can use it:
// Most verbose form, most strictly correct
var m1 = 5
.ToMaybe()
.Select(x => x + 10);

// prettier but result will be of type int
var m2 = from x in 5
select x + 10;

// if you use nullable structs, it's pretty and result will be HasValue=false if anything is null
var m3 = from x in (int?)5
from y in (int?)10
select x + y;

// identical to above except the long form, with a null
int? five = 5;
int? ten = null;
var m4 = five.Select(x => ten.SelectMany(y => x + y));

// Pretty form for reference types, check for null on result.
var m5 = from x in "testing"
from y in (string)null
select x + y;

// Maybe form of above, check for HasValue
var m6 = from x in "testing".ToMaybe()
from y in ((string)null).ToMaybe()
select x + y;

// Longer select chains
var m7 = from x in new Example()
from y in x.Inner
from z in y.Inner
select z.Value;

var m8 = from x in new Example { Inner = new Example { Inner = new Example { Value = "success!" } } }
from y in x.Inner
from z in y.Inner
select z.Value;

Console.WriteLine("m1: {0}->{1}", m1.HasValue, m1.Value);
Console.WriteLine("m2: True->{0} (non-nullable)", m2);
Console.WriteLine("m3: {0}->{1}", m3.HasValue, m3.Value);
Console.WriteLine("m4: {0}", m4.HasValue);
Console.WriteLine("m5: {0}", m5 != null);
Console.WriteLine("m6: {0}", m6.HasValue);
Console.WriteLine("m7: {0}", m7 != null);
Console.WriteLine("m8: {0}->{1}", m8 != null, m8);
Console.ReadKey(true);

Scrum in 5 Minutes | Stephen Walther

Scrum in 5 Minutes | Stephen Walther.

This is the best description of Scrum (the software development methodology) I have read so far. It’s just long enough to have details and just short enough to be able to read it all without going over your TL;DR threshold.

This is pretty similar to what we do at work so I can associate with the whole post. I do have a few problems with scrum however. But I am very glad to read the description about how story points are designed to solve the problem between the need for estimates and the difficulty of giving accurate estimates.

Atheist Voices of Minnesota

I recently contributed a chapter to what I think is a very remarkable anthology of short stories written by fellow Minnesota Atheists. It was a very nice experience to finally be able to write about the unusual path I have taken to both arrive in Minnesota and become and atheist. My contribution was a fairly personal story, partly about my time in a religious cult but also how it felt to loose my faith and the thought process that lead me to the conclusion that there is no God. It felt good to share it publicly and I hope you enjoy it.  The goal of the book was to provide positive and inspirational stories from regular people to show everyone that Atheists are just people too and to help provide some insight into what makes us tick. And maybe you are an atheist too? If so, with this book you may find a community of like minded people waiting for you.

The book is now officially published and available in print or ebook from various book stores. Please head over to the website for more details:

http://www.freethoughthouse.com/atheist-voices-of-mn.html

Image Cover