public abstract class Either { private Either() { } abstract public T Fold(Func leftFold, Func rightFold); abstract public bool HasError { get; } public sealed class Left : Either { public readonly A error; public Left(A error) { this.error = error; } public override T Fold(Func leftFold, Func rightFold) { return leftFold(error); } public override bool HasError { get { return true; } } } public sealed class Right : Either { public readonly B value; public Right(B value) { this.value = value; } public override T Fold(Func leftFold, Func rightFold) { return rightFold(value); } public override bool HasError { get { return false; } } } public static Either left(A error) { return new Left(error); } public static Either right(B value) { return new Right(value); } }