Last active
August 29, 2015 14:12
-
-
Save taichi/12fc59477c3f8958f8f4 to your computer and use it in GitHub Desktop.
Exception Hander for Java8 like Either. heavily inspired. https://github.com/benjiman/expressions/blob/master/src/main/java/uk/co/benjiweber/expressions/exceptions/Result.java and https://github.com/functionaljava/functionaljava/blob/master/core/src/main/java/fj/data/Either.java
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
/** | |
* @author taichi | |
*/ | |
@FunctionalInterface | |
public interface ExceptionalFunction<T, R, EX extends Exception> { | |
R apply(T t) throws EX; | |
} |
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
import java.io.*; | |
import java.util.stream.Stream; | |
public class Main { | |
public static void main(String[] args) { | |
Stream.of("aaa", "bbb", "ccc").map(File::new) | |
.map(Trial.of(FileInputStream::new)) | |
.map(t -> t.either(fs -> 200, ex -> 400)) | |
.map(i -> i + 300); // why not integer? | |
} | |
} |
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
import java.util.Optional; | |
import java.util.function.Function; | |
import java.util.function.Predicate; | |
import java.util.function.Supplier; | |
/** | |
* @author taichi | |
*/ | |
public interface Trial<T> { | |
boolean success(); | |
boolean failure(); | |
<U> U either(Function<? super T, ? extends U> onSuccess, | |
Function<Exception, ? extends U> onFailure); | |
Optional<Trial<T>> filter(Predicate<? super T> predicate); | |
T get(); | |
T orElse(T other); | |
T orElseGet(Supplier<? extends T> other); | |
<U> Trial<U> map(Function<? super T, ? extends U> mapper); | |
<U> Trial<U> flatMap(Function<? super T, Trial<U>> mapper); | |
static class Success<T> implements Trial<T> { | |
final T value; | |
Success(T value) { | |
this.value = value; | |
} | |
@Override | |
public boolean success() { | |
return true; | |
} | |
@Override | |
public boolean failure() { | |
return false; | |
} | |
@Override | |
public <U> U either(Function<? super T, ? extends U> onSuccess, | |
Function<Exception, ? extends U> onFailure) { | |
return onSuccess.apply(this.value); | |
} | |
@Override | |
public Optional<Trial<T>> filter(Predicate<? super T> predicate) { | |
return predicate.test(this.value) ? Optional.of(this) : Optional | |
.empty(); | |
} | |
@Override | |
public T get() { | |
return this.value; | |
} | |
@Override | |
public T orElse(T other) { | |
return this.value; | |
} | |
@Override | |
public T orElseGet(Supplier<? extends T> other) { | |
return this.value; | |
} | |
@Override | |
public <U> Trial<U> map(Function<? super T, ? extends U> mapper) { | |
return new Success<U>(mapper.apply(this.value)); | |
} | |
@Override | |
public <U> Trial<U> flatMap(Function<? super T, Trial<U>> mapper) { | |
return mapper.apply(this.value); | |
} | |
} | |
static class Failure<T> implements Trial<T> { | |
static class FailureException extends RuntimeException { | |
private static final long serialVersionUID = 6537304884970413146L; | |
public FailureException(Exception exception) { | |
super(exception); | |
} | |
} | |
final Exception exception; | |
Failure(Exception exception) { | |
this.exception = exception; | |
} | |
@Override | |
public boolean success() { | |
return false; | |
} | |
@Override | |
public boolean failure() { | |
return true; | |
} | |
@Override | |
public <U> U either(Function<? super T, ? extends U> onSuccess, | |
Function<Exception, ? extends U> onFailure) { | |
return onFailure.apply(this.exception); | |
} | |
@Override | |
public Optional<Trial<T>> filter(Predicate<? super T> predicate) { | |
return Optional.empty(); | |
} | |
@Override | |
public T get() { | |
throw new FailureException(this.exception); | |
} | |
@Override | |
public T orElse(T other) { | |
return other; | |
} | |
@Override | |
public T orElseGet(Supplier<? extends T> other) { | |
return other.get(); | |
} | |
@Override | |
public <U> Trial<U> map(Function<? super T, ? extends U> mapper) { | |
return new Failure<U>(this.exception); | |
} | |
@Override | |
public <U> Trial<U> flatMap(Function<? super T, Trial<U>> mapper) { | |
return new Failure<U>(exception); | |
} | |
} | |
public static <T, R, E extends Exception> Function<T, Trial<R>> of( | |
ExceptionalFunction<T, R, E> fn) { | |
return t -> { | |
try { | |
return new Success<R>(fn.apply(t)); | |
} catch (Exception e) { | |
return new Failure<R>(e); | |
} | |
}; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment