public static void Main()
var test = (IWrapper<int>)Either<int>.Of(1);
var t2 = test.Select(i => i*2);
var val = t2.Chain(b => b*b);
: new Either<int>.Left("value not less than 4.");
Console.WriteLine(test.Inspect());
Console.WriteLine(t2.Inspect());
Console.WriteLine(fail.Inspect());
public string Message { get; private set; }
public Error(string msg){Message = msg;}
public override string ToString() {return Message;}
public static Either<T> Of(T v) { return new Right(v); }
} else if(this is Right){
Either<T>, IWrapper<Error> {
public Left(string value) {Value = new Error(value);}
public Error Value { get; private set;}
public IWrapper<R> Select<R>(Func<Error,R> _){
return (IWrapper<R>)this;
public R Chain<R>(Func<Error,R> _) {
public T Value { get; private set;}
public Right(T value) { Value = value; }
public IWrapper<R> Select<R>(Func<T,R> fn) {
return (IWrapper<R>)Either<R>.Of(fn(Value));}
public R Chain<R>(Func<T,R> fn){
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>(this T t){
public static T Flat<T>(this IWrapper<T> @this) {
return @this.Chain<T>(Identity);}
public static string Inspect<T>(this IWrapper<T> @this) {
return string.Format("{0}({1})",@this.GetType().Name, @this.Value);}
public static IWrapper<T> AsWrapper<T>(this IWrapper<T> @this) {
return (IWrapper<T>)@this;