Last active
March 13, 2016 18:48
-
-
Save gszeliga/9cbf6751061d84f306af to your computer and use it in GitHub Desktop.
Type inference thingy
This file contains 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
package com.gszeliga.tictattoe.handlers; | |
import java.util.NoSuchElementException; | |
import java.util.Optional; | |
import java.util.Random; | |
import java.util.function.BiFunction; | |
import java.util.function.Consumer; | |
import java.util.function.Function; | |
import java.util.function.Supplier; | |
import static com.gszeliga.tictattoe.handlers.Sample.Either.left; | |
/** | |
* Created by guillermo on 13/03/16. | |
*/ | |
public class Sample { | |
private static Function<Integer, Either<Exception, Integer>> doSomethingElse = Either::right; | |
private static final Random r = new Random(); | |
public static void main(String[] args) { | |
Either<Exception, Integer> result = | |
Optional | |
.of(r.nextInt()) | |
.map(n -> { | |
if(n % 2 == 0){ | |
return doSomethingElse.apply(n); | |
} | |
else | |
{ | |
//DO NOT REMOVE TYPE PARAMETER | |
return Either.<Exception, Integer>left(new Exception("Not even!")); | |
} | |
}).orElse(left(new Exception("Foo"))); | |
} | |
public static 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 static <LL, RR,T> Either<LL, T> appendRight(final Either<LL, RR> v1, | |
final Either<LL, RR> v2, | |
final BiFunction<RR,RR,T> append) | |
{ | |
return right(append.apply(v1.getRight(), v2.getRight())); | |
} | |
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 <T> T fold(Function<L, T> left, Function<R, T> right) | |
{ | |
if(isRight()) | |
return right.apply(getRight()); | |
else | |
{ | |
return left.apply(getLeft()); | |
} | |
} | |
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(); | |
} | |
@Override | |
public boolean equals(Object o) { | |
if (this == o) return true; | |
if (o == null || getClass() != o.getClass()) return false; | |
Left<?, ?> left = (Left<?, ?>) o; | |
return value.equals(left.value); | |
} | |
@Override | |
public int hashCode() { | |
return value.hashCode(); | |
} | |
@Override | |
public String toString() { | |
return "Left{" + | |
"value=" + value + | |
'}'; | |
} | |
} | |
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(); | |
} | |
@Override | |
public boolean equals(Object o) { | |
if (this == o) return true; | |
if (o == null || getClass() != o.getClass()) return false; | |
Right<?, ?> right = (Right<?, ?>) o; | |
return value != null ? value.equals(right.value) : right.value == null; | |
} | |
@Override | |
public int hashCode() { | |
return value != null ? value.hashCode() : 0; | |
} | |
@Override | |
public String toString() { | |
return "Right{" + | |
"value=" + value + | |
'}'; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment