summaryrefslogtreecommitdiff
path: root/src/main/java/bjc/data/Either.java
diff options
context:
space:
mode:
authorBen Culkin <scorpress@gmail.com>2022-09-24 12:34:30 -0400
committerBen Culkin <scorpress@gmail.com>2022-09-24 12:34:30 -0400
commitf7d96d88798c904f69f0b5306a5ddecd0456b377 (patch)
tree5a41a891a629322f19d649c938a92ac293b19c0e /src/main/java/bjc/data/Either.java
parente3501bcc50d6579dd16ce678436fa93d6e528e5f (diff)
Add some additional combinators, of various sorts
Diffstat (limited to 'src/main/java/bjc/data/Either.java')
-rw-r--r--src/main/java/bjc/data/Either.java144
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);
}
}