Skip to content

Instantly share code, notes, and snippets.

@gszeliga
Last active March 13, 2016 18:48
Show Gist options
  • Save gszeliga/9cbf6751061d84f306af to your computer and use it in GitHub Desktop.
Save gszeliga/9cbf6751061d84f306af to your computer and use it in GitHub Desktop.
Type inference thingy
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