diff options
| author | Ben Culkin <scorpress@gmail.com> | 2022-09-24 12:34:30 -0400 |
|---|---|---|
| committer | Ben Culkin <scorpress@gmail.com> | 2022-09-24 12:34:30 -0400 |
| commit | f7d96d88798c904f69f0b5306a5ddecd0456b377 (patch) | |
| tree | 5a41a891a629322f19d649c938a92ac293b19c0e /src/main/java/bjc/data | |
| parent | e3501bcc50d6579dd16ce678436fa93d6e528e5f (diff) | |
Add some additional combinators, of various sorts
Diffstat (limited to 'src/main/java/bjc/data')
| -rw-r--r-- | src/main/java/bjc/data/Either.java | 144 |
1 files changed, 72 insertions, 72 deletions
diff --git a/src/main/java/bjc/data/Either.java b/src/main/java/bjc/data/Either.java index 75447f2..90efba7 100644 --- a/src/main/java/bjc/data/Either.java +++ b/src/main/java/bjc/data/Either.java @@ -3,54 +3,46 @@ package bjc.data; import java.util.*; import java.util.function.*; +import bjc.functypes.ID; + /** * Represents a pair where only one side has a value. * * @author ben * - * @param <LeftType> - * The type that could be on the left. + * @param <LeftType> The type that could be on the left. * - * @param <RightType> - * The type that could be on the right. + * @param <RightType> The type that could be on the right. * */ public class Either<LeftType, RightType> { /** * Create a new either with the left value occupied. * - * @param <LeftType> - * The type of the left value. + * @param <LeftType> The type of the left value. * - * @param <RightType> - * The type of the empty right value. + * @param <RightType> The type of the empty right value. * - * @param left - * The value to put on the left. + * @param left The value to put on the left. * * @return An either with the left side occupied. */ - public static <LeftType, RightType> Either<LeftType, RightType> - left(final LeftType left) { + public static <LeftType, RightType> Either<LeftType, RightType> left(final LeftType left) { return new Either<>(left, null); } /** * Create a new either with the right value occupied. * - * @param <LeftType> - * The type of the empty left value. + * @param <LeftType> The type of the empty left value. * - * @param <RightType> - * The type of the right value. + * @param <RightType> The type of the right value. * - * @param right - * The value to put on the right. + * @param right The value to put on the right. * * @return An either with the right side occupied. */ - public static <LeftType, RightType> Either<LeftType, RightType> - right(final RightType right) { + public static <LeftType, RightType> Either<LeftType, RightType> right(final RightType right) { return new Either<>(null, right); } @@ -75,56 +67,50 @@ public class Either<LeftType, RightType> { /** * Perform a mapping over this either. * - * @param <NewLeft> The new left type. + * @param <NewLeft> The new left type. * @param <NewRight> The new right type. * - * @param leftFunc The function to apply if this is a left either. - * @param rightFunc The function to apply if this is a right either. + * @param leftFunc The function to apply if this is a left either. + * @param rightFunc The function to apply if this is a right either. * - * @return A new either, containing a value transformed by the appropriate function. + * @return A new either, containing a value transformed by the appropriate + * function. */ - public <NewLeft, NewRight> Either<NewLeft, NewRight> map( - Function<LeftType, NewLeft> leftFunc, - Function<RightType, NewRight> rightFunc) - { - if (isLeft) return left(leftFunc.apply(leftVal)); - else return right(rightFunc.apply(rightVal)); + public <NewLeft, NewRight> Either<NewLeft, NewRight> map(Function<LeftType, NewLeft> leftFunc, + Function<RightType, NewRight> rightFunc) { + return isLeft ? left(leftFunc.apply(leftVal)) : right(rightFunc.apply(rightVal)); } - + /** * Extract the value from this Either. * - * @param <Common> The common type to extract. + * @param <Common> The common type to extract. * - * @param leftHandler The function to handle left-values. + * @param leftHandler The function to handle left-values. * @param rightHandler The function to handle right-values. * * @return The result of applying the proper function. */ - public <Common> Common extract( - Function<LeftType, Common> leftHandler, - Function<RightType, Common> rightHandler) - { - if (isLeft) return leftHandler.apply(leftVal); - else return rightHandler.apply(rightVal); + public <Common> Common extract(Function<LeftType, Common> leftHandler, Function<RightType, Common> rightHandler) { + return isLeft ? leftHandler.apply(leftVal) : rightHandler.apply(rightVal); } - + /** * Perform an action on this either. * - * @param leftHandler The handler of left values. + * @param leftHandler The handler of left values. * @param rightHandler The handler of right values. */ - public void pick( - Consumer<LeftType> leftHandler, Consumer<RightType> rightHandler) - { - if (isLeft) leftHandler.accept(leftVal); - else rightHandler.accept(rightVal); + public void pick(Consumer<LeftType> leftHandler, Consumer<RightType> rightHandler) { + if (isLeft) + leftHandler.accept(leftVal); + else + rightHandler.accept(rightVal); } /** - * Check if this either is left-aligned (has the left value filled, - * not the right value). + * Check if this either is left-aligned (has the left value filled, not the + * right value). * * @return Whether this either is left-aligned. */ @@ -140,23 +126,21 @@ public class Either<LeftType, RightType> { public Optional<LeftType> getLeft() { return Optional.ofNullable(leftVal); } - + /** - * Get the left value of this either, or get a {@link NoSuchElementException} - * if there isn't one. + * Get the left value of this either, or get a {@link NoSuchElementException} if + * there isn't one. * * @return The left value of this either. * * @throws NoSuchElementException If this either doesn't have a left value. */ public LeftType forceLeft() { - if (isLeft) - { + if (isLeft) { return leftVal; - } else - { - throw new NoSuchElementException("Either has no left value, is right value"); } + + throw new NoSuchElementException("Either has no left value, is right value"); } /** @@ -167,7 +151,7 @@ public class Either<LeftType, RightType> { public Optional<RightType> getRight() { return Optional.ofNullable(rightVal); } - + /** * Get the right value of this either, or get a {@link NoSuchElementException} * if there isn't one. @@ -177,17 +161,32 @@ public class Either<LeftType, RightType> { * @throws NoSuchElementException If this either doesn't have a right value. */ public RightType forceRight() { - if (isLeft) - { + if (isLeft) { throw new NoSuchElementException("Either has no right value, has left value"); - } else - { - return rightVal; } + + return rightVal; + } + + @SuppressWarnings("unchecked") + public <T> Either<LeftType, T> newRight() { + if (isLeft) return (Either<LeftType, T>) this; + + throw new NoSuchElementException("Can't replace right type on right Either"); } - // Misc. overrides + @SuppressWarnings("unchecked") + public <T> Either<T, RightType> newLeft() { + if (isLeft) + throw new NoSuchElementException("Can't replace left type on left Either"); + return (Either<T, RightType>) this; + } + public static <T> T collapse(Either<T, T> eth) { + return eth.extract(ID.id(), ID.id()); + } + // Misc. overrides + @Override public int hashCode() { return Objects.hash(isLeft, leftVal, rightVal); @@ -195,20 +194,21 @@ public class Either<LeftType, RightType> { @Override public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Either<?, ?> other = (Either<?, ?>) obj; - - return isLeft == other.isLeft - && Objects.equals(leftVal, other.leftVal) + + return isLeft == other.isLeft && Objects.equals(leftVal, other.leftVal) && Objects.equals(rightVal, other.rightVal); } @Override public String toString() { - return String.format("Either [leftVal='%s', rightVal='%s', isLeft=%s]", leftVal, - rightVal, isLeft); + return String.format("Either [leftVal='%s', rightVal='%s', isLeft=%s]", leftVal, rightVal, isLeft); } } |
