Skip to content

Instantly share code, notes, and snippets.

@gszeliga
Last active August 29, 2015 14:20
Show Gist options
  • Save gszeliga/2bf86e309b4a99c3d8bc to your computer and use it in GitHub Desktop.
Save gszeliga/2bf86e309b4a99c3d8bc to your computer and use it in GitHub Desktop.
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.NoSuchElementException;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
public abstract class Either<L,R> {
public static <LL, RR> Either<LL, RR> left(final LL left) {
return new Left<>(left);
}
public static <LL, RR> Either<LL, RR> right(final RR right) {
return new Right<>(right);
}
public abstract boolean isRight();
public abstract boolean isLeft();
public abstract L getLeft();
public abstract R getRight();
public final Left<L,R> left(){
return (Left<L,R>)this;
}
public final Right<L,R> right(){
return (Right<L,R>)this;
}
public final <X> Either<L,X> mapR(Function<R,X> f)
{
if(isRight())
{
return new Right<>(f.apply(getRight()));
}
else
{
return (Either<L,X>)this;
}
}
public final void ifRight(Consumer<R> f)
{
if(isRight())
{
f.accept(getRight());
}
}
public final <X> Either<L,X> flatMapR(Function<R,Either<L,X>> f)
{
if(isRight())
{
return f.apply(getRight());
}
else
{
return (Either<L,X>)this;
}
}
public final <LL,RR> Either<LL,RR> fold(Function<L, LL> left, Function<R, RR> right)
{
if(isRight())
return (Either<LL,RR>) new Right<L,RR>(right.apply(getRight()));
else
{
return (Either<LL,RR>) new Left<LL,R>(left.apply(getLeft()));
}
}
@EqualsAndHashCode
@ToString
public static class Left<L,R> extends Either<L,R>
{
private final L value;
Left(L left)
{
value = left;
}
public <X> Left<X,R> map(Function<L, X> map)
{
return new Left(map.apply(value));
}
@Override
public boolean isRight() {
return false;
}
@Override
public boolean isLeft() {
return true;
}
@Override
public L getLeft() {
return value;
}
@Override
public R getRight() {
throw new NoSuchElementException("No value present");
}
public L orElse(Supplier<L> supplier)
{
return (value != null)? value : supplier.get();
}
}
@EqualsAndHashCode
@ToString
public static class Right<L,R> extends Either<L,R>
{
private final R value;
Right(R right)
{
value = right;
}
public <X> Right<L,X> map(Function<R, X> map)
{
return new Right(map.apply(value));
}
@Override
public boolean isRight() {
return true;
}
@Override
public boolean isLeft() {
return false;
}
@Override
public L getLeft() {
throw new NoSuchElementException("No value present");
}
@Override
public R getRight() {
return value;
}
public R orElse(Supplier<R> supplier)
{
return (value != null)? value : supplier.get();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment