A to some {@link Comparable} type B and two values
@@ -16,6 +18,7 @@
* @param the value type
* @param the mapped comparison type
* @see CmpEq
+ * @see CmpEqWith
* @see LTBy
* @see GTBy
*/
@@ -28,7 +31,7 @@ private CmpEqBy() {
@Override
public Boolean checkedApply(Fn1 super A, ? extends B> compareFn, A x, A y) {
- return compareFn.apply(x).compareTo(compareFn.apply(y)) == 0;
+ return cmpEqWith(comparing(compareFn.toFunction()), x, y);
}
@Override
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/CmpEqWith.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/CmpEqWith.java
new file mode 100644
index 000000000..ff95cd2fc
--- /dev/null
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/CmpEqWith.java
@@ -0,0 +1,62 @@
+package com.jnape.palatable.lambda.functions.builtin.fn3;
+
+import com.jnape.palatable.lambda.functions.Fn3;
+import com.jnape.palatable.lambda.functions.specialized.BiPredicate;
+import com.jnape.palatable.lambda.functions.specialized.Predicate;
+
+import java.util.Comparator;
+
+import static com.jnape.palatable.lambda.functions.builtin.fn3.Compare.compare;
+import static com.jnape.palatable.lambda.functions.ordering.ComparisonRelation.equal;
+import static com.jnape.palatable.lambda.functions.specialized.Predicate.predicate;
+
+/**
+ * Given a {@link Comparator} from some type A and two values of type A, return
+ * true if the first value is strictly equal to the second value (according to
+ * {@link Comparator#compare(Object, Object)} otherwise, return false.
+ *
+ * @param the value type
+ * @see CmpEqBy
+ * @see LTBy
+ * @see GTBy
+ * @see Compare
+ */
+public final class CmpEqWith implements Fn3A and two values of type A, return a
+ * {@link ComparisonRelation} of the first value with reference to the second value (according to
+ * {@link Comparator#compare(Object, Object)}. The order of parameters is flipped with respect to
+ * {@link Comparator#compare(Object, Object)} for more idiomatic partial application.
+ * + * Example: + *
+ * {@code
+ * Compare.compare(naturalOrder(), 1, 2); // ComparisonRelation.GreaterThan
+ * Compare.compare(naturalOrder(), 2, 1); // ComparisonRelation.LessThan
+ * Compare.compare(naturalOrder(), 1, 1); // ComparisonRelation.Equal
+ * }
+ *
+ *
+ * @param the value type
+ * @see Comparator
+ * @see Compare
+ */
+public final class Compare implements Fn3A to some {@link Comparable} type B and two values
@@ -16,6 +18,7 @@
* @param the value type
* @param the mapped comparison type
* @see GT
+ * @see GTWith
* @see LTBy
*/
public final class GTBy> implements Fn3A to some {@link Comparable} type B and two values
@@ -18,6 +19,7 @@
* @param the value type
* @param the mapped comparison type
* @see GTE
+ * @see GTEWith
* @see LTEBy
*/
public final class GTEBy> implements Fn3A and two values of type A,
+ * return true if the second value is greater than or equal to the first value in
+ * terms of their mapped B results according to {@link Comparator#compare(Object, Object)};
+ * otherwise, return false.
+ *
+ * @param the value type
+ * @see GTE
+ * @see GTEBy
+ * @see LTEWith
+ */
+public final class GTEWith implements Fn3A and two values of type A,
+ * return true if the second value is strictly greater than the first value in
+ * terms of their mapped B results; otherwise, return false.
+ *
+ * @param the value type
+ * @see GT
+ * @see GTBy
+ * @see LTWith
+ */
+public final class GTWith implements Fn3A to some {@link Comparable} type B and two values
@@ -27,7 +29,7 @@ private LTBy() {
@Override
public Boolean checkedApply(Fn1 super A, ? extends B> compareFn, A y, A x) {
- return compareFn.apply(x).compareTo(compareFn.apply(y)) < 0;
+ return ltWith(comparing(compareFn.toFunction()), y, x);
}
@Override
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LTEBy.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LTEBy.java
index bc755470d..4c377d583 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LTEBy.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LTEBy.java
@@ -6,7 +6,8 @@
import com.jnape.palatable.lambda.functions.specialized.BiPredicate;
import com.jnape.palatable.lambda.functions.specialized.Predicate;
-import static com.jnape.palatable.lambda.functions.builtin.fn3.CmpEqBy.cmpEqBy;
+import static com.jnape.palatable.lambda.functions.builtin.fn3.LTEWith.lteWith;
+import static java.util.Comparator.comparing;
/**
* Given a mapping function from some type A to some {@link Comparable} type B and two values
@@ -28,7 +29,7 @@ private LTEBy() {
@Override
public Boolean checkedApply(Fn1 super A, ? extends B> compareFn, A y, A x) {
- return LTBy.ltBy(compareFn).or(cmpEqBy(compareFn)).apply(y, x);
+ return lteWith(comparing(compareFn.toFunction()), y, x);
}
@Override
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LTEWith.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LTEWith.java
new file mode 100644
index 000000000..403f5c15f
--- /dev/null
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LTEWith.java
@@ -0,0 +1,62 @@
+package com.jnape.palatable.lambda.functions.builtin.fn3;
+
+import com.jnape.palatable.lambda.functions.Fn3;
+import com.jnape.palatable.lambda.functions.builtin.fn2.LTE;
+import com.jnape.palatable.lambda.functions.specialized.BiPredicate;
+import com.jnape.palatable.lambda.functions.specialized.Predicate;
+
+import java.util.Comparator;
+
+import static com.jnape.palatable.lambda.functions.builtin.fn3.GTWith.gtWith;
+import static com.jnape.palatable.lambda.functions.specialized.Predicate.predicate;
+
+/**
+ * Given a {@link Comparator} from some type A and two values of type A,
+ * return true if the second value is less than or equal to the first value in
+ * terms of their mapped B results according to {@link Comparator#compare(Object, Object)};
+ * otherwise, return false.
+ *
+ * @param the value type
+ * @see LTE
+ * @see LTEBy
+ * @see GTEWith
+ */
+public final class LTEWith implements Fn3A and two values of type A,
+ * return true if the second value is strictly less than than the first value in
+ * terms of their mapped B results; otherwise, return false.
+ *
+ * @param the value type
+ * @see LT
+ * @see LTBy
+ * @see GTWith
+ */
+public final class LTWith implements Fn3+ * Due to its singly-linked embedded design, {@link IterateT} is a canonical example of purely-functional streaming + * computation. For example, to lazily print all lines from a file descriptor, an initial implementation using + * {@link IterateT} might take the following form: + *
+ * String filePath = "/tmp/a_tale_of_two_cities.txt";
+ * IterateT<IO<?>, String> streamLines = IterateT.unfold(
+ * reader -> io(() -> maybe(reader.readLine()).fmap(line -> tuple(line, reader))),
+ * io(() -> Files.newBufferedReader(Paths.get(filePath))));
+ *
+ * // iterative read and print lines without retaining references
+ * IO<Unit> printLines = streamLines.forEach(line -> io(() -> System.out.println(line)));
+ * printLines.unsafePerformIO(); // prints "It was the best of times, it was the worst of times, [...]"
+ *
+ *
+ * @param other {@link IterateT}.
+ *
+ * @param other the other {@link IterateT}
+ * @return the concatenated {@link IterateT}
+ */
+ public IterateTC inside the
+ * context of the monadic effect, using the provided cFn0 to construct the initial instance.
+ *
+ * Note that this is a fundamentally monolithic operation - meaning that incremental progress is not possible - and
+ * as such, calling this on an infinite {@link IterateT} will result in either heap exhaustion (e.g. in the case of
+ * {@link List lists}) or non-termination (e.g. in the case of {@link Set sets}).
+ *
+ * @param cFn0 the {@link Collection} construction function
+ * @param fn and a starting seed value
+ * mb by successively applying fn to the latest seed value, producing {@link Maybe maybe}
+ * a value to yield out and the next seed value for the subsequent computation.
+ *
+ * @param fn the unfolding function
+ * @param mb the starting seed value
+ * @param predicate
+ * then return just the embedded value
+ *
+ * @param predicate the predicate to apply to the embedded value
+ * @return maybe the satisfied value embedded under M
+ */
+ public MaybeT{@link TypeSafeKey} -> {@link Semigroup}
+ * {@link MergeHMaps#key(TypeSafeKey, Semigroup) mappings}, defaulting to {@link Last} in case no
+ * {@link Semigroup} has been chosen for a given {@link TypeSafeKey}.
+ */
+public final class MergeHMaps implements MonoidA, produce a {@link Semigroup} over A that chooses
+ * between two values x and y via the following rules:
+ *
+ *
+ *
+ * @param the value type
+ * @see Max
+ * @see MaxBy
+ * @see MinWith
+ */
+public final class MaxWith implements SemigroupFactoryx is strictly less than y in terms of B, return yxA, produce a {@link Semigroup} over A that chooses
+ * between two values x and y via the following rules:
+ *
+ *
+ *
+ * @param the value type
+ * @see Min
+ * @see MinBy
+ * @see MaxBy
+ */
+public final class MinWith implements SemigroupFactoryx is strictly greater than y in terms of B, return yx