Skip to content

Instantly share code, notes, and snippets.

@mrwilson
Last active September 11, 2024 21:29
Show Gist options
  • Save mrwilson/ebf1c64bbd0210d48029ef33f705ae90 to your computer and use it in GitHub Desktop.
Save mrwilson/ebf1c64bbd0210d48029ef33f705ae90 to your computer and use it in GitHub Desktop.
import java.util.function.Function;
// https://en.wikipedia.org/wiki/Result_type
public sealed interface Result<LEFT, RIGHT> permits Result.Success, Result.Failure {
// Both functions have a common result supertype
// e.g. `T` can be a `Result<X,Y>` or a resolved type like a `String` / `Request`
<T, L2 extends T, R2 extends T> T either(Function<LEFT, L2> left, Function<RIGHT, R2> right);
default <T> T then(Function<Result<LEFT, RIGHT>, T> function) {
return function.apply(this);
}
record Success<L, R>(L value) implements Result<L, R> {
@Override
public <T, L2 extends T, R2 extends T> T either(Function<L, L2> left, Function<R, R2> right) {
return left.apply(value);
}
}
record Failure<L, R>(R error) implements Result<L, R> {
@Override
public <T, L2 extends T, R2 extends T> T either(Function<L, L2> left, Function<R, R2> right) {
return right.apply(error);
}
}
}
import org.junit.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
public class ResultTest {
@Test
public void example() {
var output = parse("ten")
.then(this::attemptToDouble);
// Expected: is "Two times ten is equal to 20"
// but: was "java.lang.NumberFormatException: For input string: \"ten\""
assertThat(output, is("Two times ten is equal to 20"));
}
public Result<Integer, Exception> parse(String input) {
try {
return new Success<>(Integer.parseInt(input));
} catch (NumberFormatException e) {
return new Failure<>(e);
}
}
private String attemptToDouble(Result<Integer, Exception> result) {
return result.either(
integer -> "Two times ten is equal to " + integer * 2,
Throwable::toString
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment