using System.Collections.Generic;
using System.Text.RegularExpressions;
public interface Optional
public interface None : Optional {}
public interface Some<T>: Optional { T Value {get; }}
public static class Option
public static Optional None { get {return new Impl.None_();}}
public static Optional Some<T>(T value) where T : class {
if (value == null) return new Impl.None_(); else return new Impl.Some_<T>(value);}
private static class Impl
public struct None_ : None
public bool IsSome { get { return false;}}
public bool IsNone { get { return true; }}
public struct Some_<T> : Some<T>
public bool IsSome { get { return true;}}
public bool IsNone { get { return false;}}
public T Value { get { return this.value;}}
public static string PrintType(Optional obj)
if (obj is None) return "None";
if (obj is Some<string>) return "Some: " + (obj as Some<string>).Value;
public static void Main(string[] args)
var two = Option.Some("Hola");
Console.WriteLine(PrintType(one));
Console.WriteLine(PrintType(two));