public static void Main()
var t0 = Either<Err, int>
? M.Right<int>(t0).Inspect()
: M.Left<int>(t0 + " not greater than 11.").Inspect();
Console.WriteLine("failed value produces default int32? result - " + t1);
? M.Right<string>("I succeeded because t1 == " + t1).Inspect()
: M.Left<string>("I failed! t1 != 0").Inspect();
Console.WriteLine("'fail' is instance of Either? " + fail.Assert<Either<Err,int>>());
public static Either<Err,T>.Left Left<T> (string v) {
return (Either<Err,T>.Left)Either<Err,T>.Fail(new Err(v));
public static IWrapper<T> Right<T> (T v) {
return Either<Err,T>.Of(v);
public static bool Assert<T>(this object o) {
} catch { return false; }
public static IWrapper<T> Of(T value) {
? (IWrapper<T>) new Just(value)
public class Nothing : Maybe<T>, IWrapper<T> {
public T Value {get;private set;}
public Nothing(){ Value = default(T);}
public IWrapper<R> Select<R>(Func<T,R> _) {
return (IWrapper<R>)this;
public R Chain<R>(Func<T,R> _) {
public class Just: Maybe<T>, IWrapper<T> {
public T Value {get;private set;}
public Just(T value) {Value = value;}
public IWrapper<R> Select<R>(Func<T,R> fn) {
return Maybe<R>.Of(fn(Value));
public R Chain<R>(Func<T,R> fn) {
public class Either<L,R> {
public static IWrapper<R> Of(R v) { return new Right(v); }
public static IWrapper<R> Fail(L v) { return new Left(v); }
public class Left : Either<L,R>, IWrapper<R> {
public R Value { get; private set; }
public L LValue {get; private set; }
public Left(L v) { Value = default(R); LValue = v; }
public IWrapper<U> Select<U> (Func<R,U> _){
return (IWrapper<U>)this;
public U Chain<U> (Func<R,U> _) {
public IWrapper<R> Inspect() {
Console.WriteLine("Left(" + LValue + ")");
public class Right : Either<L,R>, IWrapper<R> {
public R Value { get; private set; }
public Right(R v) { Value = v; }
public IWrapper<U> Select<U> (Func<R,U> fn){
return (IWrapper<U>)Either<L,U>.Of(fn(Value));
public U Chain<U> (Func<R,U> fn) {
public string Message { get; protected set; }
public Err(string msg) {Message = msg;}
public override string ToString(){
public interface IWrapper<T> {
IWrapper<R> Select<R>(Func<T,R> fn);
R Chain<R>(Func<T,R> fn);
public static class IWrapperXts {
public static T Identity<T>(T t) { return t; }
public static T Flat<T>(this IWrapper<T> @this){
return @this.Chain(Identity);
public static IWrapper<T> Inspect<T>(this IWrapper<T> @this) {
Console.WriteLine(string.Format("{0}({1})", @this.GetType().Name,@this.Value));
public static IWrapper<T> Inspect<T>(this Either<Err,T>.Left @this) {
Console.WriteLine(string.Format("{0}({1})", @this.GetType().Name,@this.LValue));