Last active
August 29, 2015 14:20
-
-
Save gszeliga/2bf86e309b4a99c3d8bc to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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