co.unruly.control.pair.Pairs Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of control Show documentation
Show all versions of control Show documentation
A collection of functional utilities around error handling, wrapping a successfully returned value or
error
The newest version!
package co.unruly.control.pair;
import co.unruly.control.result.Result;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.IntFunction;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static co.unruly.control.result.Result.failure;
import static co.unruly.control.result.Result.success;
import static java.util.stream.Collectors.toList;
/**
* Convenience functions on Pairs
*/
public interface Pairs {
/**
* Applies the given function to the left element of a Pair, returning a new Pair with the result of that
* function as the left element and the original right element untouched
*/
static Function, Pair> onLeft(Function super OL, NL> leftMapper) {
return pair -> Pair.of(leftMapper.apply(pair.left), pair.right);
}
/**
* Applies the given function to the right element of a Pair, returning a new Pair with the result of that
* function as the right element and the original left element untouched
*/
static Function, Pair> onRight(Function rightMapper) {
return pair -> Pair.of(pair.left, rightMapper.apply(pair.right));
}
/**
* Applies the given function to both elements off a Pair, assuming that both elements are of the
* same type
*/
static Function, Pair> onBoth(Function f) {
return pair -> Pair.of(f.apply(pair.left), f.apply(pair.right));
}
/**
* Applies the given function to both elements off a Pair, yielding a non-Pair value
*/
static Function, T> merge(BiFunction f) {
return pair -> pair.then(f);
}
/**
* Merges a Pair of Lists of T into a single List of T, with the left items at the front of the list.
*/
static Function, List>, List> mergeLists() {
return pair -> Stream.of(pair.left, pair.right).flatMap(List::stream).collect(toList());
}
/**
* Collects a Stream of Pairs into a single Pair of lists, where a given index can be used to access the left
* and right parts of the input pairs respectively.
*/
static Collector, Pair, List>, Pair, List>> toParallelLists() {
return using(Collections::unmodifiableList, Collections::unmodifiableList);
}
/**
* Collects a Stream of Pairs into a single Pair of arrays, where a given index can be used to access the left
* and right parts of the input pairs respectively.
*/
static Collector, Pair, List>, Pair> toArrays(IntFunction leftArrayConstructor, IntFunction rightArrayConstructor) {
return using(
left -> left.stream().toArray(leftArrayConstructor),
right -> right.stream().toArray(rightArrayConstructor)
);
}
/**
* Reduces a stream of pairs to a single pair, using the provided identities and reducer functions
*/
static PairReducingCollector reducing(
L leftIdentity, BinaryOperator leftReducer,
R rightIdentity, BinaryOperator rightReducer) {
return new PairReducingCollector<>(leftIdentity, rightIdentity, leftReducer, rightReducer);
}
static Collector, Pair, List>, Pair> using(
Function, FL> leftFinisher,
Function, FR> rightFinisher) {
return new PairListCollector<>(leftFinisher, rightFinisher);
}
/**
* If there are any elements in the right side of the Pair, return a failure of
* the right side, otherwise return a success of the left.
*/
static Result, List> anyFailures(Pair, List> sides) {
return sides.right.isEmpty() ? success(sides.left) : failure(sides.right);
}
/**
* If there are any elements in the left side of the Pair, return a success of
* the left side, otherwise return a failure of the left.
*/
static Result, List> anySuccesses(Pair, List> sides) {
return sides.left.isEmpty() ? failure(sides.right) : success(sides.left);
}
}