Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import java.util.NoSuchElementException;
import java.util.Optional;
@SuppressWarnings("unused")
public sealed interface Either<L, R> permits Either.Left, Either.Right {
static <L, R extends Throwable> Either<L, R> of(java.util.function.Supplier<L> supplier) {
try {
return new Either.Left<>(supplier.get());
} catch (Throwable t) {
try {
@SuppressWarnings("unchecked")
R exc = (R) t;
return new Right<>(exc);
} catch (ClassCastException e) {
try {
@SuppressWarnings("unchecked")
R exc = (R) t.getCause();
return new Right<>(exc);
} catch (ClassCastException ignored) {}
throw t;
}
}
}
default boolean isLeft() {
return (this instanceof Either.Left<L,R>);
}
default boolean isRight() {
return (this instanceof Either.Right<L,R>);
}
default Optional<L> getLeft(){
return switch (this) {
case Either.Left<L, R> left -> Optional.ofNullable(left.left);
case Either.Right<L, R> right -> Optional.empty();
};
}
default Optional<R> getRight() {
return switch (this) {
case Either.Left<L, R> left -> Optional.empty();
case Either.Right<L, R> right -> Optional.ofNullable(right.right);
};
}
default Either<R, L> flip() {
return switch (this) {
case Either.Left<L, R> left -> new Right<>(left.left);
case Either.Right<L, R> right -> new Left<>(right.right);
};
}
default <L2> Either<L2, R> andThen(java.util.function.Function<L, Either<L2, R>> nextFunc) {
return switch(this) {
case Either.Left<L, R> left -> nextFunc.apply(left.left);
case Either.Right<L, R> right -> new Either.Right<>(right.right);
};
}
default <R2> Either<L, R2> andThenErr(java.util.function.Function<R, Either<L, R2>> nextFunc) {
return switch(this) {
case Either.Left<L, R> left -> new Either.Left<>(left.left);
case Either.Right<L, R> right -> nextFunc.apply(right.right);
};
}
default L unwrap() throws NoSuchElementException {
return getLeft().orElseThrow();
}
record Left<L, R>(L left) implements Either<L, R> {}
record Right<L, R>(R right) implements Either<L, R> {}
}