From 0a8f34c27c6ef93c5c94d17728af62c7607e225f Mon Sep 17 00:00:00 2001 From: Ben Culkin Date: Thu, 3 Dec 2020 19:21:38 -0500 Subject: Rename types to match Java style This renames several interfaces that had names like IWhatever, since that isn't a style that Java uses --- src/main/java/bjc/data/Pair.java | 306 +++++++++++++++++++++++++-------------- 1 file changed, 201 insertions(+), 105 deletions(-) (limited to 'src/main/java/bjc/data/Pair.java') diff --git a/src/main/java/bjc/data/Pair.java b/src/main/java/bjc/data/Pair.java index ea2f82f..42a28f8 100644 --- a/src/main/java/bjc/data/Pair.java +++ b/src/main/java/bjc/data/Pair.java @@ -1,154 +1,250 @@ package bjc.data; +import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.Function; +import bjc.funcdata.theory.Bifunctor; + /** - * A pair of values, with nothing special about them. + * Represents a pair of values. * * @author ben * * @param - * The type of the left value. + * The type of the left side of the pair. * * @param - * The type of the right value. + * The type of the right side of the pair. + * */ -public class Pair implements IPair { - /* The left value. */ - private LeftType leftValue; - /* The right value. */ - private RightType rightValue; - - /** Create a new pair with both sides set to null. */ - public Pair() { - // Do nothing :) - } - +public interface Pair extends Bifunctor { /** - * Create a new pair with both sides set to the specified values. + * Bind a function across the values in this pair. * - * @param left - * The value of the left side. + * @param + * The type of the bound left. * - * @param right - * The value of the right side. + * @param + * The type of the bound right. + * + * @param binder + * The function to bind with. + * + * @return The bound pair. */ - public Pair(final LeftType left, final RightType right) { - leftValue = left; - rightValue = right; - } - - @Override - public IPair bind( - final BiFunction> binder) { - if (binder == null) throw new NullPointerException("Binder must not be null."); + public Pair + bind(BiFunction> binder); - return binder.apply(leftValue, rightValue); - } + /** + * Bind a function to the left value in this pair. + * + * @param + * The type of the bound value. + * + * @param leftBinder + * The function to use to bind. + * + * @return A pair with the left type bound. + */ + public Pair + bindLeft(Function> leftBinder); - @Override - public IPair - bindLeft(final Function> leftBinder) { - if (leftBinder == null) throw new NullPointerException("Binder must not be null"); + /** + * Bind a function to the right value in this pair. + * + * @param + * The type of the bound value. + * + * @param rightBinder + * The function to use to bind. + * + * @return A pair with the right type bound. + */ + public Pair + bindRight(Function> rightBinder); - return leftBinder.apply(leftValue); + /** + * Pairwise combine two pairs together. + * + * @param + * The left type of the other pair. + * + * @param + * The right type of the other pair. + * + * @param otherPair + * The pair to combine with. + * + * @return The pairs, pairwise combined together. + */ + public default + Pair, Pair> + combine(final Pair otherPair) { + return combine(otherPair, + SimplePair::new, + SimplePair::new); } - @Override - public IPair bindRight( - final Function> rightBinder) { - if (rightBinder == null) throw new NullPointerException("Binder must not be null"); + /** + * Combine the contents of two pairs together. + * + * @param + * The type of the left value of the other pair. + * + * @param + * The type of the right value of the other pair. + * + * @param + * The type of the left value of the combined pair. + * + * @param + * The type of the right value of the combined pair. + * + * @param otherPair + * The other pair to combine with. + * + * @param leftCombiner + * The function to combine the left values with. + * + * @param rightCombiner + * The function to combine the right values with. + * + * @return A pair with its values combined. + */ + public + Pair + combine(Pair otherPair, + BiFunction leftCombiner, + BiFunction rightCombiner); - return rightBinder.apply(rightValue); - } + /** + * Immediately perfom the specified action with the contents of this pair. + * + * @param consumer + * The action to perform on the pair. + */ + public default void doWith(final BiConsumer consumer) { + merge((leftValue, rightValue) -> { + consumer.accept(leftValue, rightValue); - @Override - public - IPair - combine(final IPair otherPair, - final BiFunction leftCombiner, - final BiFunction rightCombiner) { - return otherPair.bind((otherLeft, otherRight) -> { - final CombinedLeft left = leftCombiner.apply(leftValue, otherLeft); - final CombinedRight right = rightCombiner.apply(rightValue, otherRight); - - return new Pair<>(left, right); + return null; }); } @Override - public IPair - mapLeft(final Function mapper) { - if (mapper == null) throw new NullPointerException("Mapper must not be null"); + default LeftBifunctorMap + fmapLeft(final Function func) { + return argumentPair -> { + if (!(argumentPair instanceof Pair)) { + final String msg + = "This function can only be applied to instances of IPair"; - return new Pair<>(mapper.apply(leftValue), rightValue); - } + throw new IllegalArgumentException(msg); + } - @Override - public IPair - mapRight(final Function mapper) { - if (mapper == null) throw new NullPointerException("Mapper must not be null"); + final Pair argPair + = (Pair) argumentPair; - return new Pair<>(leftValue, mapper.apply(rightValue)); + return argPair.mapLeft(func); + }; } @Override - public MergedType - merge(final BiFunction merger) { - if (merger == null) throw new NullPointerException("Merger must not be null"); + default RightBifunctorMap + fmapRight(final Function func) { + return argumentPair -> { + if (!(argumentPair instanceof Pair)) { + final String msg + = "This function can only be applied to instances of IPair"; - return merger.apply(leftValue, rightValue); - } + throw new IllegalArgumentException(msg); + } - @Override - public String toString() { - return String.format("Pair [leftValue='%s', rightValue='%s']", leftValue, - rightValue); + final Pair argPair + = (Pair) argumentPair; + + return argPair.mapRight(func); + }; } + /** + * Get the value on the left side of the pair. + * + * @return The value on the left side of the pair. + */ @Override - public LeftType getLeft() { - return leftValue; + public default LeftType getLeft() { + return merge((leftValue, rightValue) -> leftValue); } + /** + * Get the value on the right side of the pair. + * + * @return The value on the right side of the pair. + */ @Override - public RightType getRight() { - return rightValue; + public default RightType getRight() { + return merge((leftValue, rightValue) -> rightValue); } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; + /** + * Transform the value on the left side of the pair. + * + * Doesn't modify the pair. + * + * @param + * The new type of the left part of the pair. + * + * @param mapper + * The function to use to transform the left part of the pair. + * + * @return The pair, with its left part transformed. + */ + public Pair + mapLeft(Function mapper); - result = prime * result + (leftValue == null ? 0 : leftValue.hashCode()); - result = prime * result + (rightValue == null ? 0 : rightValue.hashCode()); + /** + * Transform the value on the right side of the pair. + * + * Doesn't modify the pair. + * + * @param + * The new type of the right part of the pair. + * + * @param mapper + * The function to use to transform the right part of the + * pair. + * + * @return The pair, with its right part transformed. + */ + public Pair + mapRight(Function mapper); - return result; - } + /** + * Merge the two values in this pair into a single value. + * + * @param + * The type of the single value. + * + * @param merger + * The function to use for merging. + * + * @return The pair, merged into a single value. + */ + public MergedType + merge(BiFunction merger); - @Override - public boolean equals(final Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (!(obj instanceof Pair)) return false; - - final Pair other = (Pair) obj; - - if (leftValue == null) { - if (other.leftValue != null) return false; - } else if (!leftValue.equals(other.leftValue)) { - return false; - } - - if (rightValue == null) { - if (other.rightValue != null) return false; - } else if (!rightValue.equals(other.rightValue)) { - return false; - } - - return true; + /** + * Static pair constructor. + * + * @param left + * The left side of the pair. + * @param right + * The right side of the pair. + * @return A pair, with the specified left/right side. + */ + public static Pair pair(T1 left, T2 right) { + return new SimplePair<>(left, right); } } -- cgit v1.2.3