Either.java 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. package org.leumasjaffe.container;
  2. import java.util.function.Consumer;
  3. import java.util.function.Function;
  4. import lombok.AccessLevel;
  5. import lombok.AllArgsConstructor;
  6. import lombok.Getter;
  7. import lombok.NonNull;
  8. @AllArgsConstructor(access=AccessLevel.PRIVATE)
  9. @Getter(AccessLevel.PACKAGE) // For JUnit tests only
  10. public class Either<T1, T2> {
  11. public enum State { LEFT, RIGHT }
  12. T1 left;
  13. T2 right;
  14. public static <T1, T2> Either<T1, T2> ofLeft(@NonNull T1 left) {
  15. return new Either<>(left, null);
  16. }
  17. public static <T1, T2> Either<T1, T2> ofRight(@NonNull T2 right) {
  18. return new Either<>(null, right);
  19. }
  20. State getState() {
  21. return left == null ? State.RIGHT : State.LEFT;
  22. }
  23. public void setLeft(@NonNull T1 left) {
  24. this.right = null;
  25. this.left = left;
  26. }
  27. public void setRight(@NonNull T2 right) {
  28. this.right = right;
  29. this.left = null;
  30. }
  31. public void consume(@NonNull Consumer<T1> fLeft, @NonNull Consumer<T2> fRight) {
  32. switch (getState()) {
  33. case LEFT: fLeft.accept(left); return;
  34. case RIGHT: fRight.accept(right); return;
  35. default: throw new IllegalStateException();
  36. }
  37. }
  38. public <R1, R2> Either<R1, R2> map(@NonNull Function<T1, R1> fLeft,
  39. @NonNull Function<T2, R2> fRight) {
  40. switch (getState()) {
  41. case LEFT: return Either.ofLeft(fLeft.apply(left));
  42. case RIGHT: return Either.ofRight(fRight.apply(right));
  43. default: throw new IllegalStateException();
  44. }
  45. }
  46. public <R> Either<R, T2> mapLeft(@NonNull Function<T1, R> fLeft) {
  47. switch (getState()) {
  48. case LEFT: return Either.ofLeft(fLeft.apply(left));
  49. case RIGHT: return Either.ofRight(right);
  50. default: throw new IllegalStateException();
  51. }
  52. }
  53. public <R> Either<T1, R> mapRight(@NonNull Function<T2, R> fRight) {
  54. switch (getState()) {
  55. case LEFT: return Either.ofLeft(left);
  56. case RIGHT: return Either.ofRight(fRight.apply(right));
  57. default: throw new IllegalStateException();
  58. }
  59. }
  60. public static <T> Function<T, T> identity() {
  61. return (x) -> x;
  62. }
  63. public static <T, R> Function<T, R> discard() {
  64. return (x) -> null;
  65. }
  66. public <R> R unify(@NonNull Function<T1, R> fLeft, @NonNull Function<T2, R> fRight) {
  67. switch (getState()) {
  68. case LEFT: return fLeft.apply(left);
  69. case RIGHT: return fRight.apply(right);
  70. default: throw new IllegalStateException();
  71. }
  72. }
  73. }