Skip to content

Instantly share code, notes, and snippets.

@nkoneko
Created September 5, 2014 02:26
Show Gist options
  • Save nkoneko/ef59ef9d3272f29568cc to your computer and use it in GitHub Desktop.
Save nkoneko/ef59ef9d3272f29568cc to your computer and use it in GitHub Desktop.
namespace Monad
{
interface IEither<out E, V> {}
public class Either<E, V> : IEither<E, V>
{
public readonly E Error;
public V Value { get; private set; }
public bool HasError { get; private set; }
public Either(E error)
{
HasError = true;
Error = error;
Value = default(V);
}
public Either(V value)
{
HasError = value == null;
Value = value;
Error = default(E);
}
}
public static class EitherAsMonadInstance
{
public static Either<E, V> Return<E, V>(this E error)
{
return new Either<E, V>(error);
}
public static Either<E, V> Return<E, V>(this V value)
{
return value != null ? new Either<E, V>(value) : new Either<E, V>(default(E));
}
public static Either<E, V> Select<E, U, V>(this Either<E, U> ma, Func<U, V> f)
{
return ma.HasError ?
new Either<E, V>(ma.Error) :
new Either<E, V>(f(ma.Value));
}
public static Either<E, U> SelectMany<E, V, U>(this Either<E, V> ma, Func<V, Either<E, U>> k)
{
return ma.HasError ?
new Either<E, U>(ma.Error) :
k(ma.Value);
}
public static Either<E, W> SelectMany<E, U, V, W>(this Either<E, U> ma, Func<U, Either<E, V>> k, Func<U, V, W> p)
{
return ma.HasError ?
new Either<E, W>(ma.Error) :
k(ma.Value).HasError ?
new Either<E, W>(k(ma.Value).Error) :
new Either<E, W>(p(ma.Value, k(ma.Value).Value));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment