Skip to content

Instantly share code, notes, and snippets.

@carstenlenz
Created March 1, 2012 11:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save carstenlenz/1949162 to your computer and use it in GitHub Desktop.
Save carstenlenz/1949162 to your computer and use it in GitHub Desktop.
Option Type for C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace OptionType
{
public abstract class Option<T>
{
public abstract T Value { get; }
public abstract bool IsEmpty { get; }
public Option<TRet> Bind<TRet>(Func<T, TRet> fun)
{
if (IsEmpty)
{
return None<TRet>.INSTANCE;
}
return fun(Value).AsOption();
}
public void Bind(Action<T> fun)
{
if (!IsEmpty)
{
fun(Value);
}
}
public T GetOrElse(T defaultValue)
{
if (IsEmpty)
{
return defaultValue;
}
return Value;
}
}
public static class Options
{
public static Option<TOption> AsOption<TOption>(this TOption value)
{
if (value == null)
{
return None<TOption>.INSTANCE;
}
return new Some<TOption>(value);
}
}
public sealed class Some<T> : Option<T>
{
private readonly T value;
public Some(T value)
{
if (value == null)
{
throw new ArgumentNullException("value", "value is expected - use None instead of Some");
}
this.value = value;
}
public override T Value
{
get { return value; }
}
public override bool IsEmpty
{
get { return false; }
}
}
public sealed class None<T> : Option<T>
{
internal static readonly None<T> INSTANCE = new None<T>();
public override T Value
{
get { throw new NotSupportedException("No value available"); }
}
public override bool IsEmpty
{
get { return true; }
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment