Skip to content

Instantly share code, notes, and snippets.

@dtchepak
Last active August 29, 2015 13:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dtchepak/9818021 to your computer and use it in GitHub Desktop.
Save dtchepak/9818021 to your computer and use it in GitHub Desktop.
Quick sketch of Either type in C#
public class Either<TLeft, TRight>
{
private readonly bool isLeft;
private readonly TLeft left;
private readonly TRight right;
private Either(bool isLeft, TLeft a, TRight b)
{
this.isLeft = isLeft;
this.left = a;
this.right = b;
}
public static Either<A, B> Left<A, B>(A left)
{
return new Either<A, B>(true, left, default(B));
}
public static Either<TA, TB> Right<TA, TB>(TB right)
{
return new Either<TA, TB>(false, default(TA), right);
}
public T Fold<T>(Func<TLeft, T> onLeft, Func<TRight, T> onRight)
{
return isLeft ? onLeft(left) : onRight(right);
}
public Either<TLeft, T> SelectMany<T>(Func<TRight, Either<TLeft, T>> f)
{
return Fold(Left<TLeft, T>, f);
}
public Either<TLeft, TResult> SelectMany<T, TResult>(Func<TRight, Either<TLeft, T>> f, Func<TRight, T, TResult> selector)
{
return SelectMany(x => f(x).Select(t => selector(right, t)));
}
public Either<TLeft,T> Select<T>(Func<TRight, T> f)
{
return SelectMany(x => Right<TLeft,T>(f(x)));
}
public Either<TA, TB> BiMap<TA, TB>(Func<TLeft, TA> onLeft, Func<TRight, TB> onRight)
{
return Fold(x => Left<TA,TB>(onLeft(x)), x => Right<TA,TB>(onRight(x)));
}
public Either<TRight, TLeft> Swap()
{
return Fold(Right<TRight, TLeft>, Left<TRight, TLeft>);
}
public static Either<Exception, T> Try<T>(Func<T> f)
{
try { return Right<Exception, T>(f()); }
catch (Exception ex) { return Left<Exception, T>(ex); }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment