Skip to content

Instantly share code, notes, and snippets.

@JamesTryand
Created September 3, 2015 14:07
Show Gist options
  • Save JamesTryand/3377403d59a0d7d15962 to your computer and use it in GitHub Desktop.
Save JamesTryand/3377403d59a0d7d15962 to your computer and use it in GitHub Desktop.
C# OptionType
using System;
namespace Options {
public abstract class Option<T>
{
public class Some : Option<T>
{
public T Value { get; private set; }
public Some(T value)
{
Value = value;
}
public bool HasValue { get { return Value != null; }}
}
public class None : Option<T>
{
public bool HasValue { get { return false; } }
}
public TOut Match<TOut>(Func<T, TOut> valueProjection, Func<TOut> alternativeProjection)
{
if (this is Some)
{
var t1 = (Some)this;
return valueProjection(t1.Value);
}
else if (this is None)
{
None t2 = (None)this;
return alternativeProjection();
}
else throw new ArgumentException();
}
}
public static class OptionExtensions
{
public static Option<B> Bind<A, B>(this Option<A> a, Func<A, Option<B>> func)
{
return a is Option<A>.Some
? func(((Option<A>.Some) a).Value)
: new Option<B>.None();
}
public static Option<C> SelectMany<A, B, C>(this Option<A> a, Func<A, Option<B>> func, Func<A, B, C> select)
{
return a.Bind(aval => func(aval).Bind(bval => select(aval, bval).ToOption()));
}
public static Option<T> ToOption<T>(this T value) { return new Option<T>.Some(value); }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment