From 9b8b8bd4d7d9acfb6fc232cfd7a749046a76510f Mon Sep 17 00:00:00 2001 From: jnape Date: Tue, 19 Feb 2019 23:16:35 -0600 Subject: [PATCH 01/69] [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 145522c52..00b717374 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ lambda - 3.3.0 + 3.3.1-SNAPSHOT jar Lambda From 911e54961af0131155c3ec81ea951de41f9203fc Mon Sep 17 00:00:00 2001 From: jnape Date: Sun, 10 Mar 2019 15:53:30 -0500 Subject: [PATCH 02/69] Updating CHANGELOG and README --- CHANGELOG.md | 8 +++++++- README.md | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee919be2e..83f665c3b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/). ## [Unreleased] +No changes + +## [3.3.0] - 2019-02-18 ### Added - `MergeMaps`, a `Monoid` on `Map` formed by `Map#merge` - `CheckedEffect` is now a `CheckedFn1` @@ -16,7 +19,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/). - test jar is now published - `Monad#join` static alias for `flatMap(id())` - `Effect#effect` static factory method taking `Fn1` +- `IO#unsafePerformAsyncIO` overloads for running `IO`s asynchronously - `IO`s automatically encode parallelism in composition +- `IO#exceptionally` for recovering from failure during `IO` operation ### Fixed - issue where certain ways to compose `Effect`s unintentionally nullified the effect @@ -426,7 +431,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/). - `Monadic/Dyadic/TriadicFunction`, `Predicate`, `Tuple2`, `Tuple3` - `Functor`, `BiFunctor`, `ProFunctor` -[Unreleased]: https://github.com/palatable/lambda/compare/lambda-3.2.0...HEAD +[Unreleased]: https://github.com/palatable/lambda/compare/lambda-3.3.0...HEAD +[3.3.0]: https://github.com/palatable/lambda/compare/lambda-3.2.0...3.3.0 [3.2.0]: https://github.com/palatable/lambda/compare/lambda-3.1.0...lambda-3.2.0 [3.1.0]: https://github.com/palatable/lambda/compare/lambda-3.0.3...lambda-3.1.0 [3.0.3]: https://github.com/palatable/lambda/compare/lambda-3.0.2...lambda-3.0.3 diff --git a/README.md b/README.md index 65501c222..d4c933638 100644 --- a/README.md +++ b/README.md @@ -57,14 +57,14 @@ Add the following dependency to your: com.jnape.palatable lambda - 3.2.0 + 3.3.0 ``` `build.gradle` ([Gradle](https://docs.gradle.org/current/userguide/dependency_management.html)): ```gradle -compile group: 'com.jnape.palatable', name: 'lambda', version: '3.2.0' +compile group: 'com.jnape.palatable', name: 'lambda', version: '3.3.0' ``` Examples From 8e887966e656a34c0d0e4e47f081a2549051a6c8 Mon Sep 17 00:00:00 2001 From: jnape Date: Thu, 28 Mar 2019 19:03:44 -0500 Subject: [PATCH 03/69] IO internal rewrite - now sealed - linear and recursive composition is stack-safe - static factory methods are now much easier to infer --- CHANGELOG.md | 6 +- .../palatable/lambda/functions/Effect.java | 3 +- .../jnape/palatable/lambda/functions/Fn0.java | 6 +- .../jnape/palatable/lambda/functions/IO.java | 222 +++++++++++------- .../specialized/checked/CheckedEffect.java | 4 +- .../specialized/checked/CheckedRunnable.java | 9 +- .../palatable/lambda/functions/IOTest.java | 70 +++++- .../java/testsupport/EqualityAwareIO.java | 36 ++- 8 files changed, 225 insertions(+), 131 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 83f665c3b..ac54fccb9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/). ## [Unreleased] -No changes +### Changed +- ***Breaking Change***: `IO` is now sealed. Most previous constructions using the static factory methods +should continue to work (by simply targeting `Supplier` now instead of an anonymous `IO`), but some might +need to be reworked, and subtyping is obviously no longer supported. +- `IO` is now stack-safe, regardless of whether the composition nests linearly or recursively ## [3.3.0] - 2019-02-18 ### Added diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Effect.java b/src/main/java/com/jnape/palatable/lambda/functions/Effect.java index 5c36ff861..ea5bef72f 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Effect.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Effect.java @@ -6,7 +6,6 @@ import java.util.function.Consumer; import java.util.function.Function; -import static com.jnape.palatable.lambda.functions.Fn0.fn0; import static com.jnape.palatable.lambda.functions.IO.io; import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; @@ -22,7 +21,7 @@ public interface Effect extends Fn1>, Consumer { @Override default IO apply(A a) { - return io(fn0(() -> accept(a))); + return io(() -> accept(a)); } @Override diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn0.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn0.java index 84eb3e4a8..a1c67f5cc 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Fn0.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn0.java @@ -9,7 +9,6 @@ import java.util.function.Supplier; import static com.jnape.palatable.lambda.adt.Unit.UNIT; -import static com.jnape.palatable.lambda.functions.IO.io; /** * A function taking "no arguments", implemented as an {@link Fn1}<{@link Unit}, A>. @@ -124,7 +123,10 @@ static Fn0 fn0(Fn0 fn) { * @return the {@link Fn0} */ static Fn0 fn0(Runnable runnable) { - return io(runnable)::unsafePerformIO; + return fn0(() -> { + runnable.run(); + return UNIT; + }); } /** diff --git a/src/main/java/com/jnape/palatable/lambda/functions/IO.java b/src/main/java/com/jnape/palatable/lambda/functions/IO.java index cb0ce4c07..a71dddebf 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/IO.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/IO.java @@ -2,17 +2,29 @@ import com.jnape.palatable.lambda.adt.Try; import com.jnape.palatable.lambda.adt.Unit; +import com.jnape.palatable.lambda.adt.choice.Choice2; +import com.jnape.palatable.lambda.adt.hlist.Tuple2; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.monad.Monad; +import java.util.LinkedList; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; import java.util.function.Function; import java.util.function.Supplier; -import static com.jnape.palatable.lambda.adt.Unit.UNIT; +import static com.jnape.palatable.lambda.adt.choice.Choice2.a; +import static com.jnape.palatable.lambda.adt.hlist.HList.tuple; +import static com.jnape.palatable.lambda.functions.Fn0.fn0; +import static com.jnape.palatable.lambda.functions.builtin.fn2.Into.into; +import static com.jnape.palatable.lambda.functions.builtin.fn3.FoldLeft.foldLeft; +import static com.jnape.palatable.lambda.functions.recursion.RecursiveResult.recurse; +import static com.jnape.palatable.lambda.functions.recursion.RecursiveResult.terminate; +import static com.jnape.palatable.lambda.functions.recursion.Trampoline.trampoline; import static com.jnape.palatable.lambda.functions.specialized.checked.CheckedSupplier.checked; +import static java.util.concurrent.CompletableFuture.completedFuture; import static java.util.concurrent.CompletableFuture.supplyAsync; +import static java.util.concurrent.ForkJoinPool.commonPool; /** * A {@link Monad} representing some side-effecting computation to be performed. Note that because {@link IO} inherently @@ -21,14 +33,17 @@ * * @param the result type */ -public interface IO extends Monad> { +public abstract class IO implements Monad> { + + private IO() { + } /** * Run the effect represented by this {@link IO} instance, blocking the current thread until the effect terminates. * * @return the result of the effect */ - A unsafePerformIO(); + public abstract A unsafePerformIO(); /** * Returns a {@link CompletableFuture} representing the result of this eventual effect. By default, this will @@ -39,8 +54,8 @@ public interface IO extends Monad> { * @return the {@link CompletableFuture} representing this {@link IO}'s eventual result * @see IO#unsafePerformAsyncIO(Executor) */ - default CompletableFuture unsafePerformAsyncIO() { - return supplyAsync(this::unsafePerformIO); + public final CompletableFuture unsafePerformAsyncIO() { + return unsafePerformAsyncIO(commonPool()); } /** @@ -53,9 +68,7 @@ default CompletableFuture unsafePerformAsyncIO() { * @return the {@link CompletableFuture} representing this {@link IO}'s eventual result * @see IO#unsafePerformAsyncIO() */ - default CompletableFuture unsafePerformAsyncIO(Executor executor) { - return supplyAsync(this::unsafePerformIO, executor); - } + public abstract CompletableFuture unsafePerformAsyncIO(Executor executor); /** * Given a function from any {@link Throwable} to the result type A, if this {@link IO} successfully @@ -64,18 +77,13 @@ default CompletableFuture unsafePerformAsyncIO(Executor executor) { * @param recoveryFn the recovery function * @return the guarded {@link IO} */ - default IO exceptionally(Function recoveryFn) { + public final IO exceptionally(Function recoveryFn) { return new IO() { @Override public A unsafePerformIO() { return Try.trying(IO.this::unsafePerformIO).recover(recoveryFn); } - @Override - public CompletableFuture unsafePerformAsyncIO() { - return IO.this.unsafePerformAsyncIO().exceptionally(recoveryFn::apply); - } - @Override public CompletableFuture unsafePerformAsyncIO(Executor executor) { return IO.this.unsafePerformAsyncIO(executor).exceptionally(recoveryFn::apply); @@ -87,40 +95,15 @@ public CompletableFuture unsafePerformAsyncIO(Executor executor) { * {@inheritDoc} */ @Override - default IO flatMap(Function>> f) { - return new IO() { - @Override - public B unsafePerformIO() { - return f.apply(IO.this.unsafePerformIO()).>coerce().unsafePerformIO(); - } - - @Override - public CompletableFuture unsafePerformAsyncIO() { - return IO.this.unsafePerformAsyncIO() - .thenCompose(a -> f.apply(a).>coerce().unsafePerformAsyncIO()); - } - - @Override - public CompletableFuture unsafePerformAsyncIO(Executor executor) { - return IO.this.unsafePerformAsyncIO(executor) - .thenCompose(a -> f.apply(a).>coerce().unsafePerformAsyncIO(executor)); - } - }; + public final IO pure(B b) { + return io(b); } /** * {@inheritDoc} */ @Override - default IO pure(B b) { - return () -> b; - } - - /** - * {@inheritDoc} - */ - @Override - default IO fmap(Function fn) { + public final IO fmap(Function fn) { return Monad.super.fmap(fn).coerce(); } @@ -128,32 +111,19 @@ default IO fmap(Function fn) { * {@inheritDoc} */ @Override - default IO zip(Applicative, IO> appFn) { - IO ioA = this; - IO> ioF = appFn.coerce(); - return new IO() { - @Override - public B unsafePerformIO() { - return ioF.unsafePerformIO().apply(ioA.unsafePerformIO()); - } - - @Override - public CompletableFuture unsafePerformAsyncIO() { - return ioF.unsafePerformAsyncIO().thenCompose(ioA.unsafePerformAsyncIO()::thenApply); - } - - @Override - public CompletableFuture unsafePerformAsyncIO(Executor executor) { - return ioF.unsafePerformAsyncIO(executor).thenCompose(ioA.unsafePerformAsyncIO(executor)::thenApply); - } - }; + public final IO zip(Applicative, IO> appFn) { + @SuppressWarnings("unchecked") + IO source = (IO) this; + @SuppressWarnings("unchecked") + IO> zip = (IO>) (Object) appFn; + return new Compose<>(source, a(zip)); } /** * {@inheritDoc} */ @Override - default IO discardL(Applicative> appB) { + public final IO discardL(Applicative> appB) { return Monad.super.discardL(appB).coerce(); } @@ -161,19 +131,20 @@ default IO discardL(Applicative> appB) { * {@inheritDoc} */ @Override - default IO discardR(Applicative> appB) { + public final IO discardR(Applicative> appB) { return Monad.super.discardR(appB).coerce(); } /** - * Static factory method for coercing a lambda to an {@link IO}. - * - * @param io the lambda to coerce - * @param the result type - * @return the {@link IO} + * {@inheritDoc} */ - static IO io(IO io) { - return io; + @Override + public final IO flatMap(Function>> f) { + @SuppressWarnings("unchecked") + IO source = (IO) this; + @SuppressWarnings({"unchecked", "RedundantCast"}) + Function> flatMap = (Function>) (Object) f; + return new Compose<>(source, Choice2.b(flatMap)); } /** @@ -183,32 +154,49 @@ static IO io(IO io) { * @param the result type * @return the {@link IO} */ - static IO io(A a) { - return io(() -> a); + public static IO io(A a) { + return new IO() { + @Override + public A unsafePerformIO() { + return a; + } + + @Override + public CompletableFuture unsafePerformAsyncIO(Executor executor) { + return completedFuture(a); + } + }; } /** - * Static factory method for creating an {@link IO} that runs runnable and returns {@link Unit}. + * Static factory method for coercing a lambda to an {@link IO}. * - * @param runnable the {@link Runnable} + * @param supplier the lambda to coerce + * @param the result type * @return the {@link IO} */ - static IO io(Runnable runnable) { - return io(() -> { - runnable.run(); - return UNIT; - }); + public static IO io(Supplier supplier) { + return new IO() { + @Override + public A unsafePerformIO() { + return supplier.get(); + } + + @Override + public CompletableFuture unsafePerformAsyncIO(Executor executor) { + return supplyAsync(supplier, executor); + } + }; } /** - * Static factory method for creating an {@link IO} from an {@link Fn1}<{@link Unit}, A>. + * Static factory method for creating an {@link IO} that runs runnable and returns {@link Unit}. * - * @param fn1 the {@link Fn1} - * @param the result type + * @param runnable the {@link Runnable} * @return the {@link IO} */ - static IO io(Fn1 fn1) { - return io(() -> fn1.apply(UNIT)); + public static IO io(Runnable runnable) { + return io(fn0(runnable)); } /** @@ -223,22 +211,76 @@ static IO io(Fn1 fn1) { * @param the result type * @return the {@link IO} */ - static IO externallyManaged(Supplier> supplier) { + public static IO externallyManaged(Supplier> supplier) { return new IO() { @Override public A unsafePerformIO() { return checked(() -> unsafePerformAsyncIO().get()).get(); } - @Override - public CompletableFuture unsafePerformAsyncIO() { - return supplier.get(); - } - @Override public CompletableFuture unsafePerformAsyncIO(Executor executor) { return supplier.get(); } }; } + + private static final class Compose extends IO { + private final IO source; + private final Choice2>, Function>> composition; + + private Compose(IO source, + Choice2>, Function>> composition) { + this.source = source; + this.composition = composition; + } + + @Override + public A unsafePerformIO() { + @SuppressWarnings("unchecked") + A result = (A) trampoline(into((source, compositions) -> { + Object res = source.unsafePerformIO(); + return compositions.isEmpty() + ? terminate(res) + : compositions.pop().match( + zip -> recurse(tuple(io(zip.unsafePerformIO().apply(res)), compositions)), + flatMap -> { + IO next = flatMap.apply(res); + return (next instanceof Compose) + ? recurse(((Compose) next).deforest(compositions)) + : recurse(tuple(next, compositions)); + }); + }), deforest(new LinkedList<>())); + + return result; + } + + @Override + public CompletableFuture unsafePerformAsyncIO(Executor executor) { + @SuppressWarnings("unchecked") + CompletableFuture future = (CompletableFuture) deforest(new LinkedList<>()) + .into((source, compositions) -> foldLeft( + (io, composition) -> composition + .match(zip -> zip.unsafePerformAsyncIO(executor).thenCompose(io::thenApply), + flatMap -> io.thenComposeAsync(obj -> flatMap.apply(obj) + .unsafePerformAsyncIO(executor))), + source.unsafePerformAsyncIO(executor), + compositions)); + return future; + } + + private Tuple2, LinkedList>, Function>>>> + deforest(LinkedList>, Function>>> branches) { + Tuple2, LinkedList>, Function>>>> args = + tuple(this, branches); + return trampoline(into((source, compositions) -> { + IO leaf = source.source; + compositions.push(source.composition); + return leaf instanceof Compose + ? recurse(tuple((Compose) leaf, compositions)) + : terminate(tuple(leaf, compositions)); + }), args); + } + + } } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedEffect.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedEffect.java index a4dc0c820..1d833c91b 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedEffect.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedEffect.java @@ -3,14 +3,14 @@ import com.jnape.palatable.lambda.adt.Unit; import com.jnape.palatable.lambda.functions.Effect; import com.jnape.palatable.lambda.functions.Fn1; -import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functions.IO; +import com.jnape.palatable.lambda.functor.Applicative; import java.util.function.Consumer; import java.util.function.Function; -import static com.jnape.palatable.lambda.functions.specialized.checked.Runtime.throwChecked; import static com.jnape.palatable.lambda.functions.IO.io; +import static com.jnape.palatable.lambda.functions.specialized.checked.Runtime.throwChecked; /** * Specialized {@link Effect} that can throw any {@link Throwable}. diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedRunnable.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedRunnable.java index 7eb794917..954f4b952 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedRunnable.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedRunnable.java @@ -1,7 +1,6 @@ package com.jnape.palatable.lambda.functions.specialized.checked; import com.jnape.palatable.lambda.adt.Unit; -import com.jnape.palatable.lambda.functions.IO; import static com.jnape.palatable.lambda.adt.Unit.UNIT; import static com.jnape.palatable.lambda.functions.specialized.checked.Runtime.throwChecked; @@ -14,7 +13,7 @@ * @see CheckedFn1 */ @FunctionalInterface -public interface CheckedRunnable extends Runnable, IO { +public interface CheckedRunnable extends Runnable { /** * A version of {@link Runnable#run()} that can throw checked exceptions. @@ -32,12 +31,6 @@ default void run() { } } - @Override - default Unit unsafePerformIO() { - run(); - return UNIT; - } - /** * Convert this {@link CheckedRunnable} to a {@link CheckedSupplier} that returns {@link Unit}. * diff --git a/src/test/java/com/jnape/palatable/lambda/functions/IOTest.java b/src/test/java/com/jnape/palatable/lambda/functions/IOTest.java index cab2595c0..578f458f3 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/IOTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functions/IOTest.java @@ -16,11 +16,11 @@ import java.util.function.Function; import static com.jnape.palatable.lambda.adt.Unit.UNIT; -import static com.jnape.palatable.lambda.functions.Fn0.fn0; import static com.jnape.palatable.lambda.functions.IO.externallyManaged; import static com.jnape.palatable.lambda.functions.IO.io; import static com.jnape.palatable.lambda.functions.builtin.fn2.Tupler2.tupler; -import static com.jnape.palatable.lambda.functions.specialized.checked.CheckedFn1.checked; +import static com.jnape.palatable.lambda.functions.builtin.fn3.Times.times; +import static com.jnape.palatable.lambda.functions.specialized.checked.CheckedSupplier.checked; import static java.util.concurrent.CompletableFuture.completedFuture; import static java.util.concurrent.Executors.newFixedThreadPool; import static java.util.concurrent.ForkJoinPool.commonPool; @@ -29,8 +29,10 @@ @RunWith(Traits.class) public class IOTest { + private static final int STACK_EXPLODING_NUMBER = 50_000; + @TestTraits({FunctorLaws.class, ApplicativeLaws.class, MonadLaws.class}) - public IO testSubject() { + public EqualityAwareIO testSubject() { return new EqualityAwareIO<>(io(1)); } @@ -38,7 +40,6 @@ public IO testSubject() { public void staticFactoryMethods() { assertEquals((Integer) 1, io(1).unsafePerformIO()); assertEquals((Integer) 1, io(() -> 1).unsafePerformIO()); - assertEquals((Integer) 1, io(fn0(() -> 1)).unsafePerformIO()); assertEquals(UNIT, io(() -> {}).unsafePerformIO()); } @@ -61,12 +62,12 @@ public void zipAndDerivativesComposesInParallel() { CountDownLatch advanceFirst = new CountDownLatch(1); CountDownLatch advanceSecond = new CountDownLatch(1); - IO ioA = io(checked(__ -> { + IO ioA = io(checked(() -> { advanceFirst.countDown(); advanceSecond.await(); return a; })); - IO>> ioF = io(checked(__ -> { + IO>> ioF = io(checked(() -> { advanceFirst.await(); advanceSecond.countDown(); return f; @@ -118,6 +119,63 @@ public void exceptionallyRescuesFutures() { completeExceptionally(new UnsupportedOperationException("foo")); }}).exceptionally(e -> e.getCause().getMessage()); assertEquals("foo", externallyManaged.unsafePerformIO()); + } + + @Test + public void linearSyncStackSafety() { + assertEquals((Integer) STACK_EXPLODING_NUMBER, + times(STACK_EXPLODING_NUMBER, f -> f.fmap(x -> x + 1), io(0)).unsafePerformIO()); + assertEquals((Integer) STACK_EXPLODING_NUMBER, + times(STACK_EXPLODING_NUMBER, f -> f.zip(f.pure(x -> x + 1)), io(0)).unsafePerformIO()); + assertEquals((Integer) 0, + times(STACK_EXPLODING_NUMBER, f -> f.pure(0).discardR(f), io(0)).unsafePerformIO()); + assertEquals((Integer) 1, + times(STACK_EXPLODING_NUMBER, f -> f.pure(1).discardR(f), io(0)).unsafePerformIO()); + assertEquals((Integer) 0, + times(STACK_EXPLODING_NUMBER, f -> f.pure(1).discardL(f), io(0)).unsafePerformIO()); + assertEquals((Integer) STACK_EXPLODING_NUMBER, + times(STACK_EXPLODING_NUMBER, f -> f.flatMap(x -> f.pure(x + 1)), io(0)).unsafePerformIO()); + } + + @Test + public void recursiveSyncFlatMapStackSafety() { + assertEquals((Integer) STACK_EXPLODING_NUMBER, + new Fn1, IO>() { + @Override + public IO apply(IO a) { + return a.flatMap(x -> x < STACK_EXPLODING_NUMBER ? apply(io(x + 1)) : io(x)); + } + }.apply(io(0)).unsafePerformIO()); + + } + + @Test + public void linearAsyncStackSafety() { + assertEquals((Integer) STACK_EXPLODING_NUMBER, + times(STACK_EXPLODING_NUMBER, f -> f.fmap(x -> x + 1), io(0)).unsafePerformAsyncIO().join()); + assertEquals((Integer) STACK_EXPLODING_NUMBER, + times(STACK_EXPLODING_NUMBER, f -> f.zip(f.pure(x -> x + 1)), io(0)).unsafePerformAsyncIO() + .join()); + assertEquals((Integer) 0, + times(STACK_EXPLODING_NUMBER, f -> f.pure(0).discardR(f), io(0)).unsafePerformAsyncIO().join()); + assertEquals((Integer) 1, + times(STACK_EXPLODING_NUMBER, f -> f.pure(1).discardR(f), io(0)).unsafePerformAsyncIO().join()); + assertEquals((Integer) 0, + times(STACK_EXPLODING_NUMBER, f -> f.pure(1).discardL(f), io(0)).unsafePerformAsyncIO().join()); + assertEquals((Integer) STACK_EXPLODING_NUMBER, + times(STACK_EXPLODING_NUMBER, f -> f.flatMap(x -> f.pure(x + 1)), io(0)).unsafePerformAsyncIO() + .join()); + } + + @Test + public void recursiveAsyncFlatMapStackSafety() { + assertEquals((Integer) STACK_EXPLODING_NUMBER, + new Fn1, IO>() { + @Override + public IO apply(IO a) { + return a.flatMap(x -> x < STACK_EXPLODING_NUMBER ? apply(io(x + 1)) : io(x)); + } + }.apply(io(0)).unsafePerformAsyncIO().join()); } } \ No newline at end of file diff --git a/src/test/java/testsupport/EqualityAwareIO.java b/src/test/java/testsupport/EqualityAwareIO.java index 822cfebf7..b662f968d 100644 --- a/src/test/java/testsupport/EqualityAwareIO.java +++ b/src/test/java/testsupport/EqualityAwareIO.java @@ -6,9 +6,10 @@ import java.util.function.Function; +import static com.jnape.palatable.lambda.functions.IO.io; import static java.util.Objects.hash; -public final class EqualityAwareIO implements IO { +public final class EqualityAwareIO implements Monad> { private final IO io; public EqualityAwareIO(IO io) { @@ -16,45 +17,40 @@ public EqualityAwareIO(IO io) { } @Override - public A unsafePerformIO() { - return io.unsafePerformIO(); + public EqualityAwareIO flatMap(Function>> f) { + return new EqualityAwareIO<>(io.flatMap(f.andThen(x -> x.>coerce().io))); } @Override - public EqualityAwareIO flatMap(Function>> f) { - return new EqualityAwareIO<>(io.flatMap(f)); - } - - @Override - public EqualityAwareIO fmap(Function f) { - return new EqualityAwareIO<>(io.fmap(f)); + public EqualityAwareIO pure(B b) { + return new EqualityAwareIO<>(io(b)); } @Override - public EqualityAwareIO zip(Applicative, IO> appFn) { - return new EqualityAwareIO<>(io.zip(appFn)); + public EqualityAwareIO fmap(Function fn) { + return new EqualityAwareIO<>(io.fmap(fn)); } @Override - public EqualityAwareIO pure(B b) { - return new EqualityAwareIO<>(io.pure(b)); + public EqualityAwareIO zip(Applicative, EqualityAwareIO> appFn) { + return new EqualityAwareIO<>(io.zip(appFn.>>coerce().io)); } - @Override - public EqualityAwareIO discardL(Applicative> appB) { - return new EqualityAwareIO<>(io.discardL(appB)); + public EqualityAwareIO discardL(Applicative> appB) { + return new EqualityAwareIO<>(io.discardL(appB.>coerce().io)); } @Override - public EqualityAwareIO discardR(Applicative> appB) { - return new EqualityAwareIO<>(io.discardR(appB)); + public EqualityAwareIO discardR(Applicative> appB) { + return new EqualityAwareIO<>(io.discardR(appB.>coerce().io)); } @Override @SuppressWarnings("unchecked") public boolean equals(Object other) { - return other instanceof IO && ((IO) other).unsafePerformIO().equals(unsafePerformIO()); + return other instanceof EqualityAwareIO + && ((EqualityAwareIO) other).io.unsafePerformIO().equals(io.unsafePerformIO()); } @Override From 7cced8cd7b3af70f75418b986b68826d8ad670c9 Mon Sep 17 00:00:00 2001 From: jnape Date: Sun, 31 Mar 2019 16:18:15 -0500 Subject: [PATCH 04/69] Fixing javadocs for inequality operations --- .../com/jnape/palatable/lambda/functions/builtin/fn2/GT.java | 4 ++-- .../com/jnape/palatable/lambda/functions/builtin/fn2/GTE.java | 4 ++-- .../com/jnape/palatable/lambda/functions/builtin/fn2/LT.java | 4 ++-- .../com/jnape/palatable/lambda/functions/builtin/fn2/LTE.java | 4 ++-- .../jnape/palatable/lambda/functions/builtin/fn3/GTBy.java | 2 +- .../jnape/palatable/lambda/functions/builtin/fn3/GTEBy.java | 2 +- .../jnape/palatable/lambda/functions/builtin/fn3/LTBy.java | 2 +- .../jnape/palatable/lambda/functions/builtin/fn3/LTEBy.java | 2 +- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GT.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GT.java index 3c45e24cd..85cd2018c 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GT.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GT.java @@ -8,8 +8,8 @@ import static com.jnape.palatable.lambda.functions.builtin.fn3.GTBy.gtBy; /** - * Given two {@link Comparable} values of type A, return true if the first value is strictly - * greater than the second value; otherwise, return false. + * Given two {@link Comparable} values of type A, return true if the second value is strictly + * greater than the first value; otherwise, return false. * * @param the value type * @see GTBy diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GTE.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GTE.java index 23069dd03..a0203984d 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GTE.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GTE.java @@ -8,8 +8,8 @@ import static com.jnape.palatable.lambda.functions.builtin.fn3.GTEBy.gteBy; /** - * Given two {@link Comparable} values of type A, return true if the first value is greater - * than or equal to the second value according to {@link Comparable#compareTo(Object)}; otherwise, return false. + * Given two {@link Comparable} values of type A, return true if the second value is greater + * than or equal to the first value according to {@link Comparable#compareTo(Object)}; otherwise, return false. * * @param the value type * @see GTEBy diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LT.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LT.java index d6a1d6d99..68f9fe1b2 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LT.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LT.java @@ -8,8 +8,8 @@ import static com.jnape.palatable.lambda.functions.builtin.fn3.LTBy.ltBy; /** - * Given two {@link Comparable} values of type A, return true if the first value is strictly - * less than the second value; otherwise, return false. + * Given two {@link Comparable} values of type A, return true if the second value is strictly + * less than the first value; otherwise, return false. * * @param the value type * @see LTBy diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LTE.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LTE.java index 19d2424c4..72bdc97ad 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LTE.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LTE.java @@ -8,8 +8,8 @@ import static com.jnape.palatable.lambda.functions.builtin.fn3.LTEBy.lteBy; /** - * Given two {@link Comparable} values of type A, return true if the first value is less than - * or equal to the second value according to {@link Comparable#compareTo(Object)} otherwise, return false. + * Given two {@link Comparable} values of type A, return true if the second value is less than + * or equal to the first value according to {@link Comparable#compareTo(Object)} otherwise, return false. * * @param the value typ * @see LTEBy diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/GTBy.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/GTBy.java index 4428784e1..d79910faa 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/GTBy.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/GTBy.java @@ -9,7 +9,7 @@ /** * Given a mapping function from some type A to some {@link Comparable} type B and two values - * of type A, return true if the first value is strictly greater than the second value in + * 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 diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/GTEBy.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/GTEBy.java index 2c5d8ae26..f61fcb4c6 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/GTEBy.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/GTEBy.java @@ -11,7 +11,7 @@ /** * Given a mapping function from some type A to some {@link Comparable} type B and two values - * of type A, return true if the first value is greater than or equal to the second value in + * 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 Comparable#compareTo(Object)}; otherwise, return * false. * diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LTBy.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LTBy.java index 220a600e8..632cc9da0 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LTBy.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LTBy.java @@ -9,7 +9,7 @@ /** * Given a mapping function from some type A to some {@link Comparable} type B and two values - * of type A, return true if the first value is strictly less than the second value in terms + * of type A, return true if the second value is strictly less than the first value in terms * of their mapped B results; otherwise, return false. * * @param the value type 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 a83fdc9c5..c001a8c89 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 @@ -11,7 +11,7 @@ /** * Given a mapping function from some type A to some {@link Comparable} type B and two values - * of type A, return true if the first value is less than or equal to the second value in + * 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 Comparable#compareTo(Object)}; otherwise, return * false. * From 08ebc8e778ac0f8b63a8fb05981b7ad4d0954643 Mon Sep 17 00:00:00 2001 From: jnape Date: Sun, 31 Mar 2019 16:22:35 -0500 Subject: [PATCH 05/69] Moving IO to its own package --- CHANGELOG.md | 6 +++--- .../java/com/jnape/palatable/lambda/functions/Effect.java | 3 ++- .../palatable/lambda/functions/builtin/fn2/Alter.java | 2 +- .../functions/specialized/checked/CheckedEffect.java | 4 ++-- .../com/jnape/palatable/lambda/{functions => io}/IO.java | 2 +- .../com/jnape/palatable/lambda/lens/lenses/MapLens.java | 2 +- .../com/jnape/palatable/lambda/monoid/builtin/RunAll.java | 4 ++-- .../jnape/palatable/lambda/semigroup/builtin/RunAll.java | 2 +- .../jnape/palatable/lambda/{functions => io}/IOTest.java | 8 +++++--- .../jnape/palatable/lambda/monoid/builtin/RunAllTest.java | 2 +- .../palatable/lambda/semigroup/builtin/RunAllTest.java | 2 +- src/test/java/testsupport/EqualityAwareIO.java | 4 ++-- 12 files changed, 22 insertions(+), 19 deletions(-) rename src/main/java/com/jnape/palatable/lambda/{functions => io}/IO.java (99%) rename src/test/java/com/jnape/palatable/lambda/{functions => io}/IOTest.java (97%) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac54fccb9..40a692490 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,9 +5,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/). ## [Unreleased] ### Changed -- ***Breaking Change***: `IO` is now sealed. Most previous constructions using the static factory methods -should continue to work (by simply targeting `Supplier` now instead of an anonymous `IO`), but some might -need to be reworked, and subtyping is obviously no longer supported. +- ***Breaking Change***: `IO` is now sealed and moved to its own package. Most previous constructions using the static +factory methods should continue to work (by simply targeting `Supplier` now instead of an anonymous `IO`), but some +might need to be reworked, and subtyping is obviously no longer supported. - `IO` is now stack-safe, regardless of whether the composition nests linearly or recursively ## [3.3.0] - 2019-02-18 diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Effect.java b/src/main/java/com/jnape/palatable/lambda/functions/Effect.java index ea5bef72f..c08a44b01 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Effect.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Effect.java @@ -2,11 +2,12 @@ import com.jnape.palatable.lambda.adt.Unit; import com.jnape.palatable.lambda.functor.Applicative; +import com.jnape.palatable.lambda.io.IO; import java.util.function.Consumer; import java.util.function.Function; -import static com.jnape.palatable.lambda.functions.IO.io; +import static com.jnape.palatable.lambda.io.IO.io; import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; /** diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Alter.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Alter.java index f51050eae..488de31ce 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Alter.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Alter.java @@ -3,7 +3,7 @@ import com.jnape.palatable.lambda.functions.Effect; import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functions.Fn2; -import com.jnape.palatable.lambda.functions.IO; +import com.jnape.palatable.lambda.io.IO; import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedEffect.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedEffect.java index 1d833c91b..0dc24e4bb 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedEffect.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedEffect.java @@ -3,13 +3,13 @@ import com.jnape.palatable.lambda.adt.Unit; import com.jnape.palatable.lambda.functions.Effect; import com.jnape.palatable.lambda.functions.Fn1; -import com.jnape.palatable.lambda.functions.IO; +import com.jnape.palatable.lambda.io.IO; import com.jnape.palatable.lambda.functor.Applicative; import java.util.function.Consumer; import java.util.function.Function; -import static com.jnape.palatable.lambda.functions.IO.io; +import static com.jnape.palatable.lambda.io.IO.io; import static com.jnape.palatable.lambda.functions.specialized.checked.Runtime.throwChecked; /** diff --git a/src/main/java/com/jnape/palatable/lambda/functions/IO.java b/src/main/java/com/jnape/palatable/lambda/io/IO.java similarity index 99% rename from src/main/java/com/jnape/palatable/lambda/functions/IO.java rename to src/main/java/com/jnape/palatable/lambda/io/IO.java index a71dddebf..d659e35a8 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/IO.java +++ b/src/main/java/com/jnape/palatable/lambda/io/IO.java @@ -1,4 +1,4 @@ -package com.jnape.palatable.lambda.functions; +package com.jnape.palatable.lambda.io; import com.jnape.palatable.lambda.adt.Try; import com.jnape.palatable.lambda.adt.Unit; diff --git a/src/main/java/com/jnape/palatable/lambda/lens/lenses/MapLens.java b/src/main/java/com/jnape/palatable/lambda/lens/lenses/MapLens.java index e6df4f236..63823404f 100644 --- a/src/main/java/com/jnape/palatable/lambda/lens/lenses/MapLens.java +++ b/src/main/java/com/jnape/palatable/lambda/lens/lenses/MapLens.java @@ -3,7 +3,7 @@ import com.jnape.palatable.lambda.adt.Maybe; import com.jnape.palatable.lambda.adt.hlist.Tuple2; import com.jnape.palatable.lambda.functions.Fn1; -import com.jnape.palatable.lambda.functions.IO; +import com.jnape.palatable.lambda.io.IO; import com.jnape.palatable.lambda.functions.builtin.fn2.Filter; import com.jnape.palatable.lambda.lens.Iso; import com.jnape.palatable.lambda.lens.Lens; diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/RunAll.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/RunAll.java index 8e3c0d869..871deebb1 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/RunAll.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/RunAll.java @@ -1,12 +1,12 @@ package com.jnape.palatable.lambda.monoid.builtin; import com.jnape.palatable.lambda.functions.Fn1; -import com.jnape.palatable.lambda.functions.IO; +import com.jnape.palatable.lambda.io.IO; import com.jnape.palatable.lambda.functions.specialized.MonoidFactory; import com.jnape.palatable.lambda.monoid.Monoid; import com.jnape.palatable.lambda.semigroup.Semigroup; -import static com.jnape.palatable.lambda.functions.IO.io; +import static com.jnape.palatable.lambda.io.IO.io; import static com.jnape.palatable.lambda.monoid.Monoid.monoid; /** diff --git a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/RunAll.java b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/RunAll.java index 5ae09b8ac..b46ff9612 100644 --- a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/RunAll.java +++ b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/RunAll.java @@ -1,7 +1,7 @@ package com.jnape.palatable.lambda.semigroup.builtin; import com.jnape.palatable.lambda.functions.Fn1; -import com.jnape.palatable.lambda.functions.IO; +import com.jnape.palatable.lambda.io.IO; import com.jnape.palatable.lambda.functions.specialized.SemigroupFactory; import com.jnape.palatable.lambda.semigroup.Semigroup; diff --git a/src/test/java/com/jnape/palatable/lambda/functions/IOTest.java b/src/test/java/com/jnape/palatable/lambda/io/IOTest.java similarity index 97% rename from src/test/java/com/jnape/palatable/lambda/functions/IOTest.java rename to src/test/java/com/jnape/palatable/lambda/io/IOTest.java index 578f458f3..193c966d2 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/IOTest.java +++ b/src/test/java/com/jnape/palatable/lambda/io/IOTest.java @@ -1,6 +1,8 @@ -package com.jnape.palatable.lambda.functions; +package com.jnape.palatable.lambda.io; import com.jnape.palatable.lambda.adt.hlist.Tuple2; +import com.jnape.palatable.lambda.functions.Fn1; +import com.jnape.palatable.lambda.io.IO; import com.jnape.palatable.traitor.annotations.TestTraits; import com.jnape.palatable.traitor.runners.Traits; import org.junit.Test; @@ -16,8 +18,8 @@ import java.util.function.Function; import static com.jnape.palatable.lambda.adt.Unit.UNIT; -import static com.jnape.palatable.lambda.functions.IO.externallyManaged; -import static com.jnape.palatable.lambda.functions.IO.io; +import static com.jnape.palatable.lambda.io.IO.externallyManaged; +import static com.jnape.palatable.lambda.io.IO.io; import static com.jnape.palatable.lambda.functions.builtin.fn2.Tupler2.tupler; import static com.jnape.palatable.lambda.functions.builtin.fn3.Times.times; import static com.jnape.palatable.lambda.functions.specialized.checked.CheckedSupplier.checked; diff --git a/src/test/java/com/jnape/palatable/lambda/monoid/builtin/RunAllTest.java b/src/test/java/com/jnape/palatable/lambda/monoid/builtin/RunAllTest.java index 782ee334f..c0e9f6d17 100644 --- a/src/test/java/com/jnape/palatable/lambda/monoid/builtin/RunAllTest.java +++ b/src/test/java/com/jnape/palatable/lambda/monoid/builtin/RunAllTest.java @@ -3,7 +3,7 @@ import com.jnape.palatable.lambda.monoid.Monoid; import org.junit.Test; -import static com.jnape.palatable.lambda.functions.IO.io; +import static com.jnape.palatable.lambda.io.IO.io; import static com.jnape.palatable.lambda.monoid.builtin.RunAll.runAll; import static org.junit.Assert.assertEquals; diff --git a/src/test/java/com/jnape/palatable/lambda/semigroup/builtin/RunAllTest.java b/src/test/java/com/jnape/palatable/lambda/semigroup/builtin/RunAllTest.java index c8840da69..329fe8429 100644 --- a/src/test/java/com/jnape/palatable/lambda/semigroup/builtin/RunAllTest.java +++ b/src/test/java/com/jnape/palatable/lambda/semigroup/builtin/RunAllTest.java @@ -3,7 +3,7 @@ import com.jnape.palatable.lambda.semigroup.Semigroup; import org.junit.Test; -import static com.jnape.palatable.lambda.functions.IO.io; +import static com.jnape.palatable.lambda.io.IO.io; import static com.jnape.palatable.lambda.semigroup.builtin.RunAll.runAll; import static org.junit.Assert.assertEquals; diff --git a/src/test/java/testsupport/EqualityAwareIO.java b/src/test/java/testsupport/EqualityAwareIO.java index b662f968d..1a82def86 100644 --- a/src/test/java/testsupport/EqualityAwareIO.java +++ b/src/test/java/testsupport/EqualityAwareIO.java @@ -1,12 +1,12 @@ package testsupport; -import com.jnape.palatable.lambda.functions.IO; +import com.jnape.palatable.lambda.io.IO; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.monad.Monad; import java.util.function.Function; -import static com.jnape.palatable.lambda.functions.IO.io; +import static com.jnape.palatable.lambda.io.IO.io; import static java.util.Objects.hash; public final class EqualityAwareIO implements Monad> { From 05356aa8a872b20ea3906b757ee181499748e7fe Mon Sep 17 00:00:00 2001 From: jnape Date: Sun, 31 Mar 2019 17:03:54 -0500 Subject: [PATCH 06/69] Adding Lazy, a monad representing a lazy computation --- CHANGELOG.md | 3 + .../lambda/functor/builtin/Lazy.java | 153 ++++++++++++++++++ .../lambda/functor/builtin/LazyTest.java | 52 ++++++ .../com/jnape/palatable/lambda/io/IOTest.java | 24 ++- src/test/java/testsupport/Constants.java | 8 + 5 files changed, 227 insertions(+), 13 deletions(-) create mode 100644 src/main/java/com/jnape/palatable/lambda/functor/builtin/Lazy.java create mode 100644 src/test/java/com/jnape/palatable/lambda/functor/builtin/LazyTest.java create mode 100644 src/test/java/testsupport/Constants.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 40a692490..04d86f6a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,9 @@ factory methods should continue to work (by simply targeting `Supplier` now inst might need to be reworked, and subtyping is obviously no longer supported. - `IO` is now stack-safe, regardless of whether the composition nests linearly or recursively +### Added +- `Lazy`, a monad supporting stack-safe lazy evaluation + ## [3.3.0] - 2019-02-18 ### Added - `MergeMaps`, a `Monoid` on `Map` formed by `Map#merge` diff --git a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Lazy.java b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Lazy.java new file mode 100644 index 000000000..3e61d3d29 --- /dev/null +++ b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Lazy.java @@ -0,0 +1,153 @@ +package com.jnape.palatable.lambda.functor.builtin; + +import com.jnape.palatable.lambda.adt.hlist.Tuple2; +import com.jnape.palatable.lambda.functions.Fn0; +import com.jnape.palatable.lambda.functor.Applicative; +import com.jnape.palatable.lambda.monad.Monad; + +import java.util.LinkedList; +import java.util.function.Function; +import java.util.function.Supplier; + +import static com.jnape.palatable.lambda.adt.hlist.HList.tuple; +import static com.jnape.palatable.lambda.functions.Fn0.fn0; +import static com.jnape.palatable.lambda.functions.builtin.fn2.Into.into; +import static com.jnape.palatable.lambda.functions.recursion.RecursiveResult.recurse; +import static com.jnape.palatable.lambda.functions.recursion.RecursiveResult.terminate; +import static com.jnape.palatable.lambda.functions.recursion.Trampoline.trampoline; + +/** + * A {@link Monad} representing a lazily-computed value. Stack-safe. + * + * @param the value type + */ +public abstract class Lazy implements Monad> { + + private Lazy() { + } + + /** + * Returns the value represented by this lazy computation. + * + * @return the value + */ + public abstract A value(); + + /** + * {@inheritDoc} + */ + @Override + public Lazy flatMap(Function>> f) { + @SuppressWarnings("unchecked") Lazy source = (Lazy) this; + @SuppressWarnings({"unchecked", "RedundantCast"}) + Function> flatMap = (Function>) (Object) f; + return new Compose<>(source, flatMap); + } + + /** + * {@inheritDoc} + */ + @Override + public Lazy pure(B b) { + return lazy(b); + } + + /** + * {@inheritDoc} + */ + @Override + public Lazy fmap(Function fn) { + return Monad.super.fmap(fn).coerce(); + } + + /** + * {@inheritDoc} + */ + @Override + public Lazy zip(Applicative, Lazy> appFn) { + return Monad.super.zip(appFn).coerce(); + } + + /** + * {@inheritDoc} + */ + @Override + public Lazy discardL(Applicative> appB) { + return Monad.super.discardL(appB).coerce(); + } + + /** + * {@inheritDoc} + */ + @Override + public Lazy discardR(Applicative> appB) { + return Monad.super.discardR(appB).coerce(); + } + + /** + * Lift a pure value into a lazy computation. + * + * @param value the value + * @param the value type + * @return the new {@link Lazy} + */ + public static Lazy lazy(A value) { + return lazy(() -> value); + } + + /** + * Wrap a computation in a lazy computation. + * + * @param supplier the computation + * @param the value type + * @return the new {@link Lazy} + */ + public static Lazy lazy(Supplier supplier) { + return new Val<>(fn0(supplier)); + } + + private static final class Val extends Lazy { + private final Fn0 fn0; + + private Val(Fn0 fn0) { + this.fn0 = fn0; + } + + @Override + public A value() { + return fn0.apply(); + } + } + + private static final class Compose extends Lazy { + private final Lazy source; + private final Function> flatMap; + + private Compose(Lazy source, + Function> flatMap) { + this.source = source; + this.flatMap = flatMap; + } + + @Override + public A value() { + @SuppressWarnings("unchecked") Tuple2, LinkedList>>> tuple = + tuple((Lazy) this, new LinkedList<>()); + @SuppressWarnings("unchecked") + A a = (A) trampoline(into((source, flatMaps) -> { + if (source instanceof Compose) { + Compose nested = (Compose) source; + flatMaps.push(nested.flatMap); + return recurse(tuple(nested.source, flatMaps)); + } + + if (flatMaps.isEmpty()) + return terminate(source.value()); + + return recurse(tuple(flatMaps.pop().apply(source.value()), flatMaps)); + }), tuple); + + return a; + } + } +} diff --git a/src/test/java/com/jnape/palatable/lambda/functor/builtin/LazyTest.java b/src/test/java/com/jnape/palatable/lambda/functor/builtin/LazyTest.java new file mode 100644 index 000000000..f8f80e2d9 --- /dev/null +++ b/src/test/java/com/jnape/palatable/lambda/functor/builtin/LazyTest.java @@ -0,0 +1,52 @@ +package com.jnape.palatable.lambda.functor.builtin; + +import org.junit.Test; + +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Function; + +import static com.jnape.palatable.lambda.functions.builtin.fn3.Times.times; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static testsupport.Constants.STACK_EXPLODING_NUMBER; + +public class LazyTest { + + @Test + public void valueExtraction() { + assertEquals("foo", lazy("foo").value()); + assertEquals("foo", lazy(() -> "foo").value()); + } + + @Test + public void lazyEvaluation() { + AtomicBoolean invoked = new AtomicBoolean(false); + Lazy lazy = lazy(0).flatMap(x -> { + invoked.set(true); + return lazy(x + 1); + }); + assertFalse(invoked.get()); + assertEquals((Integer) 1, lazy.value()); + assertTrue(invoked.get()); + } + + @Test + public void linearStackSafety() { + assertEquals(STACK_EXPLODING_NUMBER, + times(STACK_EXPLODING_NUMBER, f -> f.fmap(x -> x + 1), lazy(0)).value()); + } + + @Test + public void recursiveStackSafety() { + assertEquals(STACK_EXPLODING_NUMBER, + new Function, Lazy>() { + @Override + public Lazy apply(Lazy lazy) { + return lazy.flatMap(x -> x < STACK_EXPLODING_NUMBER ? apply(lazy(x + 1)) : lazy(x)); + } + }.apply(lazy(0)) + .value()); + } +} \ No newline at end of file diff --git a/src/test/java/com/jnape/palatable/lambda/io/IOTest.java b/src/test/java/com/jnape/palatable/lambda/io/IOTest.java index 193c966d2..af584a03b 100644 --- a/src/test/java/com/jnape/palatable/lambda/io/IOTest.java +++ b/src/test/java/com/jnape/palatable/lambda/io/IOTest.java @@ -2,7 +2,6 @@ import com.jnape.palatable.lambda.adt.hlist.Tuple2; import com.jnape.palatable.lambda.functions.Fn1; -import com.jnape.palatable.lambda.io.IO; import com.jnape.palatable.traitor.annotations.TestTraits; import com.jnape.palatable.traitor.runners.Traits; import org.junit.Test; @@ -18,21 +17,20 @@ import java.util.function.Function; import static com.jnape.palatable.lambda.adt.Unit.UNIT; -import static com.jnape.palatable.lambda.io.IO.externallyManaged; -import static com.jnape.palatable.lambda.io.IO.io; import static com.jnape.palatable.lambda.functions.builtin.fn2.Tupler2.tupler; import static com.jnape.palatable.lambda.functions.builtin.fn3.Times.times; import static com.jnape.palatable.lambda.functions.specialized.checked.CheckedSupplier.checked; +import static com.jnape.palatable.lambda.io.IO.externallyManaged; +import static com.jnape.palatable.lambda.io.IO.io; import static java.util.concurrent.CompletableFuture.completedFuture; import static java.util.concurrent.Executors.newFixedThreadPool; import static java.util.concurrent.ForkJoinPool.commonPool; import static org.junit.Assert.assertEquals; +import static testsupport.Constants.STACK_EXPLODING_NUMBER; @RunWith(Traits.class) public class IOTest { - private static final int STACK_EXPLODING_NUMBER = 50_000; - @TestTraits({FunctorLaws.class, ApplicativeLaws.class, MonadLaws.class}) public EqualityAwareIO testSubject() { return new EqualityAwareIO<>(io(1)); @@ -125,9 +123,9 @@ public void exceptionallyRescuesFutures() { @Test public void linearSyncStackSafety() { - assertEquals((Integer) STACK_EXPLODING_NUMBER, + assertEquals(STACK_EXPLODING_NUMBER, times(STACK_EXPLODING_NUMBER, f -> f.fmap(x -> x + 1), io(0)).unsafePerformIO()); - assertEquals((Integer) STACK_EXPLODING_NUMBER, + assertEquals(STACK_EXPLODING_NUMBER, times(STACK_EXPLODING_NUMBER, f -> f.zip(f.pure(x -> x + 1)), io(0)).unsafePerformIO()); assertEquals((Integer) 0, times(STACK_EXPLODING_NUMBER, f -> f.pure(0).discardR(f), io(0)).unsafePerformIO()); @@ -135,13 +133,13 @@ public void linearSyncStackSafety() { times(STACK_EXPLODING_NUMBER, f -> f.pure(1).discardR(f), io(0)).unsafePerformIO()); assertEquals((Integer) 0, times(STACK_EXPLODING_NUMBER, f -> f.pure(1).discardL(f), io(0)).unsafePerformIO()); - assertEquals((Integer) STACK_EXPLODING_NUMBER, + assertEquals(STACK_EXPLODING_NUMBER, times(STACK_EXPLODING_NUMBER, f -> f.flatMap(x -> f.pure(x + 1)), io(0)).unsafePerformIO()); } @Test public void recursiveSyncFlatMapStackSafety() { - assertEquals((Integer) STACK_EXPLODING_NUMBER, + assertEquals(STACK_EXPLODING_NUMBER, new Fn1, IO>() { @Override public IO apply(IO a) { @@ -153,9 +151,9 @@ public IO apply(IO a) { @Test public void linearAsyncStackSafety() { - assertEquals((Integer) STACK_EXPLODING_NUMBER, + assertEquals(STACK_EXPLODING_NUMBER, times(STACK_EXPLODING_NUMBER, f -> f.fmap(x -> x + 1), io(0)).unsafePerformAsyncIO().join()); - assertEquals((Integer) STACK_EXPLODING_NUMBER, + assertEquals(STACK_EXPLODING_NUMBER, times(STACK_EXPLODING_NUMBER, f -> f.zip(f.pure(x -> x + 1)), io(0)).unsafePerformAsyncIO() .join()); assertEquals((Integer) 0, @@ -164,14 +162,14 @@ public void linearAsyncStackSafety() { times(STACK_EXPLODING_NUMBER, f -> f.pure(1).discardR(f), io(0)).unsafePerformAsyncIO().join()); assertEquals((Integer) 0, times(STACK_EXPLODING_NUMBER, f -> f.pure(1).discardL(f), io(0)).unsafePerformAsyncIO().join()); - assertEquals((Integer) STACK_EXPLODING_NUMBER, + assertEquals(STACK_EXPLODING_NUMBER, times(STACK_EXPLODING_NUMBER, f -> f.flatMap(x -> f.pure(x + 1)), io(0)).unsafePerformAsyncIO() .join()); } @Test public void recursiveAsyncFlatMapStackSafety() { - assertEquals((Integer) STACK_EXPLODING_NUMBER, + assertEquals(STACK_EXPLODING_NUMBER, new Fn1, IO>() { @Override public IO apply(IO a) { diff --git a/src/test/java/testsupport/Constants.java b/src/test/java/testsupport/Constants.java new file mode 100644 index 000000000..a439920d6 --- /dev/null +++ b/src/test/java/testsupport/Constants.java @@ -0,0 +1,8 @@ +package testsupport; + +public final class Constants { + public static final Integer STACK_EXPLODING_NUMBER = 50_000; + + private Constants() { + } +} From 4e76e97286ec21e1a9a8763b9c647671c8a63fd6 Mon Sep 17 00:00:00 2001 From: jnape Date: Tue, 9 Apr 2019 22:33:14 -0500 Subject: [PATCH 07/69] Adding LazyRec for modelling lazy, stack-safe recursion --- .gitignore | 3 +- CHANGELOG.md | 1 + .../lambda/functions/builtin/fn2/LazyRec.java | 57 +++++++++++++++ .../lambda/functor/builtin/Lazy.java | 14 ++-- .../palatable/lambda/functions/Fn0Test.java | 21 ------ .../palatable/lambda/functions/Fn1Test.java | 11 +-- .../functions/builtin/fn2/LazyRecTest.java | 37 ++++++++++ .../lambda/functor/builtin/LazyTest.java | 26 +++++-- .../com/jnape/palatable/lambda/io/IOTest.java | 6 +- .../jnape/palatable/lambda/lens/IsoTest.java | 7 +- .../jnape/palatable/lambda/lens/LensTest.java | 12 ++-- .../lambda/semigroup/SemigroupTest.java | 1 - .../java/testsupport/EqualityAwareFn0.java | 72 ------------------- .../java/testsupport/EqualityAwareFn1.java | 55 -------------- .../java/testsupport/EqualityAwareIO.java | 60 ---------------- .../java/testsupport/EqualityAwareIso.java | 72 ------------------- .../java/testsupport/EqualityAwareLens.java | 57 --------------- src/test/java/testsupport/EquatableM.java | 58 +++++++++++++++ 18 files changed, 202 insertions(+), 368 deletions(-) create mode 100644 src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LazyRec.java delete mode 100644 src/test/java/com/jnape/palatable/lambda/functions/Fn0Test.java create mode 100644 src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/LazyRecTest.java delete mode 100644 src/test/java/testsupport/EqualityAwareFn0.java delete mode 100644 src/test/java/testsupport/EqualityAwareFn1.java delete mode 100644 src/test/java/testsupport/EqualityAwareIO.java delete mode 100644 src/test/java/testsupport/EqualityAwareIso.java delete mode 100644 src/test/java/testsupport/EqualityAwareLens.java create mode 100644 src/test/java/testsupport/EquatableM.java diff --git a/.gitignore b/.gitignore index 3425b85ff..6b65bb21d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .idea/* target/* -*.iml \ No newline at end of file +*.iml +.java-version \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 04d86f6a0..4e7234879 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ might need to be reworked, and subtyping is obviously no longer supported. ### Added - `Lazy`, a monad supporting stack-safe lazy evaluation +- `LazyRec`, a function for writing stack-safe recursive algorithms embedded in `Lazy` ## [3.3.0] - 2019-02-18 ### Added diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LazyRec.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LazyRec.java new file mode 100644 index 000000000..1e1ffbc8f --- /dev/null +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LazyRec.java @@ -0,0 +1,57 @@ +package com.jnape.palatable.lambda.functions.builtin.fn2; + +import com.jnape.palatable.lambda.functions.Fn1; +import com.jnape.palatable.lambda.functions.Fn2; +import com.jnape.palatable.lambda.functor.builtin.Lazy; + +import java.util.function.BiFunction; +import java.util.function.Function; + +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; +import static com.jnape.palatable.lambda.monad.Monad.join; + +/** + * Given a {@link BiFunction} that receives a recursive function and an input and yields a {@link Lazy lazy} result, and + * an input, produce a {@link Lazy lazy} result that, when forced, will recursively invoke the function until it + * terminates in a stack-safe way. + *

+ * Example: + *

+ * 
+ * Lazy lazyFactorial = lazyRec((fact, x) -> x.equals(ONE)
+ *                                                               ? lazy(x)
+ *                                                               : fact.apply(x.subtract(ONE)).fmap(y -> y.multiply(x)),
+ *                                                  BigInteger.valueOf(50_000));
+ * BigInteger value = lazyFactorial.value(); // 3.34732050959714483691547609407148647791277322381045 × 10^213236
+ * 
+ * 
+ * + * @param the input type + * @param the output type + */ +public final class LazyRec implements + Fn2>, A, Lazy>, A, Lazy> { + + private static final LazyRec INSTANCE = new LazyRec<>(); + + private LazyRec() { + } + + @Override + public Lazy apply(BiFunction>, A, Lazy> fn, A a) { + return join(lazy(() -> fn.apply(nextA -> apply(fn, nextA), a))); + } + + @SuppressWarnings("unchecked") + public static LazyRec lazyRec() { + return (LazyRec) INSTANCE; + } + + public static Fn1> lazyRec(BiFunction>, A, Lazy> fn) { + return LazyRec.lazyRec().apply(fn); + } + + public static Lazy lazyRec(BiFunction>, A, Lazy> fn, A a) { + return lazyRec(fn).apply(a); + } +} diff --git a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Lazy.java b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Lazy.java index 3e61d3d29..f3f4be0ac 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Lazy.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Lazy.java @@ -48,7 +48,7 @@ public Lazy flatMap(Function>> f) { * {@inheritDoc} */ @Override - public Lazy pure(B b) { + public final Lazy pure(B b) { return lazy(b); } @@ -56,7 +56,7 @@ public Lazy pure(B b) { * {@inheritDoc} */ @Override - public Lazy fmap(Function fn) { + public final Lazy fmap(Function fn) { return Monad.super.fmap(fn).coerce(); } @@ -72,7 +72,7 @@ public Lazy zip(Applicative, Lazy> ap * {@inheritDoc} */ @Override - public Lazy discardL(Applicative> appB) { + public final Lazy discardL(Applicative> appB) { return Monad.super.discardL(appB).coerce(); } @@ -80,7 +80,7 @@ public Lazy discardL(Applicative> appB) { * {@inheritDoc} */ @Override - public Lazy discardR(Applicative> appB) { + public final Lazy discardR(Applicative> appB) { return Monad.super.discardR(appB).coerce(); } @@ -103,13 +103,13 @@ public static Lazy lazy(A value) { * @return the new {@link Lazy} */ public static Lazy lazy(Supplier supplier) { - return new Val<>(fn0(supplier)); + return new Later<>(fn0(supplier)); } - private static final class Val extends Lazy { + private static final class Later extends Lazy { private final Fn0 fn0; - private Val(Fn0 fn0) { + private Later(Fn0 fn0) { this.fn0 = fn0; } diff --git a/src/test/java/com/jnape/palatable/lambda/functions/Fn0Test.java b/src/test/java/com/jnape/palatable/lambda/functions/Fn0Test.java deleted file mode 100644 index d04084205..000000000 --- a/src/test/java/com/jnape/palatable/lambda/functions/Fn0Test.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.jnape.palatable.lambda.functions; - -import com.jnape.palatable.traitor.annotations.TestTraits; -import com.jnape.palatable.traitor.runners.Traits; -import org.junit.runner.RunWith; -import testsupport.EqualityAwareFn0; -import testsupport.traits.ApplicativeLaws; -import testsupport.traits.FunctorLaws; -import testsupport.traits.MonadLaws; - -import static com.jnape.palatable.lambda.adt.Unit.UNIT; -import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; - -@RunWith(Traits.class) -public class Fn0Test { - - @TestTraits({FunctorLaws.class, ApplicativeLaws.class, MonadLaws.class}) - public Fn0 testSubject() { - return new EqualityAwareFn0<>(constantly(1).thunk(UNIT)); - } -} \ No newline at end of file diff --git a/src/test/java/com/jnape/palatable/lambda/functions/Fn1Test.java b/src/test/java/com/jnape/palatable/lambda/functions/Fn1Test.java index bd3237f2c..20074539b 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/Fn1Test.java +++ b/src/test/java/com/jnape/palatable/lambda/functions/Fn1Test.java @@ -4,7 +4,7 @@ import com.jnape.palatable.traitor.runners.Traits; import org.junit.Test; import org.junit.runner.RunWith; -import testsupport.EqualityAwareFn1; +import testsupport.EquatableM; import testsupport.traits.ApplicativeLaws; import testsupport.traits.FunctorLaws; import testsupport.traits.MonadLaws; @@ -13,6 +13,7 @@ import static com.jnape.palatable.lambda.adt.Maybe.just; import static com.jnape.palatable.lambda.adt.hlist.HList.tuple; +import static com.jnape.palatable.lambda.functions.Fn1.fn1; import static com.jnape.palatable.lambda.functions.builtin.fn2.ReduceLeft.reduceLeft; import static java.util.Arrays.asList; import static org.junit.Assert.assertEquals; @@ -21,8 +22,8 @@ public class Fn1Test { @TestTraits({FunctorLaws.class, ApplicativeLaws.class, MonadLaws.class}) - public Fn1 testSubject() { - return new EqualityAwareFn1<>("1", Integer::parseInt); + public EquatableM, ?> testSubject() { + return new EquatableM<>(fn1(Integer::parseInt), f -> f.apply("1")); } @Test @@ -35,9 +36,9 @@ public void profunctorProperties() { } @Test - public void fn1() { + public void staticFactoryMethods() { Function parseInt = Integer::parseInt; - assertEquals((Integer) 1, Fn1.fn1(parseInt).apply("1")); + assertEquals((Integer) 1, fn1(parseInt).apply("1")); } @Test diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/LazyRecTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/LazyRecTest.java new file mode 100644 index 000000000..8987fe32a --- /dev/null +++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/LazyRecTest.java @@ -0,0 +1,37 @@ +package com.jnape.palatable.lambda.functions.builtin.fn2; + +import org.junit.Test; + +import java.util.concurrent.atomic.AtomicBoolean; + +import static com.jnape.palatable.lambda.functions.builtin.fn2.LazyRec.lazyRec; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static testsupport.Constants.STACK_EXPLODING_NUMBER; + +public class LazyRecTest { + + @Test + public void recursivelyComputesValue() { + assertEquals(STACK_EXPLODING_NUMBER, + LazyRec.lazyRec((f, x) -> x < STACK_EXPLODING_NUMBER + ? f.apply(x + 1) + : lazy(x), + 0) + .value()); + } + + @Test + public void defersAllComputationUntilForced() { + AtomicBoolean invoked = new AtomicBoolean(false); + lazyRec((f, x) -> { + invoked.set(true); + return lazy(x); + }, + 0); + + assertFalse(invoked.get()); + } + +} \ No newline at end of file diff --git a/src/test/java/com/jnape/palatable/lambda/functor/builtin/LazyTest.java b/src/test/java/com/jnape/palatable/lambda/functor/builtin/LazyTest.java index f8f80e2d9..c506f357c 100644 --- a/src/test/java/com/jnape/palatable/lambda/functor/builtin/LazyTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functor/builtin/LazyTest.java @@ -1,9 +1,16 @@ package com.jnape.palatable.lambda.functor.builtin; +import com.jnape.palatable.lambda.functions.Fn1; +import com.jnape.palatable.traitor.annotations.TestTraits; +import com.jnape.palatable.traitor.runners.Traits; import org.junit.Test; +import org.junit.runner.RunWith; +import testsupport.EquatableM; +import testsupport.traits.ApplicativeLaws; +import testsupport.traits.FunctorLaws; +import testsupport.traits.MonadLaws; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Function; import static com.jnape.palatable.lambda.functions.builtin.fn3.Times.times; import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; @@ -12,8 +19,14 @@ import static org.junit.Assert.assertTrue; import static testsupport.Constants.STACK_EXPLODING_NUMBER; +@RunWith(Traits.class) public class LazyTest { + @TestTraits({FunctorLaws.class, ApplicativeLaws.class, MonadLaws.class}) + public EquatableM, Integer> testSubject() { + return new EquatableM<>(lazy(0), Lazy::value); + } + @Test public void valueExtraction() { assertEquals("foo", lazy("foo").value()); @@ -41,12 +54,13 @@ public void linearStackSafety() { @Test public void recursiveStackSafety() { assertEquals(STACK_EXPLODING_NUMBER, - new Function, Lazy>() { + new Fn1, Lazy>() { @Override - public Lazy apply(Lazy lazy) { - return lazy.flatMap(x -> x < STACK_EXPLODING_NUMBER ? apply(lazy(x + 1)) : lazy(x)); + public Lazy apply(Lazy lazyX) { + return lazyX.flatMap(x -> x < STACK_EXPLODING_NUMBER + ? apply(lazy(x + 1)) + : lazy(x)); } - }.apply(lazy(0)) - .value()); + }.apply(lazy(0)).value()); } } \ No newline at end of file diff --git a/src/test/java/com/jnape/palatable/lambda/io/IOTest.java b/src/test/java/com/jnape/palatable/lambda/io/IOTest.java index af584a03b..0c9ba0535 100644 --- a/src/test/java/com/jnape/palatable/lambda/io/IOTest.java +++ b/src/test/java/com/jnape/palatable/lambda/io/IOTest.java @@ -6,7 +6,7 @@ import com.jnape.palatable.traitor.runners.Traits; import org.junit.Test; import org.junit.runner.RunWith; -import testsupport.EqualityAwareIO; +import testsupport.EquatableM; import testsupport.traits.ApplicativeLaws; import testsupport.traits.FunctorLaws; import testsupport.traits.MonadLaws; @@ -32,8 +32,8 @@ public class IOTest { @TestTraits({FunctorLaws.class, ApplicativeLaws.class, MonadLaws.class}) - public EqualityAwareIO testSubject() { - return new EqualityAwareIO<>(io(1)); + public EquatableM, Integer> testSubject() { + return new EquatableM<>(io(1), IO::unsafePerformIO); } @Test diff --git a/src/test/java/com/jnape/palatable/lambda/lens/IsoTest.java b/src/test/java/com/jnape/palatable/lambda/lens/IsoTest.java index 016de15ee..003c7bda7 100644 --- a/src/test/java/com/jnape/palatable/lambda/lens/IsoTest.java +++ b/src/test/java/com/jnape/palatable/lambda/lens/IsoTest.java @@ -1,11 +1,12 @@ package com.jnape.palatable.lambda.lens; import com.jnape.palatable.lambda.adt.Maybe; +import com.jnape.palatable.lambda.functor.builtin.Const; import com.jnape.palatable.traitor.annotations.TestTraits; import com.jnape.palatable.traitor.runners.Traits; import org.junit.Test; import org.junit.runner.RunWith; -import testsupport.EqualityAwareIso; +import testsupport.EquatableM; import testsupport.traits.ApplicativeLaws; import testsupport.traits.FunctorLaws; import testsupport.traits.MonadLaws; @@ -27,8 +28,8 @@ public class IsoTest { iso(Integer::parseInt, dbl -> dbl.toString().chars().mapToObj(x -> (char) x).collect(toList())); @TestTraits({FunctorLaws.class, ApplicativeLaws.class, MonadLaws.class}) - public Iso, Integer, Double> testSubject() { - return new EqualityAwareIso<>("123", 1.23d, ISO); + public EquatableM, ?> testSubject() { + return new EquatableM<>(ISO, iso -> iso.apply(Const::new, "123")); } @Test diff --git a/src/test/java/com/jnape/palatable/lambda/lens/LensTest.java b/src/test/java/com/jnape/palatable/lambda/lens/LensTest.java index 12d94b30c..f5478be8f 100644 --- a/src/test/java/com/jnape/palatable/lambda/lens/LensTest.java +++ b/src/test/java/com/jnape/palatable/lambda/lens/LensTest.java @@ -8,7 +8,7 @@ import com.jnape.palatable.traitor.runners.Traits; import org.junit.Test; import org.junit.runner.RunWith; -import testsupport.EqualityAwareLens; +import testsupport.EquatableM; import testsupport.traits.ApplicativeLaws; import testsupport.traits.FunctorLaws; import testsupport.traits.MonadLaws; @@ -35,12 +35,14 @@ @RunWith(Traits.class) public class LensTest { - private static final Lens>, Map>, List, Set> EARLIER_LENS = lens(m -> m.get("foo"), (m, s) -> singletonMap("foo", s)); - private static final Lens, Set, String, Integer> LENS = lens(xs -> xs.get(0), (xs, i) -> singleton(i)); + private static final Lens>, Map>, List, Set> + EARLIER_LENS = lens(m -> m.get("foo"), (m, s) -> singletonMap("foo", s)); + private static final Lens, Set, String, Integer> + LENS = lens(xs -> xs.get(0), (xs, i) -> singleton(i)); @TestTraits({FunctorLaws.class, ApplicativeLaws.class, MonadLaws.class}) - public Lens, List, Integer, String> testSubject() { - return new EqualityAwareLens<>(emptyMap(), lens(m -> m.get("foo"), (m, s) -> singletonList(m.get(s)))); + public EquatableM, ?, Integer, String, Lens>, ?> testSubject() { + return new EquatableM<>(lens(m -> m.get("foo"), (m, s) -> singletonList(m.get(s))), l -> view(l, emptyMap())); } @Test diff --git a/src/test/java/com/jnape/palatable/lambda/semigroup/SemigroupTest.java b/src/test/java/com/jnape/palatable/lambda/semigroup/SemigroupTest.java index 94697cda3..ec20057bc 100644 --- a/src/test/java/com/jnape/palatable/lambda/semigroup/SemigroupTest.java +++ b/src/test/java/com/jnape/palatable/lambda/semigroup/SemigroupTest.java @@ -1,6 +1,5 @@ package com.jnape.palatable.lambda.semigroup; -import com.jnape.palatable.lambda.semigroup.Semigroup; import org.junit.Test; import static java.util.Arrays.asList; diff --git a/src/test/java/testsupport/EqualityAwareFn0.java b/src/test/java/testsupport/EqualityAwareFn0.java deleted file mode 100644 index 17b3318d5..000000000 --- a/src/test/java/testsupport/EqualityAwareFn0.java +++ /dev/null @@ -1,72 +0,0 @@ -package testsupport; - -import com.jnape.palatable.lambda.adt.Unit; -import com.jnape.palatable.lambda.functions.Fn0; -import com.jnape.palatable.lambda.functions.Fn1; -import com.jnape.palatable.lambda.functor.Applicative; -import com.jnape.palatable.lambda.monad.Monad; - -import java.util.function.Function; - -import static com.jnape.palatable.lambda.adt.Unit.UNIT; -import static java.util.Objects.hash; - -public final class EqualityAwareFn0 implements Fn0 { - private final Fn0 fn; - - public EqualityAwareFn0(Fn0 fn) { - this.fn = fn; - } - - @Override - public A apply() { - return fn.apply(); - } - - @Override - public A apply(Unit unit) { - return apply(); - } - - @Override - public EqualityAwareFn0 flatMap(Function>> f) { - return new EqualityAwareFn0<>(fn.flatMap(f)); - } - - @Override - public EqualityAwareFn0 fmap(Function f) { - return new EqualityAwareFn0<>(fn.fmap(f)); - } - - @Override - public EqualityAwareFn0 zip(Applicative, Fn1> appFn) { - return new EqualityAwareFn0<>(fn.zip(appFn)); - } - - @Override - public EqualityAwareFn0 pure(B b) { - return new EqualityAwareFn0<>(fn.pure(b)); - } - - - @Override - public EqualityAwareFn0 discardL(Applicative> appB) { - return new EqualityAwareFn0<>(fn.discardL(appB)); - } - - @Override - public EqualityAwareFn0 discardR(Applicative> appB) { - return new EqualityAwareFn0<>(fn.discardR(appB)); - } - - @Override - @SuppressWarnings("unchecked") - public boolean equals(Object other) { - return other instanceof Fn0 && ((Fn0) other).apply(UNIT).equals(apply(UNIT)); - } - - @Override - public int hashCode() { - return hash(fn); - } -} diff --git a/src/test/java/testsupport/EqualityAwareFn1.java b/src/test/java/testsupport/EqualityAwareFn1.java deleted file mode 100644 index 464962d19..000000000 --- a/src/test/java/testsupport/EqualityAwareFn1.java +++ /dev/null @@ -1,55 +0,0 @@ -package testsupport; - -import com.jnape.palatable.lambda.functions.Fn1; -import com.jnape.palatable.lambda.functor.Applicative; -import com.jnape.palatable.lambda.monad.Monad; - -import java.util.function.Function; - -import static java.util.Objects.hash; - -public final class EqualityAwareFn1 implements Fn1 { - private final A a; - private final Fn1 fn; - - public EqualityAwareFn1(A a, Fn1 fn) { - this.a = a; - this.fn = fn; - } - - @Override - public B apply(A a) { - return fn.apply(a); - } - - @Override - public EqualityAwareFn1 flatMap(Function>> f) { - return new EqualityAwareFn1<>(a, fn.flatMap(f)); - } - - @Override - public EqualityAwareFn1 fmap(Function f) { - return new EqualityAwareFn1<>(a, fn.fmap(f)); - } - - @Override - public EqualityAwareFn1 zip(Applicative, Fn1> appFn) { - return new EqualityAwareFn1<>(a, fn.zip(appFn)); - } - - @Override - public EqualityAwareFn1 pure(C c) { - return new EqualityAwareFn1<>(a, fn.pure(c)); - } - - @Override - @SuppressWarnings("unchecked") - public boolean equals(Object other) { - return other instanceof Fn1 && ((Fn1) other).apply(a).equals(apply(a)); - } - - @Override - public int hashCode() { - return hash(a, fn); - } -} diff --git a/src/test/java/testsupport/EqualityAwareIO.java b/src/test/java/testsupport/EqualityAwareIO.java deleted file mode 100644 index 1a82def86..000000000 --- a/src/test/java/testsupport/EqualityAwareIO.java +++ /dev/null @@ -1,60 +0,0 @@ -package testsupport; - -import com.jnape.palatable.lambda.io.IO; -import com.jnape.palatable.lambda.functor.Applicative; -import com.jnape.palatable.lambda.monad.Monad; - -import java.util.function.Function; - -import static com.jnape.palatable.lambda.io.IO.io; -import static java.util.Objects.hash; - -public final class EqualityAwareIO implements Monad> { - private final IO io; - - public EqualityAwareIO(IO io) { - this.io = io; - } - - @Override - public EqualityAwareIO flatMap(Function>> f) { - return new EqualityAwareIO<>(io.flatMap(f.andThen(x -> x.>coerce().io))); - } - - @Override - public EqualityAwareIO pure(B b) { - return new EqualityAwareIO<>(io(b)); - } - - @Override - public EqualityAwareIO fmap(Function fn) { - return new EqualityAwareIO<>(io.fmap(fn)); - } - - @Override - public EqualityAwareIO zip(Applicative, EqualityAwareIO> appFn) { - return new EqualityAwareIO<>(io.zip(appFn.>>coerce().io)); - } - - @Override - public EqualityAwareIO discardL(Applicative> appB) { - return new EqualityAwareIO<>(io.discardL(appB.>coerce().io)); - } - - @Override - public EqualityAwareIO discardR(Applicative> appB) { - return new EqualityAwareIO<>(io.discardR(appB.>coerce().io)); - } - - @Override - @SuppressWarnings("unchecked") - public boolean equals(Object other) { - return other instanceof EqualityAwareIO - && ((EqualityAwareIO) other).io.unsafePerformIO().equals(io.unsafePerformIO()); - } - - @Override - public int hashCode() { - return hash(io); - } -} diff --git a/src/test/java/testsupport/EqualityAwareIso.java b/src/test/java/testsupport/EqualityAwareIso.java deleted file mode 100644 index 0efc7f039..000000000 --- a/src/test/java/testsupport/EqualityAwareIso.java +++ /dev/null @@ -1,72 +0,0 @@ -package testsupport; - -import com.jnape.palatable.lambda.functor.Applicative; -import com.jnape.palatable.lambda.functor.Functor; -import com.jnape.palatable.lambda.functor.Profunctor; -import com.jnape.palatable.lambda.lens.Iso; -import com.jnape.palatable.lambda.lens.LensLike; -import com.jnape.palatable.lambda.monad.Monad; - -import java.util.Objects; -import java.util.function.Function; - -import static com.jnape.palatable.lambda.functions.builtin.fn2.Both.both; -import static com.jnape.palatable.lambda.lens.functions.View.view; - -public final class EqualityAwareIso implements Iso { - private final S s; - private final B b; - private final Iso iso; - - public EqualityAwareIso(S s, B b, Iso iso) { - this.s = s; - this.b = b; - this.iso = iso; - } - - @Override - public

, FT extends Functor, PAFB extends Profunctor, PSFT extends Profunctor> PSFT apply( - PAFB pafb) { - return iso.apply(pafb); - } - - @Override - public , FB extends Functor> FT apply( - Function fn, S s) { - return iso.apply(fn, s); - } - - @Override - public EqualityAwareIso fmap(Function fn) { - return new EqualityAwareIso<>(s, b, iso.fmap(fn)); - } - - @Override - public EqualityAwareIso pure(U u) { - return new EqualityAwareIso<>(s, b, iso.pure(u)); - } - - @Override - public EqualityAwareIso zip( - Applicative, LensLike> appFn) { - return new EqualityAwareIso<>(s, b, iso.zip(appFn)); - } - - @Override - public EqualityAwareIso flatMap( - Function>> fn) { - return new EqualityAwareIso<>(s, b, iso.flatMap(fn)); - } - - @Override - @SuppressWarnings("unchecked") - public boolean equals(Object other) { - if (other instanceof EqualityAwareIso) { - Iso that = (EqualityAwareIso) other; - Boolean sameForward = both(view(this), view(that)).apply(s).into(Objects::equals); - Boolean sameReverse = both(view(this.mirror()), view(that.mirror())).apply(b).into(Objects::equals); - return sameForward && sameReverse; - } - return false; - } -} diff --git a/src/test/java/testsupport/EqualityAwareLens.java b/src/test/java/testsupport/EqualityAwareLens.java deleted file mode 100644 index e8a8cb52f..000000000 --- a/src/test/java/testsupport/EqualityAwareLens.java +++ /dev/null @@ -1,57 +0,0 @@ -package testsupport; - -import com.jnape.palatable.lambda.functor.Applicative; -import com.jnape.palatable.lambda.functor.Functor; -import com.jnape.palatable.lambda.functor.builtin.Const; -import com.jnape.palatable.lambda.lens.Lens; -import com.jnape.palatable.lambda.lens.LensLike; -import com.jnape.palatable.lambda.monad.Monad; - -import java.util.Objects; -import java.util.function.Function; - -public final class EqualityAwareLens implements Lens { - private final S s; - private final Lens lens; - - public EqualityAwareLens(S s, Lens lens) { - this.s = s; - this.lens = lens; - } - - @Override - public , FB extends Functor> FT apply( - Function fn, S s) { - return lens.apply(fn, s); - } - - @Override - public EqualityAwareLens flatMap( - Function>> f) { - return new EqualityAwareLens<>(s, lens.flatMap(f)); - } - - @Override - public EqualityAwareLens fmap(Function fn) { - return new EqualityAwareLens<>(s, lens.fmap(fn)); - } - - @Override - public EqualityAwareLens pure(U u) { - return new EqualityAwareLens<>(s, lens.pure(u)); - } - - @Override - public EqualityAwareLens zip( - Applicative, LensLike> appFn) { - return new EqualityAwareLens<>(s, lens.zip(appFn)); - } - - @Override - @SuppressWarnings("unchecked") - public boolean equals(Object other) { - return other instanceof Lens - && Objects.equals(((Lens) other)., Const, Const>apply(Const::new, s).runConst(), - this., Const, Const>apply(Const::new, s).runConst()); - } -} diff --git a/src/test/java/testsupport/EquatableM.java b/src/test/java/testsupport/EquatableM.java new file mode 100644 index 000000000..2478e5a97 --- /dev/null +++ b/src/test/java/testsupport/EquatableM.java @@ -0,0 +1,58 @@ +package testsupport; + +import com.jnape.palatable.lambda.functor.Applicative; +import com.jnape.palatable.lambda.monad.Monad; + +import java.util.Objects; +import java.util.function.Function; + +public final class EquatableM, A> implements Monad> { + + private final Monad ma; + private final Function equatable; + + public EquatableM(Monad ma, Function equatable) { + this.ma = ma; + this.equatable = equatable; + } + + @Override + public EquatableM flatMap(Function>> f) { + return new EquatableM<>(ma.flatMap(f.andThen(x -> x.>coerce().ma)), equatable); + } + + @Override + public EquatableM pure(B b) { + return new EquatableM<>(ma.pure(b), equatable); + } + + @Override + public EquatableM fmap(Function fn) { + return new EquatableM<>(ma.fmap(fn), equatable); + } + + @Override + public EquatableM zip(Applicative, EquatableM> appFn) { + return new EquatableM<>(ma.zip(appFn.>>coerce().ma), equatable); + } + + @Override + public EquatableM discardL(Applicative> appB) { + return new EquatableM<>(ma.discardL(appB.>coerce().ma), equatable); + } + + @Override + public EquatableM discardR(Applicative> appB) { + return new EquatableM<>(ma.discardR(appB.>coerce().ma), equatable); + } + + @Override + @SuppressWarnings("unchecked") + public boolean equals(Object other) { + if (other instanceof EquatableM) { + EquatableM that = (EquatableM) other; + return Objects.equals(equatable.apply((M) ma), that.equatable.apply((M) that.ma)); + } + return false; + } +} From f076fc8ab26b30844f568e06255e71fc90d9244a Mon Sep 17 00:00:00 2001 From: jnape Date: Sat, 13 Apr 2019 17:45:31 -0500 Subject: [PATCH 08/69] - Adding Applicative#lazyZip, supporting short-circuiting for some types - FoldRight now operates in terms of Lazy and can be short-circuited --- CHANGELOG.md | 2 + .../jnape/palatable/lambda/adt/Either.java | 42 ++++++++++++++ .../com/jnape/palatable/lambda/adt/Maybe.java | 36 ++++++++++++ .../com/jnape/palatable/lambda/adt/These.java | 8 +++ .../com/jnape/palatable/lambda/adt/Try.java | 38 +++++++++++++ .../palatable/lambda/adt/choice/Choice2.java | 51 ++++++++++++++++- .../palatable/lambda/adt/choice/Choice3.java | 52 ++++++++++++++++- .../palatable/lambda/adt/choice/Choice4.java | 50 ++++++++++++++++- .../palatable/lambda/adt/choice/Choice5.java | 54 +++++++++++++++++- .../palatable/lambda/adt/choice/Choice6.java | 55 +++++++++++++++++- .../palatable/lambda/adt/choice/Choice7.java | 56 ++++++++++++++++++- .../palatable/lambda/adt/choice/Choice8.java | 54 +++++++++++++++++- .../lambda/adt/hlist/SingletonHList.java | 9 ++- .../palatable/lambda/adt/hlist/Tuple2.java | 7 +++ .../palatable/lambda/adt/hlist/Tuple3.java | 7 +++ .../palatable/lambda/adt/hlist/Tuple4.java | 7 +++ .../palatable/lambda/adt/hlist/Tuple5.java | 7 +++ .../palatable/lambda/adt/hlist/Tuple6.java | 7 +++ .../palatable/lambda/adt/hlist/Tuple7.java | 7 +++ .../palatable/lambda/adt/hlist/Tuple8.java | 7 +++ .../jnape/palatable/lambda/functions/Fn1.java | 18 +++++- .../jnape/palatable/lambda/functions/Fn2.java | 15 +++++ .../functions/builtin/fn3/FoldRight.java | 53 +++++++++++++----- .../palatable/lambda/functor/Applicative.java | 18 ++++++ .../lambda/functor/builtin/Compose.java | 24 ++++++++ .../lambda/functor/builtin/Const.java | 43 ++++++++------ .../lambda/functor/builtin/Identity.java | 24 ++++++++ .../com/jnape/palatable/lambda/io/IO.java | 9 +++ .../jnape/palatable/lambda/monad/Monad.java | 9 +++ .../jnape/palatable/lambda/monoid/Monoid.java | 6 +- .../palatable/lambda/semigroup/Semigroup.java | 7 ++- .../lambda/traversable/LambdaIterable.java | 51 ++++++++++++++--- .../palatable/lambda/adt/EitherTest.java | 9 +++ .../jnape/palatable/lambda/adt/MaybeTest.java | 9 +++ .../jnape/palatable/lambda/adt/TheseTest.java | 14 +++++ .../jnape/palatable/lambda/adt/TryTest.java | 10 ++++ .../lambda/adt/choice/Choice2Test.java | 9 +++ .../lambda/adt/choice/Choice3Test.java | 12 ++++ .../lambda/adt/choice/Choice4Test.java | 15 +++++ .../lambda/adt/choice/Choice5Test.java | 18 ++++++ .../lambda/adt/choice/Choice6Test.java | 21 +++++++ .../lambda/adt/choice/Choice7Test.java | 24 ++++++++ .../lambda/adt/choice/Choice8Test.java | 27 +++++++++ .../functions/builtin/fn3/FoldRightTest.java | 24 ++++++-- .../lambda/iteration/ConsingIteratorTest.java | 8 ++- .../lambda/semigroup/SemigroupTest.java | 2 +- .../traversable/LambdaIterableTest.java | 41 +++++++++++++- .../testsupport/traits/ApplicativeLaws.java | 35 +++++++----- 48 files changed, 1028 insertions(+), 83 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e7234879..c028d0d3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,11 +8,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/). - ***Breaking Change***: `IO` is now sealed and moved to its own package. Most previous constructions using the static factory methods should continue to work (by simply targeting `Supplier` now instead of an anonymous `IO`), but some might need to be reworked, and subtyping is obviously no longer supported. +- ***Breaking Change***: `FoldRight` now requires `Lazy` as part of its interface to support short-circuiting operations - `IO` is now stack-safe, regardless of whether the composition nests linearly or recursively ### Added - `Lazy`, a monad supporting stack-safe lazy evaluation - `LazyRec`, a function for writing stack-safe recursive algorithms embedded in `Lazy` +- `Applicative#lazyZip`, for zipping two applicatives in a way that might not require evaluation of one applicative ## [3.3.0] - 2019-02-18 ### Added diff --git a/src/main/java/com/jnape/palatable/lambda/adt/Either.java b/src/main/java/com/jnape/palatable/lambda/adt/Either.java index 00f3bf787..c90ee9dd8 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/Either.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/Either.java @@ -9,6 +9,7 @@ import com.jnape.palatable.lambda.functions.specialized.checked.CheckedSupplier; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; +import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; @@ -20,6 +21,7 @@ import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id; import static com.jnape.palatable.lambda.functions.builtin.fn3.FoldLeft.foldLeft; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; import static java.util.Arrays.asList; /** @@ -187,54 +189,94 @@ public Either peek(Consumer leftConsumer, Consumer rightConsumer) { @Override public abstract V match(Function leftFn, Function rightFn); + /** + * {@inheritDoc} + */ @Override public Choice3 diverge() { return match(Choice3::a, Choice3::b); } + /** + * {@inheritDoc} + */ @Override public final Either fmap(Function fn) { return Monad.super.fmap(fn).coerce(); } + /** + * {@inheritDoc} + */ @Override @SuppressWarnings("unchecked") public final Either biMapL(Function fn) { return (Either) Bifunctor.super.biMapL(fn); } + /** + * {@inheritDoc} + */ @Override @SuppressWarnings("unchecked") public final Either biMapR(Function fn) { return (Either) Bifunctor.super.biMapR(fn); } + /** + * {@inheritDoc} + */ @Override public final Either biMap(Function leftFn, Function rightFn) { return match(l -> left(leftFn.apply(l)), r -> right(rightFn.apply(r))); } + /** + * {@inheritDoc} + */ @Override public final Either pure(R2 r2) { return right(r2); } + /** + * {@inheritDoc} + */ @Override public final Either zip(Applicative, Either> appFn) { return appFn.>>coerce().flatMap(this::biMapR); } + /** + * {@inheritDoc} + */ + @Override + public Lazy> lazyZip( + Lazy, Either>> lazyAppFn) { + return match(l -> lazy(left(l)), + r -> lazyAppFn.fmap(eitherLF -> eitherLF.fmap(f -> f.apply(r)).coerce())); + } + + /** + * {@inheritDoc} + */ @Override public final Either discardL(Applicative> appB) { return Monad.super.discardL(appB).coerce(); } + /** + * {@inheritDoc} + */ @Override public final Either discardR(Applicative> appB) { return Monad.super.discardR(appB).coerce(); } + /** + * {@inheritDoc} + */ @Override @SuppressWarnings("unchecked") public final >, AppB extends Applicative, AppTrav extends Applicative> AppTrav traverse( diff --git a/src/main/java/com/jnape/palatable/lambda/adt/Maybe.java b/src/main/java/com/jnape/palatable/lambda/adt/Maybe.java index ad0b81ad9..7d07ba4c5 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/Maybe.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/Maybe.java @@ -9,6 +9,7 @@ import com.jnape.palatable.lambda.functions.specialized.checked.CheckedSupplier; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Functor; +import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; @@ -22,6 +23,7 @@ import static com.jnape.palatable.lambda.adt.Unit.UNIT; import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; /** * The optional type, representing a potentially absent value. This is lambda's analog of {@link Optional}, supporting @@ -125,36 +127,70 @@ public final Maybe fmap(Function fn) { return Monad.super.fmap(fn).coerce(); } + /** + * {@inheritDoc} + */ @Override public final Maybe zip(Applicative, Maybe> appFn) { return Monad.super.zip(appFn).coerce(); } + /** + * Terminate early if this is a {@link Nothing}; otherwise, continue the {@link Applicative#zip zip}. + * + * @param lazyAppFn the lazy other applicative instance + * @param the result type + * @return the zipped {@link Maybe} + */ + @Override + public Lazy> lazyZip(Lazy, Maybe>> lazyAppFn) { + return match(constantly(lazy(nothing())), + a -> lazyAppFn.fmap(maybeF -> maybeF.fmap(f -> f.apply(a)).coerce())); + } + + /** + * {@inheritDoc} + */ @Override public final Maybe discardL(Applicative appB) { return Monad.super.discardL(appB).coerce(); } + /** + * {@inheritDoc} + */ @Override public final Maybe discardR(Applicative appB) { return Monad.super.discardR(appB).coerce(); } + /** + * {@inheritDoc} + */ @Override public final Maybe flatMap(Function> f) { return match(constantly(nothing()), f.andThen(Applicative::coerce)); } + /** + * {@inheritDoc} + */ @Override public Choice3 diverge() { return match(Choice3::a, Choice3::b); } + /** + * {@inheritDoc} + */ @Override public Tuple2, Maybe> project() { return CoProduct2.super.project().into(HList::tuple); } + /** + * {@inheritDoc} + */ @Override public Choice2 invert() { return match(Choice2::b, Choice2::a); diff --git a/src/main/java/com/jnape/palatable/lambda/adt/These.java b/src/main/java/com/jnape/palatable/lambda/adt/These.java index f4ffc5846..494dbb38e 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/These.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/These.java @@ -5,6 +5,7 @@ import com.jnape.palatable.lambda.adt.hlist.Tuple2; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; +import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; @@ -14,6 +15,7 @@ import static com.jnape.palatable.lambda.adt.hlist.HList.tuple; import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; import static com.jnape.palatable.lambda.functions.builtin.fn2.Into.into; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; /** * The coproduct of a coproduct ({@link CoProduct2}<A, B>) and its product ({@link @@ -96,6 +98,12 @@ public final These zip(Applicative, T return Monad.super.zip(appFn).coerce(); } + @Override + public Lazy> lazyZip(Lazy, These>> lazyAppFn) { + return projectA().>>fmap(a -> lazy(a(a))) + .orElseGet(() -> Monad.super.lazyZip(lazyAppFn).fmap(Applicative::coerce)); + } + /** * {@inheritDoc} */ diff --git a/src/main/java/com/jnape/palatable/lambda/adt/Try.java b/src/main/java/com/jnape/palatable/lambda/adt/Try.java index d629a967b..5c67e7ebd 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/Try.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/Try.java @@ -6,6 +6,7 @@ import com.jnape.palatable.lambda.functions.specialized.checked.CheckedSupplier; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.BoundedBifunctor; +import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; @@ -18,6 +19,7 @@ import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id; import static com.jnape.palatable.lambda.functions.builtin.fn1.Upcast.upcast; import static com.jnape.palatable.lambda.functions.builtin.fn2.Peek2.peek2; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; /** * A {@link Monad} of the evaluation outcome of an expression that might throw. Try/catch/finally semantics map to @@ -139,36 +141,63 @@ public final Either toEither(Function fn) { return match(fn.andThen(Either::left), Either::right); } + /** + * {@inheritDoc} + */ @Override public Try fmap(Function fn) { return Monad.super.fmap(fn).coerce(); } + /** + * {@inheritDoc} + */ @Override public Try flatMap(Function>> f) { return match(Try::failure, a -> f.apply(a).coerce()); } + /** + * {@inheritDoc} + */ @Override public Try pure(B b) { return success(b); } + /** + * {@inheritDoc} + */ @Override public Try zip(Applicative, Try> appFn) { return Monad.super.zip(appFn).coerce(); } + @Override + public Lazy> lazyZip(Lazy, Try>> lazyAppFn) { + return match(f -> lazy(failure(f)), + s -> lazyAppFn.fmap(tryF -> tryF.fmap(f -> f.apply(s)).coerce())); + } + + /** + * {@inheritDoc} + */ @Override public Try discardL(Applicative> appB) { return Monad.super.discardL(appB).coerce(); } + /** + * {@inheritDoc} + */ @Override public Try discardR(Applicative> appB) { return Monad.super.discardR(appB).coerce(); } + /** + * {@inheritDoc} + */ @Override @SuppressWarnings("unchecked") public >, AppB extends Applicative, AppTrav extends Applicative> AppTrav traverse( @@ -177,17 +206,26 @@ public Try discardR(Applicative> appB) { a -> fn.apply(a).fmap(Try::success).fmap(Applicative::coerce).coerce()); } + /** + * {@inheritDoc} + */ @Override public Try biMap(Function lFn, Function rFn) { return match(t -> failure(lFn.apply(t)), a -> success(rFn.apply(a))); } + /** + * {@inheritDoc} + */ @Override public Try biMapL(Function fn) { return (Try) BoundedBifunctor.super.biMapL(fn); } + /** + * {@inheritDoc} + */ @Override public Try biMapR(Function fn) { return (Try) BoundedBifunctor.super.biMapR(fn); diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice2.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice2.java index 969da832d..5efb2c09a 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice2.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice2.java @@ -7,6 +7,7 @@ import com.jnape.palatable.lambda.adt.hlist.Tuple2; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; +import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; @@ -14,6 +15,7 @@ import java.util.function.Function; import static com.jnape.palatable.lambda.functions.builtin.fn2.Into.into; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; /** * Canonical ADT representation of {@link CoProduct2}. Unlike {@link Either}, there is no concept of "success" or @@ -43,65 +45,110 @@ public Tuple2, Maybe> project() { return into(HList::tuple, CoProduct2.super.project()); } + /** + * {@inheritDoc} + */ @Override public final Choice3 diverge() { return match(Choice3::a, Choice3::b); } + /** + * {@inheritDoc} + */ @Override public Choice2 invert() { return match(Choice2::b, Choice2::a); } + /** + * {@inheritDoc} + */ @Override public final Choice2 fmap(Function fn) { return Monad.super.fmap(fn).coerce(); } + /** + * {@inheritDoc} + */ @Override @SuppressWarnings("unchecked") public final Choice2 biMapL(Function fn) { return (Choice2) Bifunctor.super.biMapL(fn); } + /** + * {@inheritDoc} + */ @Override @SuppressWarnings("unchecked") public final Choice2 biMapR(Function fn) { return (Choice2) Bifunctor.super.biMapR(fn); } + /** + * {@inheritDoc} + */ @Override public final Choice2 biMap(Function lFn, Function rFn) { return match(a -> a(lFn.apply(a)), b -> b(rFn.apply(b))); } + /** + * {@inheritDoc} + */ @Override public Choice2 pure(C c) { return b(c); } + /** + * {@inheritDoc} + */ @Override public Choice2 zip(Applicative, Choice2> appFn) { - return appFn.>>coerce() - .match(Choice2::a, this::biMapR); + return Monad.super.zip(appFn).coerce(); } + /** + * {@inheritDoc} + */ + @Override + public Lazy>> lazyZip( + Lazy, Choice2>> lazyAppFn) { + return match(a -> lazy(a(a)), + b -> lazyAppFn.fmap(choiceF -> choiceF.fmap(f -> f.apply(b)).coerce())); + } + + /** + * {@inheritDoc} + */ @Override public Choice2 discardL(Applicative> appB) { return Monad.super.discardL(appB).coerce(); } + /** + * {@inheritDoc} + */ @Override public Choice2 discardR(Applicative> appB) { return Monad.super.discardR(appB).coerce(); } + /** + * {@inheritDoc} + */ @Override public final Choice2 flatMap(Function>> f) { return match(Choice2::a, b -> f.apply(b).coerce()); } + /** + * {@inheritDoc} + */ @Override @SuppressWarnings("unchecked") public >, AppB extends Applicative, AppTrav extends Applicative> AppTrav traverse( diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice3.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice3.java index 1f8aa3226..d8f984cf7 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice3.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice3.java @@ -7,6 +7,7 @@ import com.jnape.palatable.lambda.adt.hlist.Tuple3; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; +import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; @@ -14,6 +15,7 @@ import java.util.function.Function; import static com.jnape.palatable.lambda.functions.builtin.fn2.Into3.into3; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; /** * Canonical ADT representation of {@link CoProduct3}. @@ -43,65 +45,111 @@ public Tuple3, Maybe, Maybe> project() { return into3(HList::tuple, CoProduct3.super.project()); } + /** + * {@inheritDoc} + */ @Override public final Choice4 diverge() { return match(Choice4::a, Choice4::b, Choice4::c); } + /** + * {@inheritDoc} + */ @Override public final Choice2 converge(Function> convergenceFn) { return match(Choice2::a, Choice2::b, convergenceFn.andThen(cp2 -> cp2.match(Choice2::a, Choice2::b))); } + /** + * {@inheritDoc} + */ @Override public final Choice3 fmap(Function fn) { return Monad.super.fmap(fn).coerce(); } + /** + * {@inheritDoc} + */ @Override @SuppressWarnings("unchecked") public final Choice3 biMapL(Function fn) { return (Choice3) Bifunctor.super.biMapL(fn); } + /** + * {@inheritDoc} + */ @Override @SuppressWarnings("unchecked") public final Choice3 biMapR(Function fn) { return (Choice3) Bifunctor.super.biMapR(fn); } + /** + * {@inheritDoc} + */ @Override public final Choice3 biMap(Function lFn, Function rFn) { return match(Choice3::a, b -> b(lFn.apply(b)), c -> c(rFn.apply(c))); } + /** + * {@inheritDoc} + */ @Override public Choice3 pure(D d) { return c(d); } + /** + * {@inheritDoc} + */ @Override public Choice3 zip(Applicative, Choice3> appFn) { - return appFn.>>coerce() - .match(Choice3::a, Choice3::b, this::biMapR); + return Monad.super.zip(appFn).coerce(); } + /** + * {@inheritDoc} + */ + @Override + public Lazy> lazyZip( + Lazy, Choice3>> lazyAppFn) { + return match(a -> lazy(a(a)), + b -> lazy(b(b)), + c -> lazyAppFn.fmap(choiceF -> choiceF.fmap(f -> f.apply(c)).coerce())); + } + + /** + * {@inheritDoc} + */ @Override public Choice3 discardL(Applicative> appB) { return Monad.super.discardL(appB).coerce(); } + /** + * {@inheritDoc} + */ @Override public Choice3 discardR(Applicative> appB) { return Monad.super.discardR(appB).coerce(); } + /** + * {@inheritDoc} + */ @Override public Choice3 flatMap(Function>> f) { return match(Choice3::a, Choice3::b, c -> f.apply(c).coerce()); } + /** + * {@inheritDoc} + */ @Override @SuppressWarnings("unchecked") public >, AppB extends Applicative, AppTrav extends Applicative> AppTrav traverse( diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice4.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice4.java index 494638330..0e9a0aebb 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice4.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice4.java @@ -7,6 +7,7 @@ import com.jnape.palatable.lambda.adt.hlist.Tuple4; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; +import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; @@ -14,6 +15,7 @@ import java.util.function.Function; import static com.jnape.palatable.lambda.functions.builtin.fn2.Into4.into4; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; /** * Canonical ADT representation of {@link CoProduct4}. @@ -44,11 +46,17 @@ public Tuple4, Maybe, Maybe, Maybe> project() { return into4(HList::tuple, CoProduct4.super.project()); } + /** + * {@inheritDoc} + */ @Override public Choice5 diverge() { return match(Choice5::a, Choice5::b, Choice5::c, Choice5::d); } + /** + * {@inheritDoc} + */ @Override public Choice3 converge(Function> convergenceFn) { return match(Choice3::a, @@ -57,17 +65,26 @@ public Choice3 converge(Function cp3.match(Choice3::a, Choice3::b, Choice3::c))); } + /** + * {@inheritDoc} + */ @Override public final Choice4 fmap(Function fn) { return Monad.super.fmap(fn).coerce(); } + /** + * {@inheritDoc} + */ @Override @SuppressWarnings("unchecked") public final Choice4 biMapL(Function fn) { return (Choice4) Bifunctor.super.biMapL(fn); } + /** + * {@inheritDoc} + */ @Override @SuppressWarnings("unchecked") public final Choice4 biMapR(Function fn) { @@ -80,32 +97,61 @@ public final Choice4 biMap(Function l return match(Choice4::a, Choice4::b, c -> c(lFn.apply(c)), d -> d(rFn.apply(d))); } + /** + * {@inheritDoc} + */ @Override public Choice4 pure(E e) { return d(e); } + /** + * {@inheritDoc} + */ @Override public Choice4 zip(Applicative, Choice4> appFn) { - return appFn.>>coerce() - .match(Choice4::a, Choice4::b, Choice4::c, this::biMapR); + return Monad.super.zip(appFn).coerce(); } + /** + * {@inheritDoc} + */ + @Override + public Lazy> lazyZip( + Lazy, Choice4>> lazyAppFn) { + return match(a -> lazy(a(a)), + b -> lazy(b(b)), + c -> lazy(c(c)), + d -> lazyAppFn.fmap(choiceF -> choiceF.fmap(f -> f.apply(d)).coerce())); + } + + /** + * {@inheritDoc} + */ @Override public Choice4 discardL(Applicative> appB) { return Monad.super.discardL(appB).coerce(); } + /** + * {@inheritDoc} + */ @Override public Choice4 discardR(Applicative> appB) { return Monad.super.discardR(appB).coerce(); } + /** + * {@inheritDoc} + */ @Override public Choice4 flatMap(Function>> f) { return match(Choice4::a, Choice4::b, Choice4::c, d -> f.apply(d).coerce()); } + /** + * {@inheritDoc} + */ @Override @SuppressWarnings("unchecked") public >, AppB extends Applicative, AppTrav extends Applicative> AppTrav traverse( diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice5.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice5.java index 5954d4ae2..ab7a8c2fb 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice5.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice5.java @@ -7,6 +7,7 @@ import com.jnape.palatable.lambda.adt.hlist.Tuple5; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; +import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; @@ -14,6 +15,7 @@ import java.util.function.Function; import static com.jnape.palatable.lambda.functions.builtin.fn2.Into5.into5; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; /** * Canonical ADT representation of {@link CoProduct5}. @@ -45,11 +47,17 @@ public Tuple5, Maybe, Maybe, Maybe, Maybe> project() { return into5(HList::tuple, CoProduct5.super.project()); } + /** + * {@inheritDoc} + */ @Override public Choice6 diverge() { return match(Choice6::a, Choice6::b, Choice6::c, Choice6::d, Choice6::e); } + /** + * {@inheritDoc} + */ @Override public Choice4 converge(Function> convergenceFn) { return match(Choice4::a, @@ -59,55 +67,97 @@ public Choice4 converge(Function cp4.match(Choice4::a, Choice4::b, Choice4::c, Choice4::d))); } + /** + * {@inheritDoc} + */ @Override public Choice5 fmap(Function fn) { return Monad.super.fmap(fn).coerce(); } + /** + * {@inheritDoc} + */ @Override @SuppressWarnings("unchecked") public Choice5 biMapL(Function fn) { return (Choice5) Bifunctor.super.biMapL(fn); } + /** + * {@inheritDoc} + */ @Override @SuppressWarnings("unchecked") public Choice5 biMapR(Function fn) { return (Choice5) Bifunctor.super.biMapR(fn); } + /** + * {@inheritDoc} + */ @Override public Choice5 biMap(Function lFn, Function rFn) { return match(Choice5::a, Choice5::b, Choice5::c, d -> d(lFn.apply(d)), e -> e(rFn.apply(e))); } + /** + * {@inheritDoc} + */ @Override public Choice5 pure(F f) { return e(f); } + /** + * {@inheritDoc} + */ @Override public Choice5 zip(Applicative, Choice5> appFn) { - return appFn.>>coerce() - .match(Choice5::a, Choice5::b, Choice5::c, Choice5::d, this::biMapR); + return Monad.super.zip(appFn).coerce(); } + /** + * {@inheritDoc} + */ + @Override + public Lazy> lazyZip( + Lazy, Choice5>> lazyAppFn) { + return match(a -> lazy(a(a)), + b -> lazy(b(b)), + c -> lazy(c(c)), + d -> lazy(d(d)), + e -> lazyAppFn.fmap(choiceF -> choiceF.fmap(f -> f.apply(e)).coerce())); + } + + /** + * {@inheritDoc} + */ @Override public Choice5 discardL(Applicative> appB) { return Monad.super.discardL(appB).coerce(); } + /** + * {@inheritDoc} + */ @Override public Choice5 discardR(Applicative> appB) { return Monad.super.discardR(appB).coerce(); } + /** + * {@inheritDoc} + */ @Override public Choice5 flatMap(Function>> f) { return match(Choice5::a, Choice5::b, Choice5::c, Choice5::d, e -> f.apply(e).coerce()); } + /** + * {@inheritDoc} + */ @Override @SuppressWarnings("unchecked") public >, AppB extends Applicative, AppTrav extends Applicative> AppTrav traverse( diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice6.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice6.java index 8076383b8..59df7eee1 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice6.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice6.java @@ -7,6 +7,7 @@ import com.jnape.palatable.lambda.adt.hlist.Tuple6; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; +import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; @@ -14,6 +15,7 @@ import java.util.function.Function; import static com.jnape.palatable.lambda.functions.builtin.fn2.Into6.into6; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; /** * Canonical ADT representation of {@link CoProduct6}. @@ -46,11 +48,17 @@ public Tuple6, Maybe, Maybe, Maybe, Maybe, Maybe> projec return into6(HList::tuple, CoProduct6.super.project()); } + /** + * {@inheritDoc} + */ @Override public Choice7 diverge() { return match(Choice7::a, Choice7::b, Choice7::c, Choice7::d, Choice7::e, Choice7::f); } + /** + * {@inheritDoc} + */ @Override public Choice5 converge(Function> convergenceFn) { return match(Choice5::a, @@ -61,57 +69,100 @@ public Choice5 converge(Function cp5.match(Choice5::a, Choice5::b, Choice5::c, Choice5::d, Choice5::e))); } + /** + * {@inheritDoc} + */ @Override public Choice6 fmap(Function fn) { return Monad.super.fmap(fn).coerce(); } + /** + * {@inheritDoc} + */ @Override @SuppressWarnings("unchecked") public Choice6 biMapL(Function fn) { return (Choice6) Bifunctor.super.biMapL(fn); } + /** + * {@inheritDoc} + */ @Override @SuppressWarnings("unchecked") public Choice6 biMapR(Function fn) { return (Choice6) Bifunctor.super.biMapR(fn); } + /** + * {@inheritDoc} + */ @Override public Choice6 biMap(Function lFn, Function rFn) { return match(Choice6::a, Choice6::b, Choice6::c, Choice6::d, e -> e(lFn.apply(e)), f -> f(rFn.apply(f))); } + /** + * {@inheritDoc} + */ @Override public Choice6 pure(G g) { return f(g); } + /** + * {@inheritDoc} + */ @Override public Choice6 zip( Applicative, Choice6> appFn) { - return appFn.>>coerce() - .match(Choice6::a, Choice6::b, Choice6::c, Choice6::d, Choice6::e, this::biMapR); + return Monad.super.zip(appFn).coerce(); } + /** + * {@inheritDoc} + */ + @Override + public Lazy> lazyZip( + Lazy, Choice6>> lazyAppFn) { + return match(a -> lazy(a(a)), + b -> lazy(b(b)), + c -> lazy(c(c)), + d -> lazy(d(d)), + e -> lazy(e(e)), + f -> lazyAppFn.fmap(choiceFn -> choiceFn.fmap(fn -> fn.apply(f)).coerce())); + } + + /** + * {@inheritDoc} + */ @Override public Choice6 discardL(Applicative> appB) { return Monad.super.discardL(appB).coerce(); } + /** + * {@inheritDoc} + */ @Override public Choice6 discardR(Applicative> appB) { return Monad.super.discardR(appB).coerce(); } + /** + * {@inheritDoc} + */ @Override public Choice6 flatMap( Function>> fn) { return match(Choice6::a, Choice6::b, Choice6::c, Choice6::d, Choice6::e, f -> fn.apply(f).coerce()); } + /** + * {@inheritDoc} + */ @Override @SuppressWarnings("unchecked") public >, AppB extends Applicative, AppTrav extends Applicative> AppTrav traverse( diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice7.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice7.java index bd7f3b65f..a5f170e4b 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice7.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice7.java @@ -7,6 +7,7 @@ import com.jnape.palatable.lambda.adt.hlist.Tuple7; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; +import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; @@ -14,6 +15,7 @@ import java.util.function.Function; import static com.jnape.palatable.lambda.functions.builtin.fn2.Into7.into7; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; /** * Canonical ADT representation of {@link CoProduct7}. @@ -47,11 +49,17 @@ public Tuple7, Maybe, Maybe, Maybe, Maybe, Maybe, Maybe< return into7(HList::tuple, CoProduct7.super.project()); } + /** + * {@inheritDoc} + */ @Override public Choice8 diverge() { return match(Choice8::a, Choice8::b, Choice8::c, Choice8::d, Choice8::e, Choice8::f, Choice8::g); } + /** + * {@inheritDoc} + */ @Override public Choice6 converge( Function> convergenceFn) { @@ -64,57 +72,101 @@ public Choice6 converge( convergenceFn.andThen(cp6 -> cp6.match(Choice6::a, Choice6::b, Choice6::c, Choice6::d, Choice6::e, Choice6::f))); } + /** + * {@inheritDoc} + */ @Override public Choice7 fmap(Function fn) { return Monad.super.fmap(fn).coerce(); } + /** + * {@inheritDoc} + */ @Override @SuppressWarnings("unchecked") public Choice7 biMapL(Function fn) { return (Choice7) Bifunctor.super.biMapL(fn); } + /** + * {@inheritDoc} + */ @Override @SuppressWarnings("unchecked") public Choice7 biMapR(Function fn) { return (Choice7) Bifunctor.super.biMapR(fn); } + /** + * {@inheritDoc} + */ @Override public Choice7 biMap(Function lFn, Function rFn) { return match(Choice7::a, Choice7::b, Choice7::c, Choice7::d, Choice7::e, f -> f(lFn.apply(f)), g -> g(rFn.apply(g))); } + /** + * {@inheritDoc} + */ @Override public Choice7 pure(H h) { return g(h); } + /** + * {@inheritDoc} + */ @Override public Choice7 zip( Applicative, Choice7> appFn) { - return appFn.>>coerce() - .match(Choice7::a, Choice7::b, Choice7::c, Choice7::d, Choice7::e, Choice7::f, this::biMapR); + return Monad.super.zip(appFn).coerce(); } + /** + * {@inheritDoc} + */ + @Override + public Lazy> lazyZip( + Lazy, Choice7>> lazyAppFn) { + return match(a -> lazy(a(a)), + b -> lazy(b(b)), + c -> lazy(c(c)), + d -> lazy(d(d)), + e -> lazy(e(e)), + f -> lazy(f(f)), + g -> lazyAppFn.fmap(choiceF -> choiceF.fmap(f -> f.apply(g)).coerce())); + } + + /** + * {@inheritDoc} + */ @Override public Choice7 discardL(Applicative> appB) { return Monad.super.discardL(appB).coerce(); } + /** + * {@inheritDoc} + */ @Override public Choice7 discardR(Applicative> appB) { return Monad.super.discardR(appB).coerce(); } + /** + * {@inheritDoc} + */ @Override public Choice7 flatMap( Function>> fn) { return match(Choice7::a, Choice7::b, Choice7::c, Choice7::d, Choice7::e, Choice7::f, g -> fn.apply(g).coerce()); } + /** + * {@inheritDoc} + */ @Override @SuppressWarnings("unchecked") public >, AppB extends Applicative, AppTrav extends Applicative> AppTrav traverse( diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice8.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice8.java index 9755c5050..3cd03e2a9 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice8.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice8.java @@ -7,6 +7,7 @@ import com.jnape.palatable.lambda.adt.hlist.Tuple8; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; +import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; @@ -14,6 +15,7 @@ import java.util.function.Function; import static com.jnape.palatable.lambda.functions.builtin.fn2.Into8.into8; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; /** * Canonical ADT representation of {@link CoProduct8}. @@ -47,6 +49,9 @@ public Tuple8, Maybe, Maybe, Maybe, Maybe, Maybe, Maybe< return into8(HList::tuple, CoProduct8.super.project()); } + /** + * {@inheritDoc} + */ @Override public Choice7 converge( Function> convergenceFn) { @@ -60,57 +65,102 @@ public Choice7 converge( convergenceFn.andThen(cp7 -> cp7.match(Choice7::a, Choice7::b, Choice7::c, Choice7::d, Choice7::e, Choice7::f, Choice7::g))); } + /** + * {@inheritDoc} + */ @Override public Choice8 fmap(Function fn) { return Monad.super.fmap(fn).coerce(); } + /** + * {@inheritDoc} + */ @Override @SuppressWarnings("unchecked") public Choice8 biMapL(Function fn) { return (Choice8) Bifunctor.super.biMapL(fn); } + /** + * {@inheritDoc} + */ @Override @SuppressWarnings("unchecked") public Choice8 biMapR(Function fn) { return (Choice8) Bifunctor.super.biMapR(fn); } + /** + * {@inheritDoc} + */ @Override public Choice8 biMap(Function lFn, Function rFn) { return match(Choice8::a, Choice8::b, Choice8::c, Choice8::d, Choice8::e, Choice8::f, g -> g(lFn.apply(g)), h -> h(rFn.apply(h))); } + /** + * {@inheritDoc} + */ @Override public Choice8 pure(I i) { return h(i); } + /** + * {@inheritDoc} + */ @Override public Choice8 zip( Applicative, Choice8> appFn) { - return appFn.>>coerce() - .match(Choice8::a, Choice8::b, Choice8::c, Choice8::d, Choice8::e, Choice8::f, Choice8::g, this::biMapR); + return Monad.super.zip(appFn).coerce(); } + /** + * {@inheritDoc} + */ + @Override + public Lazy> lazyZip( + Lazy, Choice8>> lazyAppFn) { + return match(a -> lazy(a(a)), + b -> lazy(b(b)), + c -> lazy(c(c)), + d -> lazy(d(d)), + e -> lazy(e(e)), + f -> lazy(f(f)), + g -> lazy(g(g)), + h -> lazyAppFn.fmap(choiceF -> choiceF.fmap(f -> f.apply(h)).coerce())); + } + + /** + * {@inheritDoc} + */ @Override public Choice8 discardL(Applicative> appB) { return Monad.super.discardL(appB).coerce(); } + /** + * {@inheritDoc} + */ @Override public Choice8 discardR(Applicative> appB) { return Monad.super.discardR(appB).coerce(); } + /** + * {@inheritDoc} + */ @Override public Choice8 flatMap( Function>> fn) { return match(Choice8::a, Choice8::b, Choice8::c, Choice8::d, Choice8::e, Choice8::f, Choice8::g, h -> fn.apply(h).coerce()); } + /** + * {@inheritDoc} + */ @Override @SuppressWarnings("unchecked") public >, AppB extends Applicative, AppTrav extends Applicative> AppTrav traverse( diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/SingletonHList.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/SingletonHList.java index 0a8143d84..0c8608e31 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/SingletonHList.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/SingletonHList.java @@ -3,6 +3,7 @@ import com.jnape.palatable.lambda.adt.hlist.HList.HCons; import com.jnape.palatable.lambda.adt.hlist.HList.HNil; import com.jnape.palatable.lambda.functor.Applicative; +import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; @@ -45,6 +46,12 @@ public <_1Prime> SingletonHList<_1Prime> zip( return Monad.super.zip(appFn).coerce(); } + @Override + public <_1Prime> Lazy> lazyZip( + Lazy, SingletonHList>> lazyAppFn) { + return Monad.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); + } + @Override public <_1Prime> SingletonHList<_1Prime> discardL(Applicative<_1Prime, SingletonHList> appB) { return Monad.super.discardL(appB).coerce(); @@ -68,7 +75,7 @@ public } /** - * Apply {@link SingletonHList#head} to fn and return the result. + * Apply {@link SingletonHList#head()} to fn and return the result. * * @param fn the function to apply * @param the return type of the function diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple2.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple2.java index 621537198..7268d0595 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple2.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple2.java @@ -4,6 +4,7 @@ import com.jnape.palatable.lambda.adt.product.Product2; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; +import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; @@ -109,6 +110,12 @@ public <_2Prime> Tuple2<_1, _2Prime> zip( return Monad.super.zip(appFn).coerce(); } + @Override + public <_2Prime> Lazy> lazyZip( + Lazy, Tuple2<_1, ?>>> lazyAppFn) { + return Monad.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); + } + @Override public <_2Prime> Tuple2<_1, _2Prime> discardL(Applicative<_2Prime, Tuple2<_1, ?>> appB) { return Monad.super.discardL(appB).coerce(); diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple3.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple3.java index 32d8a5359..de7116c03 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple3.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple3.java @@ -4,6 +4,7 @@ import com.jnape.palatable.lambda.adt.product.Product3; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; +import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; @@ -111,6 +112,12 @@ public <_3Prime> Tuple3<_1, _2, _3Prime> zip( return biMapR(appFn.>>coerce()._3()); } + @Override + public <_3Prime> Lazy> lazyZip( + Lazy, Tuple3<_1, _2, ?>>> lazyAppFn) { + return Monad.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); + } + @Override public <_3Prime> Tuple3<_1, _2, _3Prime> discardL(Applicative<_3Prime, Tuple3<_1, _2, ?>> appB) { return Monad.super.discardL(appB).coerce(); diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple4.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple4.java index af141c9f3..b240ab948 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple4.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple4.java @@ -4,6 +4,7 @@ import com.jnape.palatable.lambda.adt.product.Product4; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; +import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; @@ -126,6 +127,12 @@ public <_4Prime> Tuple4<_1, _2, _3, _4Prime> zip( return biMapR(appFn.>>coerce()._4()); } + @Override + public <_4Prime> Lazy> lazyZip( + Lazy, Tuple4<_1, _2, _3, ?>>> lazyAppFn) { + return Monad.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); + } + @Override public <_4Prime> Tuple4<_1, _2, _3, _4Prime> discardL(Applicative<_4Prime, Tuple4<_1, _2, _3, ?>> appB) { return Monad.super.discardL(appB).coerce(); diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple5.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple5.java index 65dfb3c7a..5c9764aff 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple5.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple5.java @@ -4,6 +4,7 @@ import com.jnape.palatable.lambda.adt.product.Product5; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; +import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; @@ -146,6 +147,12 @@ public <_5Prime> Tuple5<_1, _2, _3, _4, _5Prime> zip( return Monad.super.zip(appFn).coerce(); } + @Override + public <_5Prime> Lazy> lazyZip( + Lazy, Tuple5<_1, _2, _3, _4, ?>>> lazyAppFn) { + return Monad.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); + } + @Override public <_5Prime> Tuple5<_1, _2, _3, _4, _5Prime> discardL(Applicative<_5Prime, Tuple5<_1, _2, _3, _4, ?>> appB) { return Monad.super.discardL(appB).coerce(); diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple6.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple6.java index 0f3046ace..92b983675 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple6.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple6.java @@ -4,6 +4,7 @@ import com.jnape.palatable.lambda.adt.product.Product6; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; +import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; @@ -166,6 +167,12 @@ public <_6Prime> Tuple6<_1, _2, _3, _4, _5, _6Prime> zip( return Monad.super.zip(appFn).coerce(); } + @Override + public <_6Prime> Lazy> lazyZip( + Lazy, Tuple6<_1, _2, _3, _4, _5, ?>>> lazyAppFn) { + return Monad.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); + } + @Override public <_6Prime> Tuple6<_1, _2, _3, _4, _5, _6Prime> discardL( Applicative<_6Prime, Tuple6<_1, _2, _3, _4, _5, ?>> appB) { diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple7.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple7.java index 1910381d1..f3f010e2e 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple7.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple7.java @@ -4,6 +4,7 @@ import com.jnape.palatable.lambda.adt.product.Product7; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; +import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; @@ -185,6 +186,12 @@ public <_7Prime> Tuple7<_1, _2, _3, _4, _5, _6, _7Prime> zip( return Monad.super.zip(appFn).coerce(); } + @Override + public <_7Prime> Lazy> lazyZip( + Lazy, Tuple7<_1, _2, _3, _4, _5, _6, ?>>> lazyAppFn) { + return Monad.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); + } + @Override public <_7Prime> Tuple7<_1, _2, _3, _4, _5, _6, _7Prime> discardL( Applicative<_7Prime, Tuple7<_1, _2, _3, _4, _5, _6, ?>> appB) { diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple8.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple8.java index 30a9eba61..6d424e3bb 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple8.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple8.java @@ -4,6 +4,7 @@ import com.jnape.palatable.lambda.adt.product.Product8; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; +import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; @@ -204,6 +205,12 @@ public <_8Prime> Tuple8<_1, _2, _3, _4, _5, _6, _7, _8Prime> zip( return Monad.super.zip(appFn).coerce(); } + @Override + public <_8Prime> Lazy> lazyZip( + Lazy, Tuple8<_1, _2, _3, _4, _5, _6, _7, ?>>> lazyAppFn) { + return Monad.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); + } + @Override public <_8Prime> Tuple8<_1, _2, _3, _4, _5, _6, _7, _8Prime> discardL( Applicative<_8Prime, Tuple8<_1, _2, _3, _4, _5, _6, _7, ?>> appB) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java index c9fa0ee26..3ea573870 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java @@ -3,6 +3,7 @@ import com.jnape.palatable.lambda.adt.hlist.Tuple2; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Strong; +import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; import java.util.function.BiFunction; @@ -50,6 +51,9 @@ default Fn2 widen() { return fn2(constantly(this)); } + /** + * {@inheritDoc} + */ @Override default Fn1 flatMap(Function>> f) { return a -> f.apply(apply(a)).>coerce().apply(a); @@ -80,7 +84,7 @@ default Fn1 pure(C c) { */ @Override default Fn1 zip(Applicative, Fn1> appFn) { - return a -> appFn.>>coerce().apply(a).apply(apply(a)); + return Monad.super.zip(appFn).coerce(); } /** @@ -91,6 +95,14 @@ default Fn1 zip(Fn2 appFn) { return zip((Fn1>) (Object) appFn); } + /** + * {@inheritDoc} + */ + @Override + default Lazy> lazyZip(Lazy, Fn1>> lazyAppFn) { + return Monad.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); + } + /** * {@inheritDoc} */ @@ -158,6 +170,10 @@ default Fn1, Tuple2> strengthen() { return t -> t.fmap(this); } + /** + * {@inheritDoc} + */ + @Override default Fn1> carry() { return (Fn1>) Strong.super.carry(); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn2.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn2.java index dd116a80f..1386ae11e 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Fn2.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn2.java @@ -91,26 +91,41 @@ default BiFunction toBiFunction() { return this::apply; } + /** + * {@inheritDoc} + */ @Override default Fn2 discardR(Applicative> appB) { return fn2(Fn1.super.discardR(appB)); } + /** + * {@inheritDoc} + */ @Override default Fn2 diMapL(Function fn) { return fn2(Fn1.super.diMapL(fn)); } + /** + * {@inheritDoc} + */ @Override default Fn2 contraMap(Function fn) { return fn2(Fn1.super.contraMap(fn)); } + /** + * {@inheritDoc} + */ @Override default Fn3 compose(BiFunction before) { return fn3(Fn1.super.compose(before)); } + /** + * {@inheritDoc} + */ @Override default Fn3 compose(Fn2 before) { return fn3(Fn1.super.compose(before)); diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/FoldRight.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/FoldRight.java index bb6f49f2c..a31648e68 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/FoldRight.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/FoldRight.java @@ -3,18 +3,33 @@ import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functions.Fn2; import com.jnape.palatable.lambda.functions.Fn3; +import com.jnape.palatable.lambda.functor.builtin.Lazy; import java.util.function.BiFunction; -import static com.jnape.palatable.lambda.functions.builtin.fn1.Reverse.reverse; -import static com.jnape.palatable.lambda.functions.builtin.fn3.FoldLeft.foldLeft; +import static com.jnape.palatable.lambda.functions.builtin.fn2.LazyRec.lazyRec; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; /** - * Given an Iterable of As, a starting value B, and a {@link - * BiFunction}<A, B, B>, iteratively accumulate over the Iterable, ultimately returning a - * final B value. If the Iterable is empty, just return the starting B value. - * This function is the iterative inverse of {@link FoldLeft}, such that foldRight(f, 0, asList(1, 2, 3, 4, - * 5)) is evaluated as f(f(f(f(f(0, 5), 4), 3), 2), 1). + * Given an Iterable of As, a starting {@link Lazy lazy} value B, and a + * {@link BiFunction}<A, {@link Lazy}<B>, {@link Lazy}<B>>, iteratively accumulate over + * the Iterable, ultimately returning a final {@link Lazy}<B> value. If the + * Iterable is empty, just return the starting {@link Lazy}<B> value. + * This function is computationally the iterative inverse of {@link FoldLeft}, but uses {@link Lazy} to allow support + * stack-safe execution. + *

+ * Example: + *

+ * 
+ * Lazy> lazyCopy = foldRight(
+ *     (head, lazyTail) -> lazy(cons(head, () -> lazyTail.value().iterator())),
+ *     lazy(emptyList()),
+ *     iterate(x -> x + 1, 0));
+ * Iterable copy = () -> lazyCopy.value().iterator();
+ * take(3, copy).forEach(System.out::println); // prints "1, 2, 3"
+ * take(3, copy).forEach(System.out::println); // prints "1, 2, 3"
+ * 
+ * 
*

* For more information, read about Catamorphisms. @@ -23,32 +38,40 @@ * @param The accumulation type * @see FoldLeft */ -public final class FoldRight implements Fn3, B, Iterable, B> { +public final class FoldRight implements + Fn3, ? extends Lazy>, Lazy, Iterable, Lazy> { - private static final FoldRight INSTANCE = new FoldRight(); + private static final FoldRight INSTANCE = new FoldRight<>(); private FoldRight() { } @Override - public B apply(BiFunction fn, B acc, Iterable as) { - return foldLeft((b, a) -> fn.apply(a, b), acc, reverse(as)); + public Lazy apply(BiFunction, ? extends Lazy> fn, Lazy acc, Iterable as) { + return lazyRec((f, lazyIt) -> lazyIt.flatMap(it -> it.hasNext() + ? fn.apply(it.next(), f.apply(lazy(it))) + : acc), + lazy(as::iterator)); } @SuppressWarnings("unchecked") public static FoldRight foldRight() { - return INSTANCE; + return (FoldRight) INSTANCE; } - public static Fn2, B> foldRight(BiFunction fn) { + public static Fn2, Iterable, Lazy> foldRight( + BiFunction, ? extends Lazy> fn) { return FoldRight.foldRight().apply(fn); } - public static Fn1, B> foldRight(BiFunction fn, B acc) { + public static Fn1, Lazy> foldRight( + BiFunction, ? extends Lazy> fn, + Lazy acc) { return FoldRight.foldRight(fn).apply(acc); } - public static B foldRight(BiFunction fn, B acc, Iterable as) { + public static Lazy foldRight(BiFunction, ? extends Lazy> fn, Lazy acc, + Iterable as) { return FoldRight.foldRight(fn, acc).apply(as); } } diff --git a/src/main/java/com/jnape/palatable/lambda/functor/Applicative.java b/src/main/java/com/jnape/palatable/lambda/functor/Applicative.java index c8eb56d7c..180d55c80 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/Applicative.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/Applicative.java @@ -1,5 +1,7 @@ package com.jnape.palatable.lambda.functor; +import com.jnape.palatable.lambda.functor.builtin.Lazy; + import java.util.function.Function; import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; @@ -47,6 +49,22 @@ public interface Applicative extends Functor */ Applicative zip(Applicative, App> appFn); + /** + * Given a {@link Lazy lazy} instance of this applicative over a mapping function, "zip" the two instances together + * using whatever application semantics the current applicative supports. This is useful for applicatives that + * support lazy evaluation and early termination. + * + * @param lazyAppFn the lazy other applicative instance + * @param the resulting applicative parameter type + * @return the mapped applicative + * @see com.jnape.palatable.lambda.adt.Maybe + * @see com.jnape.palatable.lambda.adt.Either + */ + default Lazy> lazyZip( + Lazy, App>> lazyAppFn) { + return lazyAppFn.fmap(this::zip); + } + @Override default Applicative fmap(Function fn) { return zip(pure(fn)); diff --git a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Compose.java b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Compose.java index 40a732247..965567501 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Compose.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Compose.java @@ -25,26 +25,50 @@ public , FGA extends Applicative> FGA getCom return fga.fmap(Applicative::coerce).coerce(); } + /** + * {@inheritDoc} + */ @Override public Compose fmap(Function fn) { return new Compose<>(fga.fmap(g -> g.fmap(fn))); } + /** + * {@inheritDoc} + */ @Override public Compose pure(B b) { return new Compose<>(fga.fmap(g -> g.pure(b))); } + /** + * {@inheritDoc} + */ @Override public Compose zip(Applicative, Compose> appFn) { return new Compose<>(fga.zip(appFn.>>coerce().getCompose().fmap(gFn -> g -> g.zip(gFn)))); } + /** + * {@inheritDoc} + */ + @Override + public Lazy> lazyZip( + Lazy, Compose>> lazyAppFn) { + return Applicative.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); + } + + /** + * {@inheritDoc} + */ @Override public Compose discardL(Applicative> appB) { return Applicative.super.discardL(appB).coerce(); } + /** + * {@inheritDoc} + */ @Override public Compose discardR(Applicative> appB) { return Applicative.super.discardR(appB).coerce(); diff --git a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Const.java b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Const.java index 6de15b769..6ef443106 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Const.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Const.java @@ -53,27 +53,50 @@ public Const pure(C c) { return (Const) this; } + /** + * {@inheritDoc} + */ @Override public Const zip(Applicative, Const> appFn) { return Monad.super.zip(appFn).coerce(); } + /** + * {@inheritDoc} + */ + @Override + public Lazy> lazyZip(Lazy, Const>> lazyAppFn) { + return Monad.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); + } + + /** + * {@inheritDoc} + */ @Override public Const discardL(Applicative> appB) { return Monad.super.discardL(appB).coerce(); } + /** + * {@inheritDoc} + */ @Override public Const discardR(Applicative> appB) { return Monad.super.discardR(appB).coerce(); } + /** + * {@inheritDoc} + */ @Override @SuppressWarnings("unchecked") public Const flatMap(Function>> f) { return (Const) this; } + /** + * {@inheritDoc} + */ @Override public >, AppB extends Applicative, AppTrav extends Applicative> AppTrav traverse( Function fn, Function pure) { @@ -81,11 +104,7 @@ public Const flatMap(Function the new left parameter type (the value) - * @return a Const over Z (the new value) and B (the same phantom parameter) + * {@inheritDoc} */ @Override @SuppressWarnings("unchecked") @@ -94,11 +113,7 @@ public Const biMapL(Function fn) { } /** - * Covariantly map over the right parameter (phantom) type. - * - * @param fn the mapping function - * @param the new right parameter (phantom) type - * @return a Const over A (the same value) and C (the new phantom parameter) + * {@inheritDoc} */ @Override @SuppressWarnings("unchecked") @@ -107,13 +122,7 @@ public Const biMapR(Function fn) { } /** - * Bifunctor's biMap, specialized for Const. - * - * @param lFn the left parameter mapping function - * @param rFn the right parameter mapping function - * @param the new left parameter type - * @param the new right parameter type - * @return a Const over C (the new value) and D (the new phantom parameter) + * {@inheritDoc} */ @Override public Const biMap(Function lFn, diff --git a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Identity.java b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Identity.java index 68e223c40..d9781e8cc 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Identity.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Identity.java @@ -45,26 +45,50 @@ public Identity fmap(Function fn) { return Monad.super.fmap(fn).coerce(); } + /** + * {@inheritDoc} + */ @Override public Identity pure(B b) { return new Identity<>(b); } + /** + * {@inheritDoc} + */ @Override public Identity zip(Applicative, Identity> appFn) { return new Identity<>(appFn.>>coerce().runIdentity().apply(a)); } + /** + * {@inheritDoc} + */ + @Override + public Lazy> lazyZip( + Lazy, Identity>> lazyAppFn) { + return Monad.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); + } + + /** + * {@inheritDoc} + */ @Override public Identity discardL(Applicative appB) { return Monad.super.discardL(appB).coerce(); } + /** + * {@inheritDoc} + */ @Override public Identity discardR(Applicative appB) { return Monad.super.discardR(appB).coerce(); } + /** + * {@inheritDoc} + */ @Override @SuppressWarnings("unchecked") public , AppB extends Applicative, AppTrav extends Applicative> AppTrav traverse( diff --git a/src/main/java/com/jnape/palatable/lambda/io/IO.java b/src/main/java/com/jnape/palatable/lambda/io/IO.java index d659e35a8..7c21845a2 100644 --- a/src/main/java/com/jnape/palatable/lambda/io/IO.java +++ b/src/main/java/com/jnape/palatable/lambda/io/IO.java @@ -5,6 +5,7 @@ import com.jnape.palatable.lambda.adt.choice.Choice2; import com.jnape.palatable.lambda.adt.hlist.Tuple2; import com.jnape.palatable.lambda.functor.Applicative; +import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; import java.util.LinkedList; @@ -119,6 +120,14 @@ public final IO zip(Applicative, IO> return new Compose<>(source, a(zip)); } + /** + * {@inheritDoc} + */ + @Override + public Lazy> lazyZip(Lazy, IO>> lazyAppFn) { + return Monad.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); + } + /** * {@inheritDoc} */ diff --git a/src/main/java/com/jnape/palatable/lambda/monad/Monad.java b/src/main/java/com/jnape/palatable/lambda/monad/Monad.java index 4c3e2e18d..e56d0ca39 100644 --- a/src/main/java/com/jnape/palatable/lambda/monad/Monad.java +++ b/src/main/java/com/jnape/palatable/lambda/monad/Monad.java @@ -2,6 +2,7 @@ import com.jnape.palatable.lambda.functions.builtin.fn1.Id; import com.jnape.palatable.lambda.functor.Applicative; +import com.jnape.palatable.lambda.functor.builtin.Lazy; import java.util.function.Function; @@ -59,6 +60,14 @@ default Monad zip(Applicative, M> app return appFn., M>>coerce().flatMap(this::fmap); } + /** + * {@inheritDoc} + */ + @Override + default Lazy> lazyZip(Lazy, M>> lazyAppFn) { + return Applicative.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); + } + /** * {@inheritDoc} */ diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/Monoid.java b/src/main/java/com/jnape/palatable/lambda/monoid/Monoid.java index 6cdf12b1e..88d13a1d6 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/Monoid.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/Monoid.java @@ -4,6 +4,7 @@ import com.jnape.palatable.lambda.functions.builtin.fn2.ReduceLeft; import com.jnape.palatable.lambda.functions.builtin.fn2.ReduceRight; import com.jnape.palatable.lambda.functions.builtin.fn3.FoldLeft; +import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.semigroup.Semigroup; import java.util.function.Function; @@ -13,6 +14,7 @@ import static com.jnape.palatable.lambda.functions.builtin.fn1.Reverse.reverse; import static com.jnape.palatable.lambda.functions.builtin.fn2.Cons.cons; import static com.jnape.palatable.lambda.functions.builtin.fn2.Map.map; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; /** * A {@link Monoid} is the pairing of a {@link Semigroup} with an identity element. @@ -80,8 +82,8 @@ default A foldLeft(A a, Iterable as) { * {@inheritDoc} */ @Override - default A foldRight(A a, Iterable as) { - return flip().foldMap(id(), reverse(cons(a, as))); + default Lazy foldRight(A a, Iterable as) { + return lazy(() -> flip().foldMap(id(), reverse(cons(a, as)))); } /** diff --git a/src/main/java/com/jnape/palatable/lambda/semigroup/Semigroup.java b/src/main/java/com/jnape/palatable/lambda/semigroup/Semigroup.java index b82aea644..10d15de15 100644 --- a/src/main/java/com/jnape/palatable/lambda/semigroup/Semigroup.java +++ b/src/main/java/com/jnape/palatable/lambda/semigroup/Semigroup.java @@ -3,6 +3,9 @@ import com.jnape.palatable.lambda.functions.Fn2; import com.jnape.palatable.lambda.functions.builtin.fn3.FoldLeft; import com.jnape.palatable.lambda.functions.builtin.fn3.FoldRight; +import com.jnape.palatable.lambda.functor.builtin.Lazy; + +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; /** * A Semigroup is a closed, associative category. As closure can be implied by the type signature, and @@ -35,8 +38,8 @@ default A foldLeft(A a, Iterable as) { * @return the folded result * @see FoldRight */ - default A foldRight(A a, Iterable as) { - return FoldRight.foldRight(toBiFunction(), a, as); + default Lazy foldRight(A a, Iterable as) { + return FoldRight.foldRight((y, lazyX) -> lazyX.fmap(x -> apply(x, y)), lazy(a), as); } /** diff --git a/src/main/java/com/jnape/palatable/lambda/traversable/LambdaIterable.java b/src/main/java/com/jnape/palatable/lambda/traversable/LambdaIterable.java index 8a40c9cb5..0dfb2b7e3 100644 --- a/src/main/java/com/jnape/palatable/lambda/traversable/LambdaIterable.java +++ b/src/main/java/com/jnape/palatable/lambda/traversable/LambdaIterable.java @@ -1,6 +1,9 @@ package com.jnape.palatable.lambda.traversable; +import com.jnape.palatable.lambda.functions.builtin.fn1.Empty; +import com.jnape.palatable.lambda.functions.builtin.fn3.FoldRight; import com.jnape.palatable.lambda.functor.Applicative; +import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; import java.util.Iterator; @@ -10,7 +13,7 @@ import static com.jnape.palatable.lambda.functions.builtin.fn1.Flatten.flatten; import static com.jnape.palatable.lambda.functions.builtin.fn2.Cons.cons; import static com.jnape.palatable.lambda.functions.builtin.fn2.Map.map; -import static com.jnape.palatable.lambda.functions.builtin.fn3.FoldRight.foldRight; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; import static java.util.Collections.emptyList; import static java.util.Collections.singleton; @@ -37,11 +40,17 @@ public Iterable unwrap() { return as; } + /** + * {@inheritDoc} + */ @Override public LambdaIterable fmap(Function fn) { return wrap(map(fn, as)); } + /** + * {@inheritDoc} + */ @Override public LambdaIterable pure(B b) { return wrap(singleton(b)); @@ -62,29 +71,57 @@ public LambdaIterable zip(Applicative, L return Monad.super.zip(appFn).coerce(); } + /** + * {@inheritDoc} + */ + @Override + public Lazy> lazyZip( + Lazy, LambdaIterable>> lazyAppFn) { + return Empty.empty(as) + ? lazy(LambdaIterable.empty()) + : Monad.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); + } + + /** + * {@inheritDoc} + */ @Override public LambdaIterable discardL(Applicative appB) { return Monad.super.discardL(appB).coerce(); } + /** + * {@inheritDoc} + */ @Override public LambdaIterable discardR(Applicative appB) { return Monad.super.discardR(appB).coerce(); } + /** + * {@inheritDoc} + */ @Override public LambdaIterable flatMap(Function> f) { return wrap(flatten(map(a -> f.apply(a).>coerce().unwrap(), as))); } + /** + * {@inheritDoc} + */ @Override @SuppressWarnings("unchecked") - public , AppB extends Applicative, AppTrav extends Applicative> AppTrav traverse( - Function fn, - Function pure) { - return foldRight((a, appTrav) -> (AppTrav) appTrav.zip(fn.apply(a).fmap(b -> bs -> (TravB) wrap(cons(b, ((LambdaIterable) bs).unwrap())))), - (AppTrav) pure.apply((TravB) LambdaIterable.empty()), - as); + public , AppB extends Applicative, + AppTrav extends Applicative> AppTrav traverse(Function fn, + Function pure) { + return FoldRight.foldRight( + (a, lglb) -> fn.apply(a) + .lazyZip(lglb., App>>fmap(appTrav -> appTrav + .fmap(travB -> b -> (TravB) wrap(cons(b, ((LambdaIterable) travB).unwrap()))))) + .fmap(appTrav -> (AppTrav) appTrav), + lazy(pure.apply((TravB) empty())), + as + ).value(); } @Override diff --git a/src/test/java/com/jnape/palatable/lambda/adt/EitherTest.java b/src/test/java/com/jnape/palatable/lambda/adt/EitherTest.java index e43e2438f..833447905 100644 --- a/src/test/java/com/jnape/palatable/lambda/adt/EitherTest.java +++ b/src/test/java/com/jnape/palatable/lambda/adt/EitherTest.java @@ -23,6 +23,7 @@ import static com.jnape.palatable.lambda.adt.Maybe.just; import static com.jnape.palatable.lambda.adt.Maybe.nothing; import static com.jnape.palatable.lambda.adt.Unit.UNIT; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; import static com.jnape.palatable.traitor.framework.Subjects.subjects; import static org.hamcrest.core.Is.is; import static org.junit.Assert.assertEquals; @@ -223,4 +224,12 @@ public void dyadicPeekDuallyLiftsIO() { assertEquals("foo", stringRef.get()); assertEquals(1, intRef.get()); } + + @Test + public void lazyZip() { + assertEquals(right(2), right(1).lazyZip(lazy(right(x -> x + 1))).value()); + assertEquals(left("foo"), left("foo").lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + } } \ No newline at end of file diff --git a/src/test/java/com/jnape/palatable/lambda/adt/MaybeTest.java b/src/test/java/com/jnape/palatable/lambda/adt/MaybeTest.java index 1e747dc34..fc21833dc 100644 --- a/src/test/java/com/jnape/palatable/lambda/adt/MaybeTest.java +++ b/src/test/java/com/jnape/palatable/lambda/adt/MaybeTest.java @@ -22,6 +22,7 @@ import static com.jnape.palatable.lambda.adt.Unit.UNIT; import static com.jnape.palatable.lambda.adt.hlist.HList.tuple; import static com.jnape.palatable.lambda.functions.builtin.fn2.Eq.eq; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; import static com.jnape.palatable.traitor.framework.Subjects.subjects; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertSame; @@ -130,4 +131,12 @@ public void invertsIntoChoice2() { assertEquals(Choice2.b(UNIT), nothing().invert()); assertEquals(Choice2.a(1), just(1).invert()); } + + @Test + public void lazyZip() { + assertEquals(just(2), just(1).lazyZip(lazy(() -> just(x -> x + 1))).value()); + assertEquals(nothing(), nothing().lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + } } \ No newline at end of file diff --git a/src/test/java/com/jnape/palatable/lambda/adt/TheseTest.java b/src/test/java/com/jnape/palatable/lambda/adt/TheseTest.java index ba44c9caf..c4484c1a3 100644 --- a/src/test/java/com/jnape/palatable/lambda/adt/TheseTest.java +++ b/src/test/java/com/jnape/palatable/lambda/adt/TheseTest.java @@ -3,6 +3,7 @@ import com.jnape.palatable.traitor.annotations.TestTraits; import com.jnape.palatable.traitor.framework.Subjects; import com.jnape.palatable.traitor.runners.Traits; +import org.junit.Test; import org.junit.runner.RunWith; import testsupport.traits.ApplicativeLaws; import testsupport.traits.BifunctorLaws; @@ -13,7 +14,9 @@ import static com.jnape.palatable.lambda.adt.These.a; import static com.jnape.palatable.lambda.adt.These.b; import static com.jnape.palatable.lambda.adt.These.both; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; import static com.jnape.palatable.traitor.framework.Subjects.subjects; +import static org.junit.Assert.assertEquals; @RunWith(Traits.class) public class TheseTest { @@ -22,4 +25,15 @@ public class TheseTest { public Subjects> testSubject() { return subjects(a("foo"), b(1), both("foo", 1)); } + + @Test + public void lazyZip() { + assertEquals(b(2), b(1).lazyZip(lazy(b(x -> x + 1))).value()); + assertEquals(b(2), b(1).lazyZip(lazy(both("foo", x -> x + 1))).value()); + assertEquals(both("bar", 2), both("foo", 1).lazyZip(lazy(both("bar", x -> x + 1))).value()); + assertEquals(both("foo", 2), both("foo", 1).lazyZip(lazy(b(x -> x + 1))).value()); + assertEquals(a(1), a(1).lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + } } \ No newline at end of file diff --git a/src/test/java/com/jnape/palatable/lambda/adt/TryTest.java b/src/test/java/com/jnape/palatable/lambda/adt/TryTest.java index f0c7cb043..57b1696f8 100644 --- a/src/test/java/com/jnape/palatable/lambda/adt/TryTest.java +++ b/src/test/java/com/jnape/palatable/lambda/adt/TryTest.java @@ -27,6 +27,7 @@ import static com.jnape.palatable.lambda.adt.Try.trying; import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; import static com.jnape.palatable.traitor.framework.Subjects.subjects; import static java.util.Arrays.asList; import static org.hamcrest.CoreMatchers.equalTo; @@ -209,4 +210,13 @@ public void cascadingWithResourcesClosesInInverseOrder() { c -> success(1))); assertEquals(asList("close c", "close b", "close a"), closeMessages); } + + @Test + public void lazyZip() { + assertEquals(success(2), success(1).lazyZip(lazy(success(x -> x + 1))).value()); + IllegalStateException e = new IllegalStateException(); + assertEquals(failure(e), failure(e).lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + } } \ No newline at end of file diff --git a/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice2Test.java b/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice2Test.java index 49b489192..ea4c27160 100644 --- a/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice2Test.java +++ b/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice2Test.java @@ -14,6 +14,7 @@ import static com.jnape.palatable.lambda.adt.choice.Choice2.a; import static com.jnape.palatable.lambda.adt.choice.Choice2.b; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; import static com.jnape.palatable.traitor.framework.Subjects.subjects; import static org.junit.Assert.assertEquals; @@ -39,4 +40,12 @@ public void divergeStaysInChoice() { assertEquals(Choice3.a(1), a.diverge()); assertEquals(Choice3.b(true), b.diverge()); } + + @Test + public void lazyZip() { + assertEquals(b(2), b(1).lazyZip(lazy(b(x -> x + 1))).value()); + assertEquals(a("foo"), a("foo").lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + } } \ No newline at end of file diff --git a/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice3Test.java b/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice3Test.java index 1d04ec9a5..2deefbb91 100644 --- a/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice3Test.java +++ b/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice3Test.java @@ -15,6 +15,7 @@ import static com.jnape.palatable.lambda.adt.choice.Choice3.a; import static com.jnape.palatable.lambda.adt.choice.Choice3.b; import static com.jnape.palatable.lambda.adt.choice.Choice3.c; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; import static com.jnape.palatable.traitor.framework.Subjects.subjects; import static org.junit.Assert.assertEquals; @@ -50,4 +51,15 @@ public void divergeStaysInChoice() { assertEquals(Choice4.b("two"), b.diverge()); assertEquals(Choice4.c(true), c.diverge()); } + + @Test + public void lazyZip() { + assertEquals(Choice3.c(2), c(1).lazyZip(lazy(c(x -> x + 1))).value()); + assertEquals(Choice3.b(1), b(1).lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + assertEquals(Choice3.a(1), a(1).lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + } } \ No newline at end of file diff --git a/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice4Test.java b/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice4Test.java index 0b70141e7..1e20850d6 100644 --- a/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice4Test.java +++ b/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice4Test.java @@ -16,6 +16,7 @@ import static com.jnape.palatable.lambda.adt.choice.Choice4.b; import static com.jnape.palatable.lambda.adt.choice.Choice4.c; import static com.jnape.palatable.lambda.adt.choice.Choice4.d; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; import static com.jnape.palatable.traitor.framework.Subjects.subjects; import static org.junit.Assert.assertEquals; @@ -55,4 +56,18 @@ public void divergeStaysInChoice() { assertEquals(Choice5.c(true), c.diverge()); assertEquals(Choice5.d(4D), d.diverge()); } + + @Test + public void lazyZip() { + assertEquals(d(2), d(1).lazyZip(lazy(d(x -> x + 1))).value()); + assertEquals(a(1), a(1).lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + assertEquals(b(1), b(1).lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + assertEquals(c(1), c(1).lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + } } \ No newline at end of file diff --git a/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice5Test.java b/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice5Test.java index d0ea885e5..bfccafcb9 100644 --- a/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice5Test.java +++ b/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice5Test.java @@ -17,6 +17,7 @@ import static com.jnape.palatable.lambda.adt.choice.Choice5.c; import static com.jnape.palatable.lambda.adt.choice.Choice5.d; import static com.jnape.palatable.lambda.adt.choice.Choice5.e; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; import static com.jnape.palatable.traitor.framework.Subjects.subjects; import static org.junit.Assert.assertEquals; @@ -60,4 +61,21 @@ public void divergeStaysInChoice() { assertEquals(Choice6.d(4D), d.diverge()); assertEquals(Choice6.e('z'), e.diverge()); } + + @Test + public void lazyZip() { + assertEquals(e(2), e(1).lazyZip(lazy(e(x -> x + 1))).value()); + assertEquals(a(1), a(1).lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + assertEquals(b(1), b(1).lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + assertEquals(c(1), c(1).lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + assertEquals(d(1), d(1).lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + } } \ No newline at end of file diff --git a/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice6Test.java b/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice6Test.java index 2262884b5..0606c892d 100644 --- a/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice6Test.java +++ b/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice6Test.java @@ -21,6 +21,7 @@ import static com.jnape.palatable.lambda.adt.choice.Choice6.d; import static com.jnape.palatable.lambda.adt.choice.Choice6.e; import static com.jnape.palatable.lambda.adt.choice.Choice6.f; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; import static com.jnape.palatable.traitor.framework.Subjects.subjects; import static org.junit.Assert.assertEquals; @@ -70,4 +71,24 @@ public void divergeStaysInChoice() { assertEquals(Choice7.e('z'), e.diverge()); assertEquals(Choice7.f(5L), f.diverge()); } + + @Test + public void lazyZip() { + assertEquals(f(2), f(1).lazyZip(lazy(f(x -> x + 1))).value()); + assertEquals(a(1), a(1).lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + assertEquals(b(1), b(1).lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + assertEquals(c(1), c(1).lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + assertEquals(d(1), d(1).lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + assertEquals(e(1), e(1).lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + } } \ No newline at end of file diff --git a/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice7Test.java b/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice7Test.java index 27bf111d0..5bec8a5b4 100644 --- a/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice7Test.java +++ b/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice7Test.java @@ -22,6 +22,7 @@ import static com.jnape.palatable.lambda.adt.choice.Choice7.e; import static com.jnape.palatable.lambda.adt.choice.Choice7.f; import static com.jnape.palatable.lambda.adt.choice.Choice7.g; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; import static com.jnape.palatable.traitor.framework.Subjects.subjects; import static org.junit.Assert.assertEquals; @@ -75,4 +76,27 @@ public void divergeStaysInChoice() { assertEquals(Choice8.f(5L), f.diverge()); assertEquals(Choice8.g(6F), g.diverge()); } + + @Test + public void lazyZip() { + assertEquals(g(2), g(1).lazyZip(lazy(g(x -> x + 1))).value()); + assertEquals(a(1), a(1).lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + assertEquals(b(1), b(1).lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + assertEquals(c(1), c(1).lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + assertEquals(d(1), d(1).lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + assertEquals(e(1), e(1).lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + assertEquals(f(1), f(1).lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + } } \ No newline at end of file diff --git a/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice8Test.java b/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice8Test.java index 24fede69b..d71e3228d 100644 --- a/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice8Test.java +++ b/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice8Test.java @@ -23,6 +23,7 @@ import static com.jnape.palatable.lambda.adt.choice.Choice8.f; import static com.jnape.palatable.lambda.adt.choice.Choice8.g; import static com.jnape.palatable.lambda.adt.choice.Choice8.h; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; import static com.jnape.palatable.traitor.framework.Subjects.subjects; import static org.junit.Assert.assertEquals; @@ -68,4 +69,30 @@ public void convergeStaysInChoice() { assertEquals(Choice7.g(6F), g.converge(convergenceFn)); assertEquals(Choice7.b("7"), h.converge(convergenceFn)); } + + @Test + public void lazyZip() { + assertEquals(h(2), h(1).lazyZip(lazy(h(x -> x + 1))).value()); + assertEquals(a(1), a(1).lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + assertEquals(b(1), b(1).lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + assertEquals(c(1), c(1).lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + assertEquals(d(1), d(1).lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + assertEquals(e(1), e(1).lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + assertEquals(f(1), f(1).lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + assertEquals(g(1), g(1).lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + } } \ No newline at end of file diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn3/FoldRightTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn3/FoldRightTest.java index b40915da7..912ee9b4a 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn3/FoldRightTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn3/FoldRightTest.java @@ -1,17 +1,22 @@ package com.jnape.palatable.lambda.functions.builtin.fn3; import com.jnape.palatable.lambda.functions.Fn1; +import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.traitor.annotations.TestTraits; import com.jnape.palatable.traitor.runners.Traits; import org.junit.Test; import org.junit.runner.RunWith; import testsupport.traits.EmptyIterableSupport; +import static com.jnape.palatable.lambda.functions.builtin.fn2.Iterate.iterate; import static com.jnape.palatable.lambda.functions.builtin.fn3.FoldRight.foldRight; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; import static java.util.Arrays.asList; import static java.util.Collections.singletonList; import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; +import static testsupport.Constants.STACK_EXPLODING_NUMBER; import static testsupport.functions.ExplainFold.explainFold; @RunWith(Traits.class) @@ -19,14 +24,25 @@ public class FoldRightTest { @TestTraits({EmptyIterableSupport.class}) public Fn1, Iterable> createTestSubject() { - return foldRight((o, objects) -> objects, singletonList(new Object())); + return foldRight((o, objects) -> objects, lazy(singletonList(new Object()))).fmap(Lazy::value); } @Test public void foldRightAccumulatesRightToLeft() { - assertThat( - foldRight(explainFold(), "5", asList("1", "2", "3", "4")), - is("(1 + (2 + (3 + (4 + 5))))") + assertThat(foldRight((a, lazyB) -> lazyB.fmap(b -> explainFold().apply(a, b)), + lazy("5"), + asList("1", "2", "3", "4")) + .value(), + is("(1 + (2 + (3 + (4 + 5))))") ); } + + @Test + public void stackSafe() { + Lazy lazy = foldRight((x, lazyY) -> x < STACK_EXPLODING_NUMBER ? lazyY.fmap(y -> y) : lazy(x), + lazy(0), + iterate(x -> x + 1, 0)); + + assertEquals(STACK_EXPLODING_NUMBER, lazy.value()); + } } diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/ConsingIteratorTest.java b/src/test/java/com/jnape/palatable/lambda/iteration/ConsingIteratorTest.java index 68f99d943..301108b0f 100644 --- a/src/test/java/com/jnape/palatable/lambda/iteration/ConsingIteratorTest.java +++ b/src/test/java/com/jnape/palatable/lambda/iteration/ConsingIteratorTest.java @@ -9,6 +9,7 @@ import static com.jnape.palatable.lambda.functions.builtin.fn2.Iterate.iterate; import static com.jnape.palatable.lambda.functions.builtin.fn2.Take.take; import static com.jnape.palatable.lambda.functions.builtin.fn3.FoldRight.foldRight; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; import static java.util.Arrays.asList; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -51,9 +52,10 @@ public void doesNotHaveNextIfNoElementsLeft() { @Test public void stackSafety() { Integer stackBlowingNumber = 10_000; - Iterable ints = foldRight((x, acc) -> () -> new ConsingIterator<>(x, acc), - (Iterable) Collections.emptyList(), - take(stackBlowingNumber, iterate(x -> x + 1, 1))); + Iterable ints = foldRight((x, lazyAcc) -> lazyAcc.fmap(acc -> () -> new ConsingIterator<>(x, acc)), + lazy((Iterable) Collections.emptyList()), + take(stackBlowingNumber, iterate(x -> x + 1, 1))) + .value(); assertEquals(stackBlowingNumber, take(1, drop(stackBlowingNumber - 1, ints)).iterator().next()); diff --git a/src/test/java/com/jnape/palatable/lambda/semigroup/SemigroupTest.java b/src/test/java/com/jnape/palatable/lambda/semigroup/SemigroupTest.java index ec20057bc..3291b6b1b 100644 --- a/src/test/java/com/jnape/palatable/lambda/semigroup/SemigroupTest.java +++ b/src/test/java/com/jnape/palatable/lambda/semigroup/SemigroupTest.java @@ -16,6 +16,6 @@ public void foldLeft() { @Test public void foldRight() { Semigroup sum = (x, y) -> x + y; - assertEquals((Integer) 6, sum.foldRight(0, asList(1, 2, 3))); + assertEquals((Integer) 6, sum.foldRight(0, asList(1, 2, 3)).value()); } } \ No newline at end of file diff --git a/src/test/java/com/jnape/palatable/lambda/traversable/LambdaIterableTest.java b/src/test/java/com/jnape/palatable/lambda/traversable/LambdaIterableTest.java index 9947e7f3a..e76f48e5e 100644 --- a/src/test/java/com/jnape/palatable/lambda/traversable/LambdaIterableTest.java +++ b/src/test/java/com/jnape/palatable/lambda/traversable/LambdaIterableTest.java @@ -1,5 +1,6 @@ package com.jnape.palatable.lambda.traversable; +import com.jnape.palatable.lambda.adt.Maybe; import com.jnape.palatable.traitor.annotations.TestTraits; import com.jnape.palatable.traitor.framework.Subjects; import com.jnape.palatable.traitor.runners.Traits; @@ -12,11 +13,22 @@ import java.util.function.Function; +import static com.jnape.palatable.lambda.adt.Maybe.just; +import static com.jnape.palatable.lambda.adt.Maybe.nothing; +import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id; +import static com.jnape.palatable.lambda.functions.builtin.fn1.Repeat.repeat; +import static com.jnape.palatable.lambda.functions.builtin.fn1.Size.size; +import static com.jnape.palatable.lambda.functions.builtin.fn2.Cons.cons; import static com.jnape.palatable.lambda.functions.builtin.fn2.Replicate.replicate; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; +import static com.jnape.palatable.lambda.traversable.LambdaIterable.empty; +import static com.jnape.palatable.lambda.traversable.LambdaIterable.wrap; import static com.jnape.palatable.traitor.framework.Subjects.subjects; import static java.util.Arrays.asList; import static java.util.Collections.singleton; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; +import static testsupport.Constants.STACK_EXPLODING_NUMBER; import static testsupport.matchers.IterableMatcher.iterates; @RunWith(Traits.class) @@ -24,13 +36,36 @@ public class LambdaIterableTest { @TestTraits({FunctorLaws.class, ApplicativeLaws.class, TraversableLaws.class, MonadLaws.class}) public Subjects> testSubject() { - return subjects(LambdaIterable.empty(), LambdaIterable.wrap(singleton(1)), LambdaIterable.wrap(replicate(100, 1))); + return subjects(LambdaIterable.empty(), wrap(singleton(1)), wrap(replicate(100, 1))); } @Test public void zipAppliesCartesianProductOfFunctionsAndValues() { - LambdaIterable> fns = LambdaIterable.wrap(asList(x -> x + 1, x -> x - 1)); - LambdaIterable xs = LambdaIterable.wrap(asList(1, 2, 3)); + LambdaIterable> fns = wrap(asList(x -> x + 1, x -> x - 1)); + LambdaIterable xs = wrap(asList(1, 2, 3)); assertThat(xs.zip(fns).unwrap(), iterates(2, 3, 4, 0, 1, 2)); } + + @Test + public void earlyTraverseTermination() { + assertEquals(nothing(), wrap(repeat(1)).traverse(x -> nothing(), Maybe::just)); + assertEquals(nothing(), LambdaIterable.>wrap(cons(just(1), repeat(nothing()))) + .traverse(id(), Maybe::just)); + } + + @Test + public void traverseStackSafety() { + Maybe> traversed = wrap(replicate(STACK_EXPLODING_NUMBER, just(1))) + .traverse(id(), Maybe::just); + assertEquals(just(STACK_EXPLODING_NUMBER.longValue()), + traversed.fmap(LambdaIterable::unwrap).fmap(size())); + } + + @Test + public void lazyZip() { + assertEquals(wrap(singleton(2)), wrap(singleton(1)).lazyZip(lazy(wrap(singleton(x -> x + 1)))).value()); + assertEquals(empty(), empty().lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + } } \ No newline at end of file diff --git a/src/test/java/testsupport/traits/ApplicativeLaws.java b/src/test/java/testsupport/traits/ApplicativeLaws.java index 6255798ce..42fd8bbde 100644 --- a/src/test/java/testsupport/traits/ApplicativeLaws.java +++ b/src/test/java/testsupport/traits/ApplicativeLaws.java @@ -11,6 +11,8 @@ import static com.jnape.palatable.lambda.adt.Maybe.just; import static com.jnape.palatable.lambda.adt.Maybe.nothing; import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; +import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; import static java.util.Arrays.asList; import static java.util.function.Function.identity; @@ -26,7 +28,8 @@ public void test(Applicative applicative) { this::testHomomorphism, this::testInterchange, this::testDiscardL, - this::testDiscardR) + this::testDiscardR, + this::testLazyZip) ) .peek(s -> { throw new AssertionError("The following Applicative laws did not hold for instance of " + applicative.getClass() + ": \n\t - " + s); @@ -37,8 +40,8 @@ private Maybe testIdentity(Applicative applicative) { Applicative v = applicative.pure(1); Applicative, App> pureId = v.pure(identity()); return v.zip(pureId).equals(v) - ? nothing() - : just("identity (v.zip(pureId).equals(v))"); + ? nothing() + : just("identity (v.zip(pureId).equals(v))"); } private Maybe testComposition(Applicative applicative) { @@ -53,8 +56,8 @@ private Maybe testComposition(Applicative applicative) { Applicative, ? extends Function, ? extends Function>>, App> pureCompose = u.pure(compose); return w.zip(v.zip(u.zip(pureCompose))).equals(w.zip(v).zip(u)) - ? nothing() - : just("composition (w.zip(v.zip(u.zip(pureCompose))).equals((w.zip(v)).zip(u)))"); + ? nothing() + : just("composition (w.zip(v.zip(u.zip(pureCompose))).equals((w.zip(v)).zip(u)))"); } private Maybe testHomomorphism(Applicative applicative) { @@ -65,8 +68,8 @@ private Maybe testHomomorphism(Applicative applicative) { Applicative, App> pureF = applicative.pure(f); Applicative pureFx = applicative.pure(f.apply(x)); return pureX.zip(pureF).equals(pureFx) - ? nothing() - : just("homomorphism (pureX.zip(pureF).equals(pureFx))"); + ? nothing() + : just("homomorphism (pureX.zip(pureF).equals(pureFx))"); } private Maybe testInterchange(Applicative applicative) { @@ -75,8 +78,8 @@ private Maybe testInterchange(Applicative applicative) { Applicative pureY = applicative.pure(y); return pureY.zip(u).equals(u.zip(applicative.pure(f -> f.apply(y)))) - ? nothing() - : just("interchange (pureY.zip(u).equals(u.zip(applicative.pure(f -> f.apply(y)))))"); + ? nothing() + : just("interchange (pureY.zip(u).equals(u.zip(applicative.pure(f -> f.apply(y)))))"); } private Maybe testDiscardL(Applicative applicative) { @@ -84,8 +87,8 @@ private Maybe testDiscardL(Applicative applicative) { Applicative v = applicative.pure("v"); return u.discardL(v).equals(v.zip(u.zip(applicative.pure(constantly(identity()))))) - ? nothing() - : just("discardL u.discardL(v).equals(v.zip(u.zip(applicative.pure(constantly(identity())))))"); + ? nothing() + : just("discardL u.discardL(v).equals(v.zip(u.zip(applicative.pure(constantly(identity())))))"); } private Maybe testDiscardR(Applicative applicative) { @@ -93,7 +96,13 @@ private Maybe testDiscardR(Applicative applicative) { Applicative v = applicative.pure("v"); return u.discardR(v).equals(v.zip(u.zip(applicative.pure(constantly())))) - ? nothing() - : just("discardR u.discardR(v).equals(v.zip(u.zip(applicative.pure(constantly()))))"); + ? nothing() + : just("discardR u.discardR(v).equals(v.zip(u.zip(applicative.pure(constantly()))))"); + } + + private Maybe testLazyZip(Applicative applicative) { + return applicative.lazyZip(lazy(applicative.pure(id()))).value().equals(applicative.zip(applicative.pure(id()))) + ? nothing() + : just("lazyZip app.zip(lazy(app.pure(id()))).equals(app.zip(app.pure(id())))"); } } From 329e78458dcb3746f3ef02d4b12bdf10d2cfe86c Mon Sep 17 00:00:00 2001 From: jnape Date: Sat, 13 Apr 2019 18:15:04 -0500 Subject: [PATCH 09/69] Eliminating all raw types --- CHANGELOG.md | 2 ++ .../jnape/palatable/lambda/adt/Either.java | 17 +++++++--- .../com/jnape/palatable/lambda/adt/Maybe.java | 29 +++++++++------- .../com/jnape/palatable/lambda/adt/These.java | 6 ++-- .../com/jnape/palatable/lambda/adt/Try.java | 6 ++-- .../palatable/lambda/adt/choice/Choice2.java | 8 +++-- .../palatable/lambda/adt/choice/Choice3.java | 6 ++-- .../palatable/lambda/adt/choice/Choice4.java | 6 ++-- .../palatable/lambda/adt/choice/Choice5.java | 6 ++-- .../palatable/lambda/adt/choice/Choice6.java | 6 ++-- .../palatable/lambda/adt/choice/Choice7.java | 6 ++-- .../palatable/lambda/adt/choice/Choice8.java | 6 ++-- .../palatable/lambda/adt/hlist/HList.java | 4 +-- .../palatable/lambda/adt/hlist/Index.java | 2 +- .../lambda/adt/hlist/SingletonHList.java | 21 +++++++----- .../palatable/lambda/adt/hlist/Tuple2.java | 10 +++--- .../palatable/lambda/adt/hlist/Tuple3.java | 6 ++-- .../palatable/lambda/adt/hlist/Tuple4.java | 6 ++-- .../palatable/lambda/adt/hlist/Tuple5.java | 6 ++-- .../palatable/lambda/adt/hlist/Tuple6.java | 6 ++-- .../palatable/lambda/adt/hlist/Tuple7.java | 7 ++-- .../palatable/lambda/adt/hlist/Tuple8.java | 7 ++-- .../lambda/adt/hmap/TypeSafeKey.java | 19 ++++++----- .../jnape/palatable/lambda/functions/Fn1.java | 6 ++-- .../functions/builtin/fn1/CatMaybes.java | 4 +-- .../functions/builtin/fn1/Coalesce.java | 4 +-- .../functions/builtin/fn1/Constantly.java | 4 +-- .../lambda/functions/builtin/fn1/Cycle.java | 4 +-- .../functions/builtin/fn1/Distinct.java | 4 +-- .../lambda/functions/builtin/fn1/Empty.java | 4 +-- .../lambda/functions/builtin/fn1/Flatten.java | 4 +-- .../lambda/functions/builtin/fn1/Force.java | 4 +-- .../lambda/functions/builtin/fn1/Head.java | 4 +-- .../lambda/functions/builtin/fn1/Id.java | 4 +-- .../lambda/functions/builtin/fn1/Init.java | 4 +-- .../lambda/functions/builtin/fn1/Inits.java | 4 +-- .../lambda/functions/builtin/fn1/Last.java | 4 +-- .../functions/builtin/fn1/Magnetize.java | 4 +-- .../lambda/functions/builtin/fn1/Not.java | 4 +-- .../functions/builtin/fn1/Occurrences.java | 4 +-- .../lambda/functions/builtin/fn1/Repeat.java | 4 +-- .../lambda/functions/builtin/fn1/Reverse.java | 4 +-- .../lambda/functions/builtin/fn1/Sort.java | 4 +-- .../lambda/functions/builtin/fn1/Tail.java | 4 +-- .../lambda/functions/builtin/fn1/Tails.java | 4 +-- .../lambda/functions/builtin/fn1/Uncons.java | 4 +-- .../lambda/functions/builtin/fn2/All.java | 4 +-- .../lambda/functions/builtin/fn2/Alter.java | 4 +-- .../lambda/functions/builtin/fn2/Any.java | 4 +-- .../lambda/functions/builtin/fn2/Both.java | 4 +-- .../builtin/fn2/CartesianProduct.java | 4 +-- .../lambda/functions/builtin/fn2/CmpEq.java | 4 +-- .../lambda/functions/builtin/fn2/Cons.java | 2 +- .../functions/builtin/fn2/Difference.java | 4 +-- .../lambda/functions/builtin/fn2/Drop.java | 4 +-- .../functions/builtin/fn2/DropWhile.java | 4 +-- .../lambda/functions/builtin/fn2/Eq.java | 4 +-- .../lambda/functions/builtin/fn2/Filter.java | 4 +-- .../lambda/functions/builtin/fn2/Find.java | 4 +-- .../lambda/functions/builtin/fn2/GT.java | 4 +-- .../lambda/functions/builtin/fn2/GTE.java | 4 +-- .../lambda/functions/builtin/fn2/GroupBy.java | 4 +-- .../functions/builtin/fn2/InGroupsOf.java | 4 +-- .../functions/builtin/fn2/Intersection.java | 4 +-- .../functions/builtin/fn2/Intersperse.java | 4 +-- .../lambda/functions/builtin/fn2/Into.java | 4 +-- .../lambda/functions/builtin/fn2/Into1.java | 4 +-- .../lambda/functions/builtin/fn2/Into3.java | 4 +-- .../lambda/functions/builtin/fn2/Into4.java | 4 +-- .../lambda/functions/builtin/fn2/Into5.java | 4 +-- .../lambda/functions/builtin/fn2/Into6.java | 4 +-- .../lambda/functions/builtin/fn2/Into7.java | 4 +-- .../lambda/functions/builtin/fn2/Into8.java | 4 +-- .../lambda/functions/builtin/fn2/Iterate.java | 4 +-- .../lambda/functions/builtin/fn2/LT.java | 4 +-- .../lambda/functions/builtin/fn2/LTE.java | 4 +-- .../functions/builtin/fn2/MagnetizeBy.java | 4 +-- .../lambda/functions/builtin/fn2/Map.java | 4 +-- .../functions/builtin/fn2/Partial2.java | 4 +-- .../functions/builtin/fn2/Partial3.java | 4 +-- .../functions/builtin/fn2/Partition.java | 4 +-- .../lambda/functions/builtin/fn2/Peek.java | 4 +-- .../lambda/functions/builtin/fn2/Peek2.java | 4 +-- .../functions/builtin/fn2/PrependAll.java | 4 +-- .../functions/builtin/fn2/ReduceLeft.java | 4 +-- .../functions/builtin/fn2/ReduceRight.java | 4 +-- .../functions/builtin/fn2/Replicate.java | 4 +-- .../functions/builtin/fn2/Sequence.java | 22 ++++++------- .../lambda/functions/builtin/fn2/Slide.java | 4 +-- .../lambda/functions/builtin/fn2/Snoc.java | 4 +-- .../lambda/functions/builtin/fn2/SortBy.java | 4 +-- .../functions/builtin/fn2/SortWith.java | 4 +-- .../lambda/functions/builtin/fn2/Span.java | 4 +-- .../lambda/functions/builtin/fn2/Take.java | 4 +-- .../functions/builtin/fn2/TakeWhile.java | 4 +-- .../lambda/functions/builtin/fn2/ToArray.java | 4 +-- .../functions/builtin/fn2/ToCollection.java | 4 +-- .../lambda/functions/builtin/fn2/ToMap.java | 4 +-- .../lambda/functions/builtin/fn2/Tupler2.java | 4 +-- .../lambda/functions/builtin/fn2/Unfoldr.java | 4 +-- .../lambda/functions/builtin/fn2/Zip.java | 4 +-- .../lambda/functions/builtin/fn3/Between.java | 4 +-- .../lambda/functions/builtin/fn3/Clamp.java | 4 +-- .../lambda/functions/builtin/fn3/CmpEqBy.java | 4 +-- .../functions/builtin/fn3/FoldLeft.java | 4 +-- .../lambda/functions/builtin/fn3/GTBy.java | 4 +-- .../lambda/functions/builtin/fn3/GTEBy.java | 4 +-- .../lambda/functions/builtin/fn3/LTBy.java | 4 +-- .../lambda/functions/builtin/fn3/LTEBy.java | 4 +-- .../lambda/functions/builtin/fn3/LiftA2.java | 33 +++++++++++-------- .../functions/builtin/fn3/ScanLeft.java | 4 +-- .../lambda/functions/builtin/fn3/Times.java | 4 +-- .../lambda/functions/builtin/fn3/ZipWith.java | 4 +-- .../functions/builtin/fn4/IfThenElse.java | 4 +-- .../lambda/functions/builtin/fn4/LiftA3.java | 16 ++++----- .../functions/builtin/fn4/RateLimit.java | 4 +-- .../lambda/functions/builtin/fn5/LiftA4.java | 18 +++++----- .../lambda/functions/builtin/fn6/LiftA5.java | 20 +++++------ .../lambda/functions/builtin/fn7/LiftA6.java | 28 ++++++++-------- .../lambda/functions/builtin/fn8/LiftA7.java | 24 +++++++------- .../functions/recursion/RecursiveResult.java | 9 +++-- .../functions/recursion/Trampoline.java | 4 +-- .../lambda/functions/specialized/Kleisli.java | 4 +-- .../lambda/functions/specialized/Noop.java | 4 +-- .../palatable/lambda/functor/Applicative.java | 4 +-- .../palatable/lambda/functor/Bifunctor.java | 2 +- .../lambda/functor/BoundedBifunctor.java | 7 +++- .../lambda/functor/Contravariant.java | 2 +- .../palatable/lambda/functor/Functor.java | 2 +- .../palatable/lambda/functor/Profunctor.java | 2 +- .../palatable/lambda/functor/Strong.java | 2 +- .../lambda/functor/builtin/Compose.java | 3 +- .../lambda/functor/builtin/Const.java | 11 +++++-- .../lambda/functor/builtin/Identity.java | 19 ++++++----- .../lambda/iteration/ImmutableQueue.java | 4 +-- .../lambda/iteration/ImmutableStack.java | 4 +-- .../com/jnape/palatable/lambda/lens/Iso.java | 24 +++++++++----- .../com/jnape/palatable/lambda/lens/Lens.java | 11 +++++-- .../jnape/palatable/lambda/lens/LensLike.java | 6 ++-- .../palatable/lambda/lens/functions/Over.java | 6 ++-- .../palatable/lambda/lens/functions/Set.java | 4 +-- .../lambda/lens/functions/Under.java | 4 +-- .../palatable/lambda/lens/functions/View.java | 4 +-- .../jnape/palatable/lambda/monad/Monad.java | 6 ++-- .../lambda/monoid/builtin/AddAll.java | 4 +-- .../lambda/monoid/builtin/Collapse.java | 4 +-- .../lambda/monoid/builtin/Compose.java | 4 +-- .../lambda/monoid/builtin/Concat.java | 4 +-- .../lambda/monoid/builtin/First.java | 4 +-- .../palatable/lambda/monoid/builtin/Last.java | 4 +-- .../lambda/monoid/builtin/LeftAll.java | 4 +-- .../lambda/monoid/builtin/LeftAny.java | 4 +-- .../lambda/monoid/builtin/Merge.java | 4 +-- .../lambda/monoid/builtin/MergeMaps.java | 4 +-- .../lambda/monoid/builtin/RightAny.java | 4 +-- .../lambda/monoid/builtin/RunAll.java | 4 +-- .../lambda/monoid/builtin/Union.java | 4 +-- .../lambda/semigroup/builtin/Absent.java | 2 +- .../lambda/semigroup/builtin/Collapse.java | 4 +-- .../lambda/semigroup/builtin/Compose.java | 4 +-- .../lambda/semigroup/builtin/LeftAll.java | 4 +-- .../lambda/semigroup/builtin/LeftAny.java | 4 +-- .../lambda/semigroup/builtin/Max.java | 4 +-- .../lambda/semigroup/builtin/MaxBy.java | 4 +-- .../lambda/semigroup/builtin/Merge.java | 4 +-- .../lambda/semigroup/builtin/Min.java | 4 +-- .../lambda/semigroup/builtin/MinBy.java | 4 +-- .../lambda/semigroup/builtin/RightAll.java | 4 +-- .../lambda/semigroup/builtin/RightAny.java | 4 +-- .../lambda/semigroup/builtin/RunAll.java | 4 +-- .../lambda/traversable/LambdaIterable.java | 15 +++++---- .../lambda/traversable/LambdaMap.java | 15 +++++---- .../lambda/traversable/Traversable.java | 4 +-- .../functions/specialized/KleisliTest.java | 4 +-- .../lambda/functor/BifunctorTest.java | 6 ++-- .../lambda/functor/ProfunctorTest.java | 6 ++-- .../lambda/functor/builtin/ComposeTest.java | 2 +- .../jnape/palatable/lambda/lens/LensTest.java | 4 +-- src/test/java/testsupport/EquatableM.java | 2 +- .../InvocationRecordingBifunctor.java | 2 +- .../InvocationRecordingProfunctor.java | 2 +- .../testsupport/traits/ApplicativeLaws.java | 2 +- .../testsupport/traits/BifunctorLaws.java | 14 ++++---- .../java/testsupport/traits/FunctorLaws.java | 10 +++--- .../java/testsupport/traits/MonadLaws.java | 2 +- .../testsupport/traits/TraversableLaws.java | 25 +++++++------- 186 files changed, 594 insertions(+), 490 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c028d0d3f..ec8477ed1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/). factory methods should continue to work (by simply targeting `Supplier` now instead of an anonymous `IO`), but some might need to be reworked, and subtyping is obviously no longer supported. - ***Breaking Change***: `FoldRight` now requires `Lazy` as part of its interface to support short-circuiting operations +- ***Breaking Change***: Eliminated all raw types and java11 warnings. This required using capture in unification + parameters for Functor and friends, so nearly every functor's type-signature changed. - `IO` is now stack-safe, regardless of whether the composition nests linearly or recursively ### Added diff --git a/src/main/java/com/jnape/palatable/lambda/adt/Either.java b/src/main/java/com/jnape/palatable/lambda/adt/Either.java index c90ee9dd8..cea6eac17 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/Either.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/Either.java @@ -32,7 +32,11 @@ * @param The left parameter type * @param The right parameter type */ -public abstract class Either implements CoProduct2>, Monad>, Traversable>, Bifunctor { +public abstract class Either implements + CoProduct2>, + Monad>, + Traversable>, + Bifunctor> { private Either() { } @@ -125,8 +129,9 @@ public final Either filter(Function pred, * @return the Either resulting from applying rightFn to this right value, or this left value if left */ @Override + @SuppressWarnings("RedundantTypeArguments") public Either flatMap(Function>> rightFn) { - return match(Either::left, rightFn.andThen(Applicative::coerce)); + return match(Either::left, rightFn.andThen(Monad>::coerce)); } @Override @@ -146,6 +151,7 @@ public final Either invert() { * @return the merged Either */ @SafeVarargs + @SuppressWarnings("varargs") public final Either merge(BiFunction leftFn, BiFunction rightFn, Either... others) { @@ -279,9 +285,10 @@ public final Either discardR(Applicative> appB) { */ @Override @SuppressWarnings("unchecked") - public final >, AppB extends Applicative, AppTrav extends Applicative> AppTrav traverse( - Function fn, - Function pure) { + public final , TravB extends Traversable>, + AppB extends Applicative, + AppTrav extends Applicative> AppTrav traverse(Function fn, + Function pure) { return (AppTrav) match(l -> pure.apply((TravB) left(l)), r -> fn.apply(r).fmap(Either::right)); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/Maybe.java b/src/main/java/com/jnape/palatable/lambda/adt/Maybe.java index 7d07ba4c5..aeaf59d3c 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/Maybe.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/Maybe.java @@ -32,7 +32,10 @@ * @param the optional parameter type * @see Optional */ -public abstract class Maybe implements CoProduct2>, Monad, Traversable { +public abstract class Maybe implements + CoProduct2>, + Monad>, + Traversable> { private Maybe() { } @@ -131,7 +134,7 @@ public final Maybe fmap(Function fn) { * {@inheritDoc} */ @Override - public final Maybe zip(Applicative, Maybe> appFn) { + public final Maybe zip(Applicative, Maybe> appFn) { return Monad.super.zip(appFn).coerce(); } @@ -143,7 +146,7 @@ public final Maybe zip(Applicative, Mayb * @return the zipped {@link Maybe} */ @Override - public Lazy> lazyZip(Lazy, Maybe>> lazyAppFn) { + public Lazy> lazyZip(Lazy, Maybe>> lazyAppFn) { return match(constantly(lazy(nothing())), a -> lazyAppFn.fmap(maybeF -> maybeF.fmap(f -> f.apply(a)).coerce())); } @@ -152,7 +155,7 @@ public Lazy> lazyZip(Lazy Maybe discardL(Applicative appB) { + public final Maybe discardL(Applicative> appB) { return Monad.super.discardL(appB).coerce(); } @@ -160,16 +163,17 @@ public final Maybe discardL(Applicative appB) { * {@inheritDoc} */ @Override - public final Maybe discardR(Applicative appB) { + public final Maybe discardR(Applicative> appB) { return Monad.super.discardR(appB).coerce(); } /** * {@inheritDoc} */ + @SuppressWarnings("RedundantTypeArguments") @Override - public final Maybe flatMap(Function> f) { - return match(constantly(nothing()), f.andThen(Applicative::coerce)); + public final Maybe flatMap(Function>> f) { + return match(constantly(nothing()), f.andThen(Monad>::coerce)); } /** @@ -208,9 +212,10 @@ public final Maybe peek(Consumer consumer) { @Override @SuppressWarnings("unchecked") - public final , AppB extends Applicative, AppTrav extends Applicative> AppTrav traverse( - Function fn, - Function pure) { + public final , TravB extends Traversable>, + AppB extends Applicative, + AppTrav extends Applicative> AppTrav traverse(Function fn, + Function pure) { return match(__ -> pure.apply((TravB) Maybe.nothing()), a -> (AppTrav) fn.apply(a).fmap(Maybe::just)); } @@ -272,11 +277,11 @@ public static Maybe just(A a) { */ @SuppressWarnings("unchecked") public static Maybe nothing() { - return Nothing.INSTANCE; + return (Maybe) Nothing.INSTANCE; } private static final class Nothing extends Maybe { - private static final Nothing INSTANCE = new Nothing(); + private static final Nothing INSTANCE = new Nothing<>(); private Nothing() { } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/These.java b/src/main/java/com/jnape/palatable/lambda/adt/These.java index 494dbb38e..e25d0e741 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/These.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/These.java @@ -57,8 +57,10 @@ public final These pure(C c) { @Override @SuppressWarnings("unchecked") - public >, AppB extends Applicative, AppTrav extends Applicative> AppTrav traverse( - Function fn, Function pure) { + public , TravB extends Traversable>, + AppB extends Applicative, + AppTrav extends Applicative> AppTrav traverse(Function fn, + Function pure) { return match(a -> pure.apply((TravB) a(a)), b -> fn.apply(b).fmap(this::pure).fmap(Applicative::coerce).coerce(), into((a, b) -> fn.apply(b).fmap(c -> both(a, c)).fmap(Applicative::coerce).coerce())); diff --git a/src/main/java/com/jnape/palatable/lambda/adt/Try.java b/src/main/java/com/jnape/palatable/lambda/adt/Try.java index 5c67e7ebd..63b915122 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/Try.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/Try.java @@ -200,8 +200,10 @@ public Try discardR(Applicative> appB) { */ @Override @SuppressWarnings("unchecked") - public >, AppB extends Applicative, AppTrav extends Applicative> AppTrav traverse( - Function fn, Function pure) { + public , TravB extends Traversable>, + AppB extends Applicative, + AppTrav extends Applicative> AppTrav traverse(Function fn, + Function pure) { return match(t -> pure.apply((TravB) failure(t)), a -> fn.apply(a).fmap(Try::success).fmap(Applicative::coerce).coerce()); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice2.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice2.java index 5efb2c09a..52eeb2455 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice2.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice2.java @@ -29,7 +29,7 @@ public abstract class Choice2 implements CoProduct2>, Monad>, - Bifunctor, + Bifunctor>, Traversable> { private Choice2() { @@ -151,8 +151,10 @@ public final Choice2 flatMap(Function>, AppB extends Applicative, AppTrav extends Applicative> AppTrav traverse( - Function fn, Function pure) { + public , TravB extends Traversable>, + AppB extends Applicative, + AppTrav extends Applicative> AppTrav traverse(Function fn, + Function pure) { return match(a -> pure.apply((TravB) a(a)), b -> fn.apply(b).fmap(Choice2::b).fmap(Applicative::coerce).coerce()); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice3.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice3.java index d8f984cf7..7ea524505 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice3.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice3.java @@ -152,8 +152,10 @@ public Choice3 flatMap(Function>, AppB extends Applicative, AppTrav extends Applicative> AppTrav traverse( - Function fn, Function pure) { + public , TravB extends Traversable>, + AppB extends Applicative, + AppTrav extends Applicative> AppTrav traverse(Function fn, + Function pure) { return match(a -> pure.apply((TravB) Choice3.a(a)).coerce(), b -> pure.apply((TravB) Choice3.b(b)).coerce(), c -> fn.apply(c).fmap(Choice3::c).fmap(Applicative::coerce).coerce()); diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice4.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice4.java index 0e9a0aebb..be222cbac 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice4.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice4.java @@ -154,8 +154,10 @@ public Choice4 flatMap(Function>, AppB extends Applicative, AppTrav extends Applicative> AppTrav traverse( - Function fn, Function pure) { + public , TravB extends Traversable>, + AppB extends Applicative, + AppTrav extends Applicative> AppTrav traverse(Function fn, + Function pure) { return match(a -> pure.apply((TravB) Choice4.a(a)).coerce(), b -> pure.apply((TravB) Choice4.b(b)).coerce(), c -> pure.apply((TravB) Choice4.c(c)), diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice5.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice5.java index ab7a8c2fb..a4c12d21d 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice5.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice5.java @@ -160,8 +160,10 @@ public Choice5 flatMap(Function>, AppB extends Applicative, AppTrav extends Applicative> AppTrav traverse( - Function fn, Function pure) { + public , TravB extends Traversable>, + AppB extends Applicative, + AppTrav extends Applicative> AppTrav traverse(Function fn, + Function pure) { return match(a -> pure.apply((TravB) Choice5.a(a)).coerce(), b -> pure.apply((TravB) Choice5.b(b)).coerce(), c -> pure.apply((TravB) Choice5.c(c)), diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice6.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice6.java index 59df7eee1..86e2648f5 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice6.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice6.java @@ -165,8 +165,10 @@ public Choice6 flatMap( */ @Override @SuppressWarnings("unchecked") - public >, AppB extends Applicative, AppTrav extends Applicative> AppTrav traverse( - Function fn, Function pure) { + public , TravB extends Traversable>, + AppB extends Applicative, + AppTrav extends Applicative> AppTrav traverse(Function fn, + Function pure) { return match(a -> pure.apply((TravB) Choice6.a(a)).coerce(), b -> pure.apply((TravB) Choice6.b(b)).coerce(), c -> pure.apply((TravB) Choice6.c(c)), diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice7.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice7.java index a5f170e4b..40c678f87 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice7.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice7.java @@ -169,8 +169,10 @@ public Choice7 flatMap( */ @Override @SuppressWarnings("unchecked") - public >, AppB extends Applicative, AppTrav extends Applicative> AppTrav traverse( - Function fn, Function pure) { + public , TravB extends Traversable>, + AppB extends Applicative, + AppTrav extends Applicative> AppTrav traverse(Function fn, + Function pure) { return match(a -> pure.apply((TravB) Choice7.a(a)).coerce(), b -> pure.apply((TravB) Choice7.b(b)).coerce(), c -> pure.apply((TravB) Choice7.c(c)), diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice8.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice8.java index 3cd03e2a9..e8fb9debe 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice8.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice8.java @@ -163,8 +163,10 @@ public Choice8 flatMap( */ @Override @SuppressWarnings("unchecked") - public >, AppB extends Applicative, AppTrav extends Applicative> AppTrav traverse( - Function fn, Function pure) { + public , TravB extends Traversable>, + AppB extends Applicative, + AppTrav extends Applicative> AppTrav traverse(Function fn, + Function pure) { return match(a -> pure.apply((TravB) Choice8.a(a)).coerce(), b -> pure.apply((TravB) Choice8.b(b)).coerce(), c -> pure.apply((TravB) Choice8.c(c)), diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/HList.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/HList.java index bfb0b8f79..91f19edbe 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/HList.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/HList.java @@ -34,7 +34,7 @@ public final String toString() { HList next = this; while (next != HNil.INSTANCE) { - HCons hCons = (HCons) next; + HCons hCons = (HCons) next; body.append(" ").append(hCons.head).append(" "); next = hCons.tail; if (next != HNil.INSTANCE) @@ -269,7 +269,7 @@ public Tail tail() { @Override public final boolean equals(Object other) { if (other instanceof HCons) { - HCons that = (HCons) other; + HCons that = (HCons) other; return this.head.equals(that.head) && this.tail.equals(that.tail); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Index.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Index.java index 12f1eeebd..6a59384c6 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Index.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Index.java @@ -55,7 +55,7 @@ private Index() { private static final class Z extends Index> { - private static final Z INSTANCE = new Z(); + private static final Z INSTANCE = new Z<>(); @Override public Target get(HCons hList) { diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/SingletonHList.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/SingletonHList.java index 0c8608e31..8a5be88b9 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/SingletonHList.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/SingletonHList.java @@ -19,7 +19,9 @@ * @see Tuple4 * @see Tuple5 */ -public class SingletonHList<_1> extends HCons<_1, HNil> implements Monad<_1, SingletonHList>, Traversable<_1, SingletonHList> { +public class SingletonHList<_1> extends HCons<_1, HNil> implements + Monad<_1, SingletonHList>, + Traversable<_1, SingletonHList> { SingletonHList(_1 _1) { super(_1, nil()); @@ -42,35 +44,38 @@ public <_1Prime> SingletonHList<_1Prime> pure(_1Prime _1Prime) { @Override public <_1Prime> SingletonHList<_1Prime> zip( - Applicative, SingletonHList> appFn) { + Applicative, SingletonHList> appFn) { return Monad.super.zip(appFn).coerce(); } @Override public <_1Prime> Lazy> lazyZip( - Lazy, SingletonHList>> lazyAppFn) { + Lazy, SingletonHList>> lazyAppFn) { return Monad.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); } @Override - public <_1Prime> SingletonHList<_1Prime> discardL(Applicative<_1Prime, SingletonHList> appB) { + public <_1Prime> SingletonHList<_1Prime> discardL(Applicative<_1Prime, SingletonHList> appB) { return Monad.super.discardL(appB).coerce(); } @Override - public <_1Prime> SingletonHList<_1> discardR(Applicative<_1Prime, SingletonHList> appB) { + public <_1Prime> SingletonHList<_1> discardR(Applicative<_1Prime, SingletonHList> appB) { return Monad.super.discardR(appB).coerce(); } @Override - public <_1Prime> SingletonHList<_1Prime> flatMap(Function> f) { + public <_1Prime> SingletonHList<_1Prime> flatMap( + Function>> f) { return f.apply(head()).coerce(); } @Override @SuppressWarnings("unchecked") - public , AppB extends Applicative, AppTrav extends Applicative> AppTrav traverse( - Function fn, Function pure) { + public , TravB extends Traversable>, + AppB extends Applicative, + AppTrav extends Applicative> AppTrav traverse(Function fn, + Function pure) { return fn.apply(head()).fmap(SingletonHList::new).fmap(Applicative::coerce).coerce(); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple2.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple2.java index 7268d0595..06dc1a20a 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple2.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple2.java @@ -29,7 +29,7 @@ public class Tuple2<_1, _2> extends HCons<_1, SingletonHList<_2>> implements Product2<_1, _2>, Map.Entry<_1, _2>, Monad<_2, Tuple2<_1, ?>>, - Bifunctor<_1, _2, Tuple2>, + Bifunctor<_1, _2, Tuple2>, Traversable<_2, Tuple2<_1, ?>> { private final _1 _1; @@ -113,7 +113,7 @@ public <_2Prime> Tuple2<_1, _2Prime> zip( @Override public <_2Prime> Lazy> lazyZip( Lazy, Tuple2<_1, ?>>> lazyAppFn) { - return Monad.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); + return Monad.super.lazyZip(lazyAppFn).fmap(Monad<_2Prime, Tuple2<_1, ?>>::coerce); } @Override @@ -133,8 +133,10 @@ public <_2Prime> Tuple2<_1, _2Prime> flatMap(Function>, AppB extends Applicative<_2Prime, App>, AppTrav extends Applicative> AppTrav traverse( - Function fn, Function pure) { + public <_2Prime, App extends Applicative, TravB extends Traversable<_2Prime, Tuple2<_1, ?>>, + AppB extends Applicative<_2Prime, App>, + AppTrav extends Applicative> AppTrav traverse(Function fn, + Function pure) { return fn.apply(_2).fmap(_2Prime -> fmap(constantly(_2Prime))).fmap(Applicative::coerce).coerce(); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple3.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple3.java index de7116c03..a4601ce19 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple3.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple3.java @@ -136,8 +136,10 @@ public <_3Prime> Tuple3<_1, _2, _3Prime> flatMap( @Override @SuppressWarnings("unchecked") - public <_3Prime, App extends Applicative, TravB extends Traversable<_3Prime, Tuple3<_1, _2, ?>>, AppB extends Applicative<_3Prime, App>, AppTrav extends Applicative> AppTrav traverse( - Function fn, Function pure) { + public <_3Prime, App extends Applicative, TravB extends Traversable<_3Prime, Tuple3<_1, _2, ?>>, + AppB extends Applicative<_3Prime, App>, + AppTrav extends Applicative> AppTrav traverse(Function fn, + Function pure) { return fn.apply(_3).fmap(_3Prime -> fmap(constantly(_3Prime))).fmap(Applicative::coerce).coerce(); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple4.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple4.java index b240ab948..6b3c410a5 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple4.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple4.java @@ -151,8 +151,10 @@ public <_4Prime> Tuple4<_1, _2, _3, _4Prime> flatMap( @Override @SuppressWarnings("unchecked") - public <_4Prime, App extends Applicative, TravB extends Traversable<_4Prime, Tuple4<_1, _2, _3, ?>>, AppB extends Applicative<_4Prime, App>, AppTrav extends Applicative> AppTrav traverse( - Function fn, Function pure) { + public <_4Prime, App extends Applicative, TravB extends Traversable<_4Prime, Tuple4<_1, _2, _3, ?>>, + AppB extends Applicative<_4Prime, App>, + AppTrav extends Applicative> AppTrav traverse(Function fn, + Function pure) { return fn.apply(_4).fmap(_4Prime -> fmap(constantly(_4Prime))).fmap(Applicative::coerce).coerce(); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple5.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple5.java index 5c9764aff..fe2961fd5 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple5.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple5.java @@ -171,8 +171,10 @@ public <_5Prime> Tuple5<_1, _2, _3, _4, _5Prime> flatMap( @Override @SuppressWarnings("unchecked") - public <_5Prime, App extends Applicative, TravB extends Traversable<_5Prime, Tuple5<_1, _2, _3, _4, ?>>, AppB extends Applicative<_5Prime, App>, AppTrav extends Applicative> AppTrav traverse( - Function fn, Function pure) { + public <_5Prime, App extends Applicative, TravB extends Traversable<_5Prime, Tuple5<_1, _2, _3, _4, ?>>, + AppB extends Applicative<_5Prime, App>, + AppTrav extends Applicative> AppTrav traverse(Function fn, + Function pure) { return fn.apply(_5).fmap(_3Prime -> fmap(constantly(_3Prime))).fmap(Applicative::coerce).coerce(); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple6.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple6.java index 92b983675..2231c6a63 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple6.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple6.java @@ -192,8 +192,10 @@ public <_6Prime> Tuple6<_1, _2, _3, _4, _5, _6Prime> flatMap( @Override @SuppressWarnings("unchecked") - public <_6Prime, App extends Applicative, TravB extends Traversable<_6Prime, Tuple6<_1, _2, _3, _4, _5, ?>>, AppB extends Applicative<_6Prime, App>, AppTrav extends Applicative> AppTrav traverse( - Function fn, Function pure) { + public <_6Prime, App extends Applicative, TravB extends Traversable<_6Prime, Tuple6<_1, _2, _3, _4, _5, ?>>, + AppB extends Applicative<_6Prime, App>, + AppTrav extends Applicative> AppTrav traverse(Function fn, + Function pure) { return fn.apply(_6).fmap(_6Prime -> fmap(constantly(_6Prime))).fmap(Applicative::coerce).coerce(); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple7.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple7.java index f3f010e2e..36e39bca8 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple7.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple7.java @@ -212,8 +212,11 @@ public <_7Prime> Tuple7<_1, _2, _3, _4, _5, _6, _7Prime> flatMap( @Override @SuppressWarnings("unchecked") - public <_7Prime, App extends Applicative, TravB extends Traversable<_7Prime, Tuple7<_1, _2, _3, _4, _5, _6, ?>>, AppB extends Applicative<_7Prime, App>, AppTrav extends Applicative> AppTrav traverse( - Function fn, Function pure) { + public <_7Prime, App extends Applicative, + TravB extends Traversable<_7Prime, Tuple7<_1, _2, _3, _4, _5, _6, ?>>, + AppB extends Applicative<_7Prime, App>, + AppTrav extends Applicative> AppTrav traverse(Function fn, + Function pure) { return fn.apply(_7).fmap(_7Prime -> fmap(constantly(_7Prime))).fmap(Applicative::coerce).coerce(); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple8.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple8.java index 6d424e3bb..bbc2123cd 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple8.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple8.java @@ -231,8 +231,11 @@ public <_8Prime> Tuple8<_1, _2, _3, _4, _5, _6, _7, _8Prime> flatMap( @Override @SuppressWarnings("unchecked") - public <_8Prime, App extends Applicative, TravB extends Traversable<_8Prime, Tuple8<_1, _2, _3, _4, _5, _6, _7, ?>>, AppB extends Applicative<_8Prime, App>, AppTrav extends Applicative> AppTrav traverse( - Function fn, Function pure) { + public <_8Prime, App extends Applicative, + TravB extends Traversable<_8Prime, Tuple8<_1, _2, _3, _4, _5, _6, _7, ?>>, + AppB extends Applicative<_8Prime, App>, + AppTrav extends Applicative> AppTrav traverse(Function fn, + Function pure) { return fn.apply(_8).fmap(_8Prime -> fmap(constantly(_8Prime))).fmap(Applicative::coerce).coerce(); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hmap/TypeSafeKey.java b/src/main/java/com/jnape/palatable/lambda/adt/hmap/TypeSafeKey.java index 8bae70949..e07936a2f 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hmap/TypeSafeKey.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hmap/TypeSafeKey.java @@ -28,9 +28,10 @@ default TypeSafeKey discardR(Applicative> Iso.Simple discarded = Iso.Simple.super.discardR(appB); return new TypeSafeKey() { @Override - public

, FT extends Functor, PAFB extends Profunctor, PSFT extends Profunctor> PSFT apply( - PAFB pafb) { - return discarded.apply(pafb); + public

, F extends Functor, FB extends Functor, + FT extends Functor, PAFB extends Profunctor, + PSFT extends Profunctor> PSFT apply(PAFB pafb) { + return discarded.apply(pafb); } @Override @@ -64,9 +65,10 @@ default TypeSafeKey andThen(Iso.Simple f) { Iso.Simple composed = Iso.Simple.super.andThen(f); return new TypeSafeKey() { @Override - public

, FT extends Functor, PAFB extends Profunctor, PSFT extends Profunctor> PSFT apply( - PAFB pafb) { - return composed.apply(pafb); + public

, FT extends Functor, PAFB extends Profunctor, PSFT extends Profunctor> PSFT apply( - PAFB pafb) { + default

, F extends Functor, FB extends Functor, + FT extends Functor, PAFB extends Profunctor, + PSFT extends Profunctor> PSFT apply(PAFB pafb) { return (PSFT) pafb; } } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java index 3ea573870..9bff01745 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java @@ -20,7 +20,7 @@ * @param The result type */ @FunctionalInterface -public interface Fn1 extends Monad>, Strong, Function { +public interface Fn1 extends Monad>, Strong>, Function { /** * Invoke this function with the given argument. @@ -100,7 +100,7 @@ default Fn1 zip(Fn2 appFn) { */ @Override default Lazy> lazyZip(Lazy, Fn1>> lazyAppFn) { - return Monad.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); + return Monad.super.lazyZip(lazyAppFn).fmap(Monad>::coerce); } /** @@ -205,6 +205,7 @@ default Fn1 compose(Function before) { * @param the resulting function's second argument type * @return an {@link Fn2}<Y, Z, B> */ + @SuppressWarnings({"overloads"}) default Fn2 compose(BiFunction before) { return compose(fn2(before)); } @@ -217,6 +218,7 @@ default Fn2 compose(BiFunction the resulting function's second argument type * @return an {@link Fn2}<Y, Z, B> */ + @SuppressWarnings({"overloads"}) default Fn2 compose(Fn2 before) { return fn2(before.fmap(this::compose))::apply; } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/CatMaybes.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/CatMaybes.java index 64b9e0a4c..d74111ba3 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/CatMaybes.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/CatMaybes.java @@ -15,7 +15,7 @@ * @param the {@link Maybe} element type, as well as the resulting {@link Iterable} element type */ public final class CatMaybes implements Fn1>, Iterable> { - private static final CatMaybes INSTANCE = new CatMaybes(); + private static final CatMaybes INSTANCE = new CatMaybes<>(); private CatMaybes() { } @@ -28,7 +28,7 @@ public Iterable apply(Iterable> maybes) { @SuppressWarnings("unchecked") public static CatMaybes catMaybes() { - return INSTANCE; + return (CatMaybes) INSTANCE; } public static Iterable catMaybes(Iterable> as) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Coalesce.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Coalesce.java index e97fe056f..ce9147028 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Coalesce.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Coalesce.java @@ -25,7 +25,7 @@ */ public final class Coalesce implements Fn1>, Either, Iterable>> { - private static final Coalesce INSTANCE = new Coalesce(); + private static final Coalesce INSTANCE = new Coalesce<>(); private Coalesce() { } @@ -42,7 +42,7 @@ public Either, Iterable> apply(Iterable> eithers) { @SuppressWarnings("unchecked") public static Coalesce coalesce() { - return INSTANCE; + return (Coalesce) INSTANCE; } public static Either, Iterable> coalesce(Iterable> eithers) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Constantly.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Constantly.java index 9f89da517..ed4d367b0 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Constantly.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Constantly.java @@ -11,7 +11,7 @@ */ public final class Constantly implements Fn2 { - private static final Constantly INSTANCE = new Constantly(); + private static final Constantly INSTANCE = new Constantly<>(); private Constantly() { } @@ -23,7 +23,7 @@ public A apply(A a, B b) { @SuppressWarnings("unchecked") public static Constantly constantly() { - return INSTANCE; + return (Constantly) INSTANCE; } public static Fn1 constantly(A a) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Cycle.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Cycle.java index 652b5470d..10fd2039b 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Cycle.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Cycle.java @@ -13,7 +13,7 @@ */ public final class Cycle implements Fn1, Iterable> { - private static final Cycle INSTANCE = new Cycle(); + private static final Cycle INSTANCE = new Cycle<>(); private Cycle() { } @@ -25,7 +25,7 @@ public Iterable apply(Iterable as) { @SuppressWarnings("unchecked") public static Cycle cycle() { - return INSTANCE; + return (Cycle) INSTANCE; } public static Iterable cycle(Iterable as) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Distinct.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Distinct.java index 8b39ac2a4..949c2c91e 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Distinct.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Distinct.java @@ -9,7 +9,7 @@ * @param the Iterable element type */ public final class Distinct implements Fn1, Iterable> { - private static final Distinct INSTANCE = new Distinct(); + private static final Distinct INSTANCE = new Distinct<>(); private Distinct() { } @@ -21,7 +21,7 @@ public Iterable apply(Iterable as) { @SuppressWarnings("unchecked") public static Distinct distinct() { - return INSTANCE; + return (Distinct) INSTANCE; } public static Iterable distinct(Iterable as) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Empty.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Empty.java index 9906aa803..b8b0f656b 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Empty.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Empty.java @@ -9,7 +9,7 @@ */ public final class Empty implements Predicate> { - private static final Empty INSTANCE = new Empty(); + private static final Empty INSTANCE = new Empty<>(); private Empty() { } @@ -21,7 +21,7 @@ public Boolean apply(Iterable as) { @SuppressWarnings("unchecked") public static Empty empty() { - return INSTANCE; + return (Empty) INSTANCE; } public static Boolean empty(Iterable as) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Flatten.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Flatten.java index 4c88bdec8..ba05c771d 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Flatten.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Flatten.java @@ -10,7 +10,7 @@ * @param the nested Iterable element type */ public final class Flatten implements Fn1>, Iterable> { - private static final Flatten INSTANCE = new Flatten(); + private static final Flatten INSTANCE = new Flatten<>(); private Flatten() { } @@ -22,7 +22,7 @@ public Iterable apply(Iterable> iterables) { @SuppressWarnings("unchecked") public static Flatten flatten() { - return INSTANCE; + return (Flatten) INSTANCE; } public static Iterable flatten(Iterable> as) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Force.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Force.java index 511b90b4e..84852199a 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Force.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Force.java @@ -10,7 +10,7 @@ */ public final class Force implements Fn1, Iterable> { - private static final Force INSTANCE = new Force(); + private static final Force INSTANCE = new Force<>(); private Force() { } @@ -25,7 +25,7 @@ public Iterable apply(Iterable as) { @SuppressWarnings("unchecked") public static Force force() { - return INSTANCE; + return (Force) INSTANCE; } public static Iterable force(Iterable as) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Head.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Head.java index e8abf632b..e6b2457e4 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Head.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Head.java @@ -16,7 +16,7 @@ */ public final class Head implements Fn1, Maybe> { - private static final Head INSTANCE = new Head(); + private static final Head INSTANCE = new Head<>(); private Head() { } @@ -29,7 +29,7 @@ public Maybe apply(Iterable as) { @SuppressWarnings("unchecked") public static Head head() { - return INSTANCE; + return (Head) INSTANCE; } public static Maybe head(Iterable as) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Id.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Id.java index 640927f50..62a5871ea 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Id.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Id.java @@ -9,7 +9,7 @@ */ public final class Id implements Fn1 { - private static final Id INSTANCE = new Id(); + private static final Id INSTANCE = new Id<>(); private Id() { } @@ -21,6 +21,6 @@ public A apply(A a) { @SuppressWarnings("unchecked") public static Id id() { - return INSTANCE; + return (Id) INSTANCE; } } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Init.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Init.java index ced05d274..2162e65ee 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Init.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Init.java @@ -11,7 +11,7 @@ */ public final class Init implements Fn1, Iterable> { - private static final Init INSTANCE = new Init(); + private static final Init INSTANCE = new Init<>(); private Init() { } @@ -23,7 +23,7 @@ public Iterable apply(Iterable as) { @SuppressWarnings("unchecked") public static Init init() { - return INSTANCE; + return (Init) INSTANCE; } public static Iterable init(Iterable as) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Inits.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Inits.java index 52c0413b6..cb6d7165c 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Inits.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Inits.java @@ -19,7 +19,7 @@ */ public final class Inits implements Fn1, Iterable>> { - private static final Inits INSTANCE = new Inits(); + private static final Inits INSTANCE = new Inits<>(); private Inits() { } @@ -31,7 +31,7 @@ public Iterable> apply(Iterable as) { @SuppressWarnings("unchecked") public static Inits inits() { - return INSTANCE; + return (Inits) INSTANCE; } public static Iterable> inits(Iterable as) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Last.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Last.java index 4710f7900..9f49e95da 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Last.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Last.java @@ -13,7 +13,7 @@ */ public final class Last implements Fn1, Maybe> { - private static final Last INSTANCE = new Last(); + private static final Last INSTANCE = new Last<>(); private Last() { } @@ -29,7 +29,7 @@ public Maybe apply(Iterable as) { @SuppressWarnings("unchecked") public static Last last() { - return INSTANCE; + return (Last) INSTANCE; } public static Maybe last(Iterable as) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Magnetize.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Magnetize.java index 47c4d3ed8..b25e3e32a 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Magnetize.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Magnetize.java @@ -12,7 +12,7 @@ */ public final class Magnetize implements Fn1, Iterable>> { - private static final Magnetize INSTANCE = new Magnetize(); + private static final Magnetize INSTANCE = new Magnetize<>(); private Magnetize() { } @@ -24,7 +24,7 @@ public Iterable> apply(Iterable as) { @SuppressWarnings("unchecked") public static Magnetize magnetize() { - return INSTANCE; + return (Magnetize) INSTANCE; } public static Iterable> magnetize(Iterable as) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Not.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Not.java index 5f0bb8691..a7b4956c6 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Not.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Not.java @@ -11,7 +11,7 @@ * @param the input argument type */ public final class Not implements BiPredicate, A> { - private static final Not INSTANCE = new Not(); + private static final Not INSTANCE = new Not<>(); private Not() { } @@ -23,7 +23,7 @@ public Boolean apply(Function pred, A a) { @SuppressWarnings("unchecked") public static Not not() { - return INSTANCE; + return (Not) INSTANCE; } public static Predicate not(Function pred) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Occurrences.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Occurrences.java index 8a9062942..af9e21f39 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Occurrences.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Occurrences.java @@ -14,7 +14,7 @@ * @param the {@link Iterable} element type */ public final class Occurrences implements Fn1, Map> { - private static final Occurrences INSTANCE = new Occurrences(); + private static final Occurrences INSTANCE = new Occurrences<>(); private Occurrences() { } @@ -29,7 +29,7 @@ public Map apply(Iterable as) { @SuppressWarnings("unchecked") public static Occurrences occurrences() { - return INSTANCE; + return (Occurrences) INSTANCE; } public static Map occurrences(Iterable as) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Repeat.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Repeat.java index 4286dbace..68209c874 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Repeat.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Repeat.java @@ -10,7 +10,7 @@ */ public final class Repeat implements Fn1> { - private static final Repeat INSTANCE = new Repeat(); + private static final Repeat INSTANCE = new Repeat<>(); private Repeat() { } @@ -22,7 +22,7 @@ public Iterable apply(A a) { @SuppressWarnings("unchecked") public static Repeat repeat() { - return INSTANCE; + return (Repeat) INSTANCE; } public static Iterable repeat(A a) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Reverse.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Reverse.java index 7b50cecbc..3913da8f0 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Reverse.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Reverse.java @@ -11,7 +11,7 @@ */ public final class Reverse implements Fn1, Iterable> { - private static final Reverse INSTANCE = new Reverse(); + private static final Reverse INSTANCE = new Reverse<>(); private Reverse() { } @@ -23,7 +23,7 @@ public Iterable apply(Iterable as) { @SuppressWarnings("unchecked") public static Reverse reverse() { - return INSTANCE; + return (Reverse) INSTANCE; } public static Iterable reverse(Iterable as) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Sort.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Sort.java index 96fb7056d..315b6780c 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Sort.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Sort.java @@ -19,7 +19,7 @@ */ public final class Sort> implements Fn1, List> { - private static final Sort INSTANCE = new Sort(); + private static final Sort INSTANCE = new Sort<>(); private Sort() { } @@ -31,7 +31,7 @@ public List apply(Iterable as) { @SuppressWarnings("unchecked") public static > Sort sort() { - return INSTANCE; + return (Sort) INSTANCE; } public static > List sort(Iterable as) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Tail.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Tail.java index 8b954fe07..930b4be95 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Tail.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Tail.java @@ -12,7 +12,7 @@ */ public final class Tail implements Fn1, Iterable> { - private static final Tail INSTANCE = new Tail(); + private static final Tail INSTANCE = new Tail<>(); private Tail() { } @@ -24,7 +24,7 @@ public Iterable apply(Iterable as) { @SuppressWarnings("unchecked") public static Tail tail() { - return INSTANCE; + return (Tail) INSTANCE; } public static Iterable tail(Iterable as) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Tails.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Tails.java index cbdc65589..cffe390d3 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Tails.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Tails.java @@ -22,7 +22,7 @@ */ public final class Tails implements Fn1, Iterable>> { - private static final Tails INSTANCE = new Tails(); + private static final Tails INSTANCE = new Tails<>(); private Tails() { } @@ -34,7 +34,7 @@ public Iterable> apply(Iterable as) { @SuppressWarnings("unchecked") public static Tails tails() { - return INSTANCE; + return (Tails) INSTANCE; } public static Iterable> tails(Iterable as) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Uncons.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Uncons.java index 7c6c807bf..27014940b 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Uncons.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Uncons.java @@ -16,7 +16,7 @@ */ public final class Uncons implements Fn1, Maybe>>> { - private static final Uncons INSTANCE = new Uncons(); + private static final Uncons INSTANCE = new Uncons<>(); private Uncons() { } @@ -28,7 +28,7 @@ public Maybe>> apply(Iterable as) { @SuppressWarnings("unchecked") public static Uncons uncons() { - return INSTANCE; + return (Uncons) INSTANCE; } public static Maybe>> uncons(Iterable as) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/All.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/All.java index 2aeb00eca..0019932b4 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/All.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/All.java @@ -15,7 +15,7 @@ */ public final class All implements BiPredicate, Iterable> { - private static final All INSTANCE = new All(); + private static final All INSTANCE = new All<>(); private All() { } @@ -31,7 +31,7 @@ public Boolean apply(Function predicate, Iterable< @SuppressWarnings("unchecked") public static All all() { - return INSTANCE; + return (All) INSTANCE; } public static Fn1, ? extends Boolean> all(Function predicate) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Alter.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Alter.java index 488de31ce..b12160c1f 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Alter.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Alter.java @@ -15,7 +15,7 @@ */ public final class Alter implements Fn2, A, IO> { - private static final Alter INSTANCE = new Alter(); + private static final Alter INSTANCE = new Alter<>(); private Alter() { } @@ -27,7 +27,7 @@ public IO apply(Effect effect, A a) { @SuppressWarnings("unchecked") public static Alter alter() { - return INSTANCE; + return (Alter) INSTANCE; } public static Fn1> alter(Effect effect) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Any.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Any.java index 6285084f5..eacb359b3 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Any.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Any.java @@ -15,7 +15,7 @@ */ public final class Any implements BiPredicate, Iterable> { - private static final Any INSTANCE = new Any(); + private static final Any INSTANCE = new Any<>(); private Any() { } @@ -31,7 +31,7 @@ public Boolean apply(Function predicate, Iterable< @SuppressWarnings("unchecked") public static Any any() { - return INSTANCE; + return (Any) INSTANCE; } public static Predicate> any(Function predicate) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Both.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Both.java index 04bce60f5..0693437cd 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Both.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Both.java @@ -16,7 +16,7 @@ */ public final class Both implements Fn3, Function, A, Tuple2> { - private static final Both INSTANCE = new Both(); + private static final Both INSTANCE = new Both<>(); private Both() { } @@ -30,7 +30,7 @@ public Tuple2 apply(Function f, @SuppressWarnings("unchecked") public static Both both() { - return INSTANCE; + return (Both) INSTANCE; } public static Fn1, Fn1>> both( diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/CartesianProduct.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/CartesianProduct.java index aa883f86c..e6663cfe3 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/CartesianProduct.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/CartesianProduct.java @@ -21,7 +21,7 @@ */ public final class CartesianProduct implements Fn2, Iterable, Iterable>> { - private static final CartesianProduct INSTANCE = new CartesianProduct(); + private static final CartesianProduct INSTANCE = new CartesianProduct<>(); private CartesianProduct() { } @@ -33,7 +33,7 @@ public Iterable> apply(Iterable as, Iterable bs) { @SuppressWarnings("unchecked") public static CartesianProduct cartesianProduct() { - return INSTANCE; + return (CartesianProduct) INSTANCE; } public static Fn1, Iterable>> cartesianProduct(Iterable as) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/CmpEq.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/CmpEq.java index 132dec5c7..de9bd9e4e 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/CmpEq.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/CmpEq.java @@ -18,7 +18,7 @@ */ public final class CmpEq> implements BiPredicate { - private static final CmpEq INSTANCE = new CmpEq(); + private static final CmpEq INSTANCE = new CmpEq<>(); private CmpEq() { } @@ -30,7 +30,7 @@ public Boolean apply(A x, A y) { @SuppressWarnings("unchecked") public static > CmpEq cmpEq() { - return INSTANCE; + return (CmpEq) INSTANCE; } public static > Predicate cmpEq(A x) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Cons.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Cons.java index bee418871..c69d18ddd 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Cons.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Cons.java @@ -11,7 +11,7 @@ */ public final class Cons implements Fn2, Iterable> { - private static final Cons INSTANCE = new Cons(); + private static final Cons INSTANCE = new Cons<>(); private Cons() { } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Difference.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Difference.java index 777279597..384b62175 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Difference.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Difference.java @@ -23,7 +23,7 @@ */ public final class Difference implements Fn2, Iterable, Iterable> { - private static final Difference INSTANCE = new Difference(); + private static final Difference INSTANCE = new Difference<>(); private Difference() { } @@ -45,7 +45,7 @@ public Iterable apply(Iterable xs, Iterable ys) { @SuppressWarnings("unchecked") public static Difference difference() { - return INSTANCE; + return (Difference) INSTANCE; } public static Fn1, Iterable> difference(Iterable xs) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Drop.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Drop.java index c286d2da6..291324bdf 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Drop.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Drop.java @@ -15,7 +15,7 @@ */ public final class Drop implements Fn2, Iterable> { - private static final Drop INSTANCE = new Drop(); + private static final Drop INSTANCE = new Drop<>(); private Drop() { } @@ -27,7 +27,7 @@ public Iterable apply(Integer n, Iterable as) { @SuppressWarnings("unchecked") public static Drop drop() { - return INSTANCE; + return (Drop) INSTANCE; } public static Fn1, Iterable> drop(int n) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/DropWhile.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/DropWhile.java index 560f35c5c..edd8e45fb 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/DropWhile.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/DropWhile.java @@ -18,7 +18,7 @@ public final class DropWhile implements Fn2, Iterable, Iterable> { - private static final DropWhile INSTANCE = new DropWhile(); + private static final DropWhile INSTANCE = new DropWhile<>(); private DropWhile() { } @@ -30,7 +30,7 @@ public Iterable apply(Function predicate, Itera @SuppressWarnings("unchecked") public static DropWhile dropWhile() { - return INSTANCE; + return (DropWhile) INSTANCE; } public static Fn1, Iterable> dropWhile(Function predicate) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Eq.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Eq.java index 83cce842c..126d26072 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Eq.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Eq.java @@ -10,7 +10,7 @@ */ public final class Eq implements BiPredicate { - private static final Eq INSTANCE = new Eq(); + private static final Eq INSTANCE = new Eq<>(); private Eq() { } @@ -22,7 +22,7 @@ public Boolean apply(A x, A y) { @SuppressWarnings("unchecked") public static Eq eq() { - return INSTANCE; + return (Eq) INSTANCE; } public static Predicate eq(A x) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Filter.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Filter.java index fd0c70e7a..8e208ac1b 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Filter.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Filter.java @@ -16,7 +16,7 @@ */ public final class Filter implements Fn2, Iterable, Iterable> { - private static final Filter INSTANCE = new Filter(); + private static final Filter INSTANCE = new Filter<>(); private Filter() { } @@ -28,7 +28,7 @@ public Iterable apply(Function predicate, Itera @SuppressWarnings("unchecked") public static Filter filter() { - return INSTANCE; + return (Filter) INSTANCE; } public static Fn1, Iterable> filter(Function predicate) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Find.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Find.java index 716a4f3e8..2ddf0c8be 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Find.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Find.java @@ -20,7 +20,7 @@ */ public final class Find implements Fn2, Iterable, Maybe> { - private static final Find INSTANCE = new Find(); + private static final Find INSTANCE = new Find<>(); private Find() { } @@ -32,7 +32,7 @@ public Maybe apply(Function predicate, Iterable @SuppressWarnings("unchecked") public static Find find() { - return INSTANCE; + return (Find) INSTANCE; } public static Fn1, Maybe> find(Function predicate) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GT.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GT.java index 85cd2018c..7d99e7bc1 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GT.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GT.java @@ -17,7 +17,7 @@ */ public final class GT> implements BiPredicate { - private static final GT INSTANCE = new GT(); + private static final GT INSTANCE = new GT<>(); private GT() { } @@ -29,7 +29,7 @@ public Boolean apply(A y, A x) { @SuppressWarnings("unchecked") public static > GT gt() { - return INSTANCE; + return (GT) INSTANCE; } public static > Predicate gt(A y) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GTE.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GTE.java index a0203984d..5304755de 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GTE.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GTE.java @@ -17,7 +17,7 @@ */ public final class GTE> implements BiPredicate { - private static final GTE INSTANCE = new GTE(); + private static final GTE INSTANCE = new GTE<>(); private GTE() { } @@ -29,7 +29,7 @@ public Boolean apply(A y, A x) { @SuppressWarnings("unchecked") public static > GTE gte() { - return INSTANCE; + return (GTE) INSTANCE; } public static > Predicate gte(A y) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GroupBy.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GroupBy.java index 1ef163a74..1e85a30ab 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GroupBy.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GroupBy.java @@ -22,7 +22,7 @@ */ public final class GroupBy implements Fn2, Iterable, Map>> { - private static final GroupBy INSTANCE = new GroupBy(); + private static final GroupBy INSTANCE = new GroupBy<>(); private GroupBy() { } @@ -37,7 +37,7 @@ public Map> apply(Function keyFn, Iterable @SuppressWarnings("unchecked") public static GroupBy groupBy() { - return INSTANCE; + return (GroupBy) INSTANCE; } public static Fn1, Map>> groupBy(Function keyFn) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/InGroupsOf.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/InGroupsOf.java index da93304c3..410e5745c 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/InGroupsOf.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/InGroupsOf.java @@ -14,7 +14,7 @@ */ public final class InGroupsOf implements Fn2, Iterable>> { - private static final InGroupsOf INSTANCE = new InGroupsOf(); + private static final InGroupsOf INSTANCE = new InGroupsOf<>(); private InGroupsOf() { } @@ -26,7 +26,7 @@ public Iterable> apply(Integer k, Iterable as) { @SuppressWarnings("unchecked") public static InGroupsOf inGroupsOf() { - return INSTANCE; + return (InGroupsOf) INSTANCE; } public static Fn1, Iterable>> inGroupsOf(Integer k) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Intersection.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Intersection.java index 178b7be8c..1a061a471 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Intersection.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Intersection.java @@ -18,7 +18,7 @@ */ public final class Intersection implements Fn2, Iterable, Iterable> { - private static final Intersection INSTANCE = new Intersection(); + private static final Intersection INSTANCE = new Intersection<>(); private Intersection() { } @@ -30,7 +30,7 @@ public Iterable apply(Iterable xs, Iterable ys) { @SuppressWarnings("unchecked") public static Intersection intersection() { - return INSTANCE; + return (Intersection) INSTANCE; } public static Fn1, Iterable> intersection(Iterable xs) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Intersperse.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Intersperse.java index 68d7bc54d..27c5cf02e 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Intersperse.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Intersperse.java @@ -15,7 +15,7 @@ */ public final class Intersperse implements Fn2, Iterable> { - private static final Intersperse INSTANCE = new Intersperse(); + private static final Intersperse INSTANCE = new Intersperse<>(); private Intersperse() { } @@ -27,7 +27,7 @@ public Iterable apply(A a, Iterable as) { @SuppressWarnings("unchecked") public static Intersperse intersperse() { - return INSTANCE; + return (Intersperse) INSTANCE; } public static Fn1, Iterable> intersperse(A a) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into.java index 5fa399bb1..75e7b4c24 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into.java @@ -16,7 +16,7 @@ */ public final class Into implements Fn2, Map.Entry, C> { - private static final Into INSTANCE = new Into(); + private static final Into INSTANCE = new Into<>(); private Into() { } @@ -28,7 +28,7 @@ public C apply(BiFunction fn, Map.Entry @SuppressWarnings("unchecked") public static Into into() { - return INSTANCE; + return (Into) INSTANCE; } public static Fn1, C> into( diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into1.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into1.java index e965ee544..a230d94b2 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into1.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into1.java @@ -15,7 +15,7 @@ */ public final class Into1 implements Fn2, SingletonHList, B> { - private static final Into1 INSTANCE = new Into1(); + private static final Into1 INSTANCE = new Into1<>(); @Override public B apply(Function fn, SingletonHList singletonHList) { @@ -24,7 +24,7 @@ public B apply(Function fn, SingletonHList singletonH @SuppressWarnings("unchecked") public static Into1 into1() { - return INSTANCE; + return (Into1) INSTANCE; } public static Fn1, B> into1(Function fn) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into3.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into3.java index 9572d3f8d..f9ed9a6cc 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into3.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into3.java @@ -16,7 +16,7 @@ */ public final class Into3 implements Fn2, Product3, D> { - private static final Into3 INSTANCE = new Into3(); + private static final Into3 INSTANCE = new Into3<>(); @Override public D apply(Fn3 fn, Product3 product) { @@ -25,7 +25,7 @@ public D apply(Fn3 fn, Product3 Into3 into3() { - return INSTANCE; + return (Into3) INSTANCE; } public static Fn1, D> into3(Fn3 fn) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into4.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into4.java index 9cd0f37e0..3544516eb 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into4.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into4.java @@ -17,7 +17,7 @@ */ public final class Into4 implements Fn2, Product4, E> { - private static final Into4 INSTANCE = new Into4(); + private static final Into4 INSTANCE = new Into4<>(); @Override public E apply(Fn4 fn, Product4 product) { @@ -26,7 +26,7 @@ public E apply(Fn4 fn, @SuppressWarnings("unchecked") public static Into4 into4() { - return INSTANCE; + return (Into4) INSTANCE; } public static Fn1, E> into4( diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into5.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into5.java index a55294f10..e59852f62 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into5.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into5.java @@ -18,7 +18,7 @@ */ public final class Into5 implements Fn2, Product5, F> { - private static final Into5 INSTANCE = new Into5(); + private static final Into5 INSTANCE = new Into5<>(); @Override public F apply(Fn5 fn, @@ -28,7 +28,7 @@ public F apply(Fn5 Into5 into5() { - return INSTANCE; + return (Into5) INSTANCE; } public static Fn1, F> into5( diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into6.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into6.java index 9caf25a5b..1b4180688 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into6.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into6.java @@ -20,7 +20,7 @@ */ public final class Into6 implements Fn2, Product6, G> { - private static final Into6 INSTANCE = new Into6(); + private static final Into6 INSTANCE = new Into6<>(); @Override public G apply(Fn6 fn, @@ -30,7 +30,7 @@ public G apply(Fn6 Into6 into6() { - return INSTANCE; + return (Into6) INSTANCE; } public static Fn1, G> into6( diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into7.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into7.java index 3ea4d0ebd..fe4b0d7e4 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into7.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into7.java @@ -21,7 +21,7 @@ */ public final class Into7 implements Fn2, Product7, H> { - private static final Into7 INSTANCE = new Into7(); + private static final Into7 INSTANCE = new Into7<>(); @Override public H apply(Fn7 fn, @@ -31,7 +31,7 @@ public H apply(Fn7 Into7 into7() { - return INSTANCE; + return (Into7) INSTANCE; } public static Fn1, H> into7( diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into8.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into8.java index a04d17660..d41c7ff75 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into8.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into8.java @@ -22,7 +22,7 @@ */ public final class Into8 implements Fn2, Product8, I> { - private static final Into8 INSTANCE = new Into8(); + private static final Into8 INSTANCE = new Into8<>(); @Override public I apply( @@ -33,7 +33,7 @@ public I apply( @SuppressWarnings("unchecked") public static Into8 into8() { - return INSTANCE; + return (Into8) INSTANCE; } public static Fn1, I> into8( diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Iterate.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Iterate.java index d948bb12f..596bea845 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Iterate.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Iterate.java @@ -18,7 +18,7 @@ */ public final class Iterate implements Fn2, A, Iterable> { - private static final Iterate INSTANCE = new Iterate(); + private static final Iterate INSTANCE = new Iterate<>(); private Iterate() { } @@ -30,7 +30,7 @@ public Iterable apply(Function fn, A seed) { @SuppressWarnings("unchecked") public static Iterate iterate() { - return INSTANCE; + return (Iterate) INSTANCE; } public static Fn1> iterate(Function fn) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LT.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LT.java index 68f9fe1b2..b5ccf4e23 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LT.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LT.java @@ -17,7 +17,7 @@ */ public final class LT> implements BiPredicate { - private static final LT INSTANCE = new LT(); + private static final LT INSTANCE = new LT<>(); private LT() { } @@ -29,7 +29,7 @@ public Boolean apply(A y, A x) { @SuppressWarnings("unchecked") public static > LT lt() { - return INSTANCE; + return (LT) INSTANCE; } public static > Predicate lt(A y) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LTE.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LTE.java index 72bdc97ad..4287229c2 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LTE.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LTE.java @@ -17,7 +17,7 @@ */ public final class LTE> implements BiPredicate { - private static final LTE INSTANCE = new LTE(); + private static final LTE INSTANCE = new LTE<>(); private LTE() { } @@ -29,7 +29,7 @@ public Boolean apply(A y, A x) { @SuppressWarnings("unchecked") public static > LTE lte() { - return INSTANCE; + return (LTE) INSTANCE; } public static > Predicate lte(A y) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/MagnetizeBy.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/MagnetizeBy.java index ef94c372a..686c521b0 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/MagnetizeBy.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/MagnetizeBy.java @@ -27,7 +27,7 @@ */ public final class MagnetizeBy implements Fn2, Iterable, Iterable>> { - private static final MagnetizeBy INSTANCE = new MagnetizeBy(); + private static final MagnetizeBy INSTANCE = new MagnetizeBy<>(); private MagnetizeBy() { } @@ -45,7 +45,7 @@ public Iterable> apply(BiFunction MagnetizeBy magnetizeBy() { - return INSTANCE; + return (MagnetizeBy) INSTANCE; } public static Fn1, Iterable>> magnetizeBy( diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Map.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Map.java index 2b48c2a07..bc0085cf7 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Map.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Map.java @@ -15,7 +15,7 @@ */ public final class Map implements Fn2, Iterable, Iterable> { - private static final Map INSTANCE = new Map(); + private static final Map INSTANCE = new Map<>(); private Map() { } @@ -27,7 +27,7 @@ public Iterable apply(Function fn, Iterable as) { @SuppressWarnings("unchecked") public static Map map() { - return INSTANCE; + return (Map) INSTANCE; } public static Fn1, Iterable> map(Function fn) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partial2.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partial2.java index 2c2317470..4a02e0ed5 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partial2.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partial2.java @@ -16,7 +16,7 @@ */ public final class Partial2 implements Fn2, A, Fn1> { - private static final Partial2 INSTANCE = new Partial2(); + private static final Partial2 INSTANCE = new Partial2<>(); private Partial2() { } @@ -28,7 +28,7 @@ public Fn1 apply(BiFunction fn, A a) { @SuppressWarnings("unchecked") public static Partial2, A, Fn1> partial2() { - return INSTANCE; + return (Partial2, A, Fn1>) INSTANCE; } public static Fn1> partial2(BiFunction fn) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partial3.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partial3.java index 8473a356b..df9b804a5 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partial3.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partial3.java @@ -16,7 +16,7 @@ */ public final class Partial3 implements Fn2, A, Fn2> { - private static final Partial3 INSTANCE = new Partial3(); + private static final Partial3 INSTANCE = new Partial3<>(); private Partial3() { } @@ -28,7 +28,7 @@ public Fn2 apply(Fn3 fn, A a) { @SuppressWarnings("unchecked") public static Partial3 partial3() { - return INSTANCE; + return (Partial3) INSTANCE; } public static Fn1> partial3(Fn3 fn) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partition.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partition.java index 5a9a17148..368dfb0bb 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partition.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partition.java @@ -26,7 +26,7 @@ */ public final class Partition implements Fn2>, Iterable, Tuple2, Iterable>> { - private static final Partition INSTANCE = new Partition(); + private static final Partition INSTANCE = new Partition<>(); private Partition() { } @@ -42,7 +42,7 @@ public Tuple2, Iterable> apply(Function Partition partition() { - return INSTANCE; + return (Partition) INSTANCE; } public static Fn1, Tuple2, Iterable>> partition( diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek.java index 59ee59cda..bd86c6856 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek.java @@ -15,7 +15,7 @@ * @param the functor type */ public final class Peek> implements Fn2, FA, FA> { - private static final Peek INSTANCE = new Peek<>(); + private static final Peek INSTANCE = new Peek<>(); private Peek() { } @@ -31,7 +31,7 @@ public FA apply(Consumer consumer, FA fa) { @SuppressWarnings("unchecked") public static > Peek peek() { - return INSTANCE; + return (Peek) INSTANCE; } public static > Fn1 peek(Consumer consumer) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek2.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek2.java index d544ac7d7..e228293e5 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek2.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek2.java @@ -19,7 +19,7 @@ * @param the bifunctor type */ public final class Peek2> implements Fn3, Consumer, FAB, FAB> { - private static final Peek2 INSTANCE = new Peek2<>(); + private static final Peek2 INSTANCE = new Peek2<>(); private Peek2() { } @@ -38,7 +38,7 @@ public FAB apply(Consumer aConsumer, Consumer bConsumer, F @SuppressWarnings("unchecked") public static > Peek2 peek2() { - return INSTANCE; + return (Peek2) INSTANCE; } public static > Fn2, FAB, FAB> peek2( diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/PrependAll.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/PrependAll.java index 4c7f26f2a..94ebd2c78 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/PrependAll.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/PrependAll.java @@ -13,7 +13,7 @@ */ public final class PrependAll implements Fn2, Iterable> { - private static final PrependAll INSTANCE = new PrependAll(); + private static final PrependAll INSTANCE = new PrependAll<>(); private PrependAll() { } @@ -25,7 +25,7 @@ public Iterable apply(A a, Iterable as) { @SuppressWarnings("unchecked") public static PrependAll prependAll() { - return INSTANCE; + return (PrependAll) INSTANCE; } public static Fn1, Iterable> prependAll(A a) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ReduceLeft.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ReduceLeft.java index c25b988a4..150206f61 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ReduceLeft.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ReduceLeft.java @@ -27,7 +27,7 @@ */ public final class ReduceLeft implements Fn2, Iterable, Maybe> { - private static final ReduceLeft INSTANCE = new ReduceLeft(); + private static final ReduceLeft INSTANCE = new ReduceLeft<>(); private ReduceLeft() { } @@ -40,7 +40,7 @@ public Maybe apply(BiFunction fn, Iterable @SuppressWarnings("unchecked") public static ReduceLeft reduceLeft() { - return INSTANCE; + return (ReduceLeft) INSTANCE; } public static Fn1, Maybe> reduceLeft(BiFunction fn) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ReduceRight.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ReduceRight.java index 432ac0f56..14a39b20a 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ReduceRight.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ReduceRight.java @@ -25,7 +25,7 @@ */ public final class ReduceRight implements Fn2, Iterable, Maybe> { - private static final ReduceRight INSTANCE = new ReduceRight(); + private static final ReduceRight INSTANCE = new ReduceRight<>(); private ReduceRight() { } @@ -37,7 +37,7 @@ public final Maybe apply(BiFunction fn, It @SuppressWarnings("unchecked") public static ReduceRight reduceRight() { - return INSTANCE; + return (ReduceRight) INSTANCE; } public static Fn1, Maybe> reduceRight(BiFunction fn) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Replicate.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Replicate.java index d810f4938..c310ae8ec 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Replicate.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Replicate.java @@ -13,7 +13,7 @@ */ public final class Replicate implements Fn2> { - private static final Replicate INSTANCE = new Replicate(); + private static final Replicate INSTANCE = new Replicate<>(); private Replicate() { } @@ -25,7 +25,7 @@ public Iterable apply(Integer n, A a) { @SuppressWarnings("unchecked") public static Replicate replicate() { - return INSTANCE; + return (Replicate) INSTANCE; } public static Fn1> replicate(Integer n) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Sequence.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Sequence.java index 36b394970..fffe9b580 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Sequence.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Sequence.java @@ -30,13 +30,13 @@ * @param the concrete parametrized output Applicative type * @param the concrete parametrized input Traversable type */ -public final class Sequence, Trav extends Traversable, AppA extends Applicative, TravA extends Traversable, AppTrav extends Applicative, TravApp extends Traversable> implements Fn2, AppTrav> { - private static final Sequence INSTANCE = new Sequence(); + private static final Sequence INSTANCE = new Sequence<>(); private Sequence() { } @@ -47,15 +47,15 @@ public AppTrav apply(TravApp traversable, Function pur } @SuppressWarnings("unchecked") - public static , Trav extends Traversable, AppA extends Applicative, TravA extends Traversable, AppTrav extends Applicative, TravApp extends Traversable> Sequence sequence() { - return INSTANCE; + return (Sequence) INSTANCE; } - public static , Trav extends Traversable, AppA extends Applicative, TravA extends Traversable, AppTrav extends Applicative, @@ -64,7 +64,7 @@ TravApp extends Traversable> Sequencesequence().apply(traversable); } - public static , Trav extends Traversable, TravA extends Traversable, AppA extends Applicative, AppTrav extends Applicative, @@ -74,27 +74,27 @@ TravApp extends Traversable> AppTrav sequence(TravApp traversable, } @SuppressWarnings({"unchecked", "RedundantTypeArguments"}) - public static , AppIterable extends Applicative, App>, IterableApp extends Iterable> + public static , AppA extends Applicative, AppIterable extends Applicative, App>, IterableApp extends Iterable> Fn1, ? extends AppIterable>, AppIterable> sequence(IterableApp iterableApp) { - return pure -> (AppIterable) Sequence., AppA, Applicative, App>, LambdaIterable>sequence( + return pure -> (AppIterable) Sequence., LambdaIterable, AppA, Applicative, App>, LambdaIterable>sequence( LambdaIterable.wrap(iterableApp), x -> pure.apply(x.unwrap()).fmap(LambdaIterable::wrap)) .fmap(LambdaIterable::unwrap); } - public static , AppIterable extends Applicative, App>, IterableApp extends Iterable> + public static , AppA extends Applicative, AppIterable extends Applicative, App>, IterableApp extends Iterable> AppIterable sequence(IterableApp iterableApp, Function, ? extends AppIterable> pure) { return Sequence.sequence(iterableApp).apply(pure); } @SuppressWarnings({"unchecked", "RedundantTypeArguments"}) - public static , AppMap extends Applicative, App>, MapApp extends Map> + public static , AppB extends Applicative, AppMap extends Applicative, App>, MapApp extends Map> Fn1, ? extends AppMap>, AppMap> sequence(MapApp mapApp) { return pure -> (AppMap) Sequence., LambdaMap, AppB, Applicative, App>, LambdaMap>sequence( LambdaMap.wrap(mapApp), x -> pure.apply(x.unwrap()).fmap(LambdaMap::wrap)) .fmap(LambdaMap::unwrap); } - public static , AppMap extends Applicative, App>, MapApp extends Map> + public static , AppB extends Applicative, AppMap extends Applicative, App>, MapApp extends Map> AppMap sequence(MapApp mapApp, Function, ? extends AppMap> pure) { return Sequence.sequence(mapApp).apply(pure); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Slide.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Slide.java index 337d59788..caec56faa 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Slide.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Slide.java @@ -21,7 +21,7 @@ */ public final class Slide implements Fn2, Iterable>> { - private static final Slide INSTANCE = new Slide<>(); + private static final Slide INSTANCE = new Slide<>(); private Slide() { } @@ -36,7 +36,7 @@ public Iterable> apply(Integer k, Iterable as) { @SuppressWarnings("unchecked") public static Slide slide() { - return INSTANCE; + return (Slide) INSTANCE; } public static Fn1, Iterable>> slide(Integer k) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Snoc.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Snoc.java index 6437c0c57..dbf151ab5 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Snoc.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Snoc.java @@ -15,7 +15,7 @@ */ public final class Snoc implements Fn2, Iterable> { - private static final Snoc INSTANCE = new Snoc(); + private static final Snoc INSTANCE = new Snoc<>(); private Snoc() { } @@ -27,7 +27,7 @@ public Iterable apply(A a, Iterable as) { @SuppressWarnings("unchecked") public static Snoc snoc() { - return INSTANCE; + return (Snoc) INSTANCE; } public static Fn1, Iterable> snoc(A a) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/SortBy.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/SortBy.java index b92628141..a5c52ed58 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/SortBy.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/SortBy.java @@ -22,7 +22,7 @@ */ public final class SortBy> implements Fn2, Iterable, List> { - private static final SortBy INSTANCE = new SortBy(); + private static final SortBy INSTANCE = new SortBy<>(); private SortBy() { } @@ -34,7 +34,7 @@ public List apply(Function fn, Iterable as) { @SuppressWarnings("unchecked") public static > SortBy sortBy() { - return INSTANCE; + return (SortBy) INSTANCE; } public static > Fn1, List> sortBy( diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/SortWith.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/SortWith.java index 813fb2e53..4062d3ebe 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/SortWith.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/SortWith.java @@ -21,7 +21,7 @@ */ public final class SortWith implements Fn2, Iterable, List> { - private static final SortWith INSTANCE = new SortWith(); + private static final SortWith INSTANCE = new SortWith<>(); private SortWith() { } @@ -35,7 +35,7 @@ public List apply(Comparator comparator, Iterable as) { @SuppressWarnings("unchecked") public static SortWith sortWith() { - return INSTANCE; + return (SortWith) INSTANCE; } public static Fn1, List> sortWith(Comparator comparator) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Span.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Span.java index aea792d08..3450a9c49 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Span.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Span.java @@ -17,7 +17,7 @@ */ public final class Span implements Fn2, Iterable, Tuple2, Iterable>> { - private static final Span INSTANCE = new Span(); + private static final Span INSTANCE = new Span<>(); private Span() { } @@ -29,7 +29,7 @@ public Tuple2, Iterable> apply(Function Span span() { - return INSTANCE; + return (Span) INSTANCE; } public static Fn1, Tuple2, Iterable>> span( diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Take.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Take.java index ed10f75bc..86c417a6d 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Take.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Take.java @@ -15,7 +15,7 @@ */ public final class Take implements Fn2, Iterable> { - private static final Take INSTANCE = new Take(); + private static final Take INSTANCE = new Take<>(); private Take() { } @@ -27,7 +27,7 @@ public Iterable apply(Integer n, Iterable as) { @SuppressWarnings("unchecked") public static Take take() { - return INSTANCE; + return (Take) INSTANCE; } public static Fn1, Iterable> take(int n) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/TakeWhile.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/TakeWhile.java index 8285d953c..29863e2bc 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/TakeWhile.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/TakeWhile.java @@ -17,7 +17,7 @@ */ public final class TakeWhile implements Fn2, Iterable, Iterable> { - private static final TakeWhile INSTANCE = new TakeWhile(); + private static final TakeWhile INSTANCE = new TakeWhile<>(); private TakeWhile() { } @@ -29,7 +29,7 @@ public Iterable apply(Function predicate, Itera @SuppressWarnings("unchecked") public static TakeWhile takeWhile() { - return INSTANCE; + return (TakeWhile) INSTANCE; } public static Fn1, Iterable> takeWhile(Function predicate) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToArray.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToArray.java index e12ae85b1..4b41af1b8 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToArray.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToArray.java @@ -16,7 +16,7 @@ */ public final class ToArray implements Fn2, Iterable, A[]> { - private static final ToArray INSTANCE = new ToArray<>(); + private static final ToArray INSTANCE = new ToArray<>(); private ToArray() { } @@ -37,7 +37,7 @@ public A[] apply(Class arrayType, Iterable as) { @SuppressWarnings("unchecked") public static ToArray toArray() { - return INSTANCE; + return (ToArray) INSTANCE; } public static Fn1, A[]> toArray(Class arrayType) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToCollection.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToCollection.java index b9b46b893..545682fb6 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToCollection.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToCollection.java @@ -16,7 +16,7 @@ */ public final class ToCollection> implements Fn2, Iterable, C> { - private static final ToCollection INSTANCE = new ToCollection(); + private static final ToCollection INSTANCE = new ToCollection<>(); private ToCollection() { } @@ -30,7 +30,7 @@ public C apply(Supplier cSupplier, Iterable as) { @SuppressWarnings("unchecked") public static > ToCollection toCollection() { - return INSTANCE; + return (ToCollection) INSTANCE; } public static > Fn1, C> toCollection(Supplier cSupplier) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToMap.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToMap.java index 1522720aa..2b21f5268 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToMap.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToMap.java @@ -19,7 +19,7 @@ */ public final class ToMap> implements Fn2, Iterable>, M> { - private static final ToMap INSTANCE = new ToMap<>(); + private static final ToMap INSTANCE = new ToMap<>(); private ToMap() { } @@ -34,7 +34,7 @@ public M apply(Supplier mSupplier, Iterable> entrie @SuppressWarnings("unchecked") public static > ToMap toMap() { - return INSTANCE; + return (ToMap) INSTANCE; } public static > Fn1>, M> toMap(Supplier mSupplier) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Tupler2.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Tupler2.java index de1b4a283..6b69f4441 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Tupler2.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Tupler2.java @@ -15,7 +15,7 @@ */ public final class Tupler2 implements Fn2> { - private static final Tupler2 INSTANCE = new Tupler2(); + private static final Tupler2 INSTANCE = new Tupler2<>(); private Tupler2() { } @@ -27,7 +27,7 @@ public Tuple2 apply(A a, B b) { @SuppressWarnings("unchecked") public static Tupler2 tupler() { - return INSTANCE; + return (Tupler2) INSTANCE; } public static Fn1> tupler(A a) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Unfoldr.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Unfoldr.java index 9a2cd1b15..efb79a76c 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Unfoldr.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Unfoldr.java @@ -31,7 +31,7 @@ */ public final class Unfoldr implements Fn2>>, B, Iterable> { - private static final Unfoldr INSTANCE = new Unfoldr(); + private static final Unfoldr INSTANCE = new Unfoldr<>(); private Unfoldr() { } @@ -43,7 +43,7 @@ public Iterable apply(Function>> fn, B b) { @SuppressWarnings("unchecked") public static Unfoldr unfoldr() { - return INSTANCE; + return (Unfoldr) INSTANCE; } public static Fn1> unfoldr(Function>> fn) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Zip.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Zip.java index 323f00e02..3e6ba39eb 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Zip.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Zip.java @@ -17,7 +17,7 @@ */ public final class Zip implements Fn2, Iterable, Iterable>> { - private static final Zip INSTANCE = new Zip(); + private static final Zip INSTANCE = new Zip<>(); private Zip() { } @@ -29,7 +29,7 @@ public Iterable> apply(Iterable as, Iterable bs) { @SuppressWarnings("unchecked") public static Zip zip() { - return INSTANCE; + return (Zip) INSTANCE; } public static Fn1, Iterable>> zip(Iterable as) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/Between.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/Between.java index 70dac2bce..451addf5c 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/Between.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/Between.java @@ -14,7 +14,7 @@ */ public final class Between> implements Fn3 { - private static final Between INSTANCE = new Between<>(); + private static final Between INSTANCE = new Between<>(); private Between() { } @@ -26,7 +26,7 @@ public Boolean apply(A lower, A upper, A a) { @SuppressWarnings("unchecked") public static > Between between() { - return INSTANCE; + return (Between) INSTANCE; } public static > BiPredicate between(A lower) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/Clamp.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/Clamp.java index 62d0c21de..20de04a77 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/Clamp.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/Clamp.java @@ -17,7 +17,7 @@ */ public final class Clamp> implements Fn3 { - private static final Clamp INSTANCE = new Clamp<>(); + private static final Clamp INSTANCE = new Clamp<>(); private Clamp() { } @@ -29,7 +29,7 @@ public A apply(A lower, A upper, A a) { @SuppressWarnings("unchecked") public static > Clamp clamp() { - return INSTANCE; + return (Clamp) INSTANCE; } public static > Fn2 clamp(A lower) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/CmpEqBy.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/CmpEqBy.java index 156c51413..5ef1382f7 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/CmpEqBy.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/CmpEqBy.java @@ -20,7 +20,7 @@ */ public final class CmpEqBy> implements Fn3, A, A, Boolean> { - private static final CmpEqBy INSTANCE = new CmpEqBy(); + private static final CmpEqBy INSTANCE = new CmpEqBy<>(); private CmpEqBy() { } @@ -42,7 +42,7 @@ public Predicate apply(Function compareFn, A x) { @SuppressWarnings("unchecked") public static > CmpEqBy cmpEqBy() { - return INSTANCE; + return (CmpEqBy) INSTANCE; } public static > BiPredicate cmpEqBy(Function compareFn) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/FoldLeft.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/FoldLeft.java index 17fb496d1..ec0ad331e 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/FoldLeft.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/FoldLeft.java @@ -22,7 +22,7 @@ */ public final class FoldLeft implements Fn3, B, Iterable, B> { - private static final FoldLeft INSTANCE = new FoldLeft(); + private static final FoldLeft INSTANCE = new FoldLeft<>(); private FoldLeft() { } @@ -37,7 +37,7 @@ public B apply(BiFunction fn, B acc, Iterable @SuppressWarnings("unchecked") public static FoldLeft foldLeft() { - return INSTANCE; + return (FoldLeft) INSTANCE; } public static Fn2, B> foldLeft(BiFunction fn) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/GTBy.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/GTBy.java index d79910faa..6dc2ddef1 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/GTBy.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/GTBy.java @@ -19,7 +19,7 @@ */ public final class GTBy> implements Fn3, A, A, Boolean> { - private static final GTBy INSTANCE = new GTBy(); + private static final GTBy INSTANCE = new GTBy<>(); private GTBy() { } @@ -41,7 +41,7 @@ public Predicate apply(Function compareFn, A x) { @SuppressWarnings("unchecked") public static > GTBy gtBy() { - return INSTANCE; + return (GTBy) INSTANCE; } public static > BiPredicate gtBy(Function fn) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/GTEBy.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/GTEBy.java index f61fcb4c6..830eacb69 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/GTEBy.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/GTEBy.java @@ -22,7 +22,7 @@ */ public final class GTEBy> implements Fn3, A, A, Boolean> { - private static final GTEBy INSTANCE = new GTEBy(); + private static final GTEBy INSTANCE = new GTEBy<>(); private GTEBy() { } @@ -44,7 +44,7 @@ public Predicate apply(Function compareFn, A y) { @SuppressWarnings("unchecked") public static > GTEBy gteBy() { - return INSTANCE; + return (GTEBy) INSTANCE; } public static > BiPredicate gteBy(Function fn) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LTBy.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LTBy.java index 632cc9da0..b09fb69a2 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LTBy.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LTBy.java @@ -19,7 +19,7 @@ */ public final class LTBy> implements Fn3, A, A, Boolean> { - private static final LTBy INSTANCE = new LTBy(); + private static final LTBy INSTANCE = new LTBy<>(); private LTBy() { } @@ -41,7 +41,7 @@ public Predicate apply(Function compareFn, A y) { @SuppressWarnings("unchecked") public static > LTBy ltBy() { - return INSTANCE; + return (LTBy) INSTANCE; } public static > BiPredicate ltBy(Function fn) { 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 c001a8c89..2eb29c7e1 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 @@ -22,7 +22,7 @@ */ public final class LTEBy> implements Fn3, A, A, Boolean> { - private static final LTEBy INSTANCE = new LTEBy(); + private static final LTEBy INSTANCE = new LTEBy<>(); private LTEBy() { } @@ -44,7 +44,7 @@ public Predicate apply(Function compareFn, A y) { @SuppressWarnings("unchecked") public static > LTEBy lteBy() { - return INSTANCE; + return (LTEBy) INSTANCE; } public static > BiPredicate lteBy(Function fn) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LiftA2.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LiftA2.java index 7ba773691..55d58fb6a 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LiftA2.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LiftA2.java @@ -20,12 +20,13 @@ * @param the inferred applicative return type * @see Applicative#zip(Applicative) */ -public final class LiftA2, AppA extends Applicative, AppB extends Applicative, - AppC extends Applicative> implements Fn3, AppA, AppB, AppC> { + AppC extends Applicative> implements + Fn3, AppA, AppB, AppC> { - private static final LiftA2 INSTANCE = new LiftA2(); + private static final LiftA2 INSTANCE = new LiftA2<>(); private LiftA2() { } @@ -36,25 +37,31 @@ public AppC apply(BiFunction fn, AppA appA, A } @SuppressWarnings("unchecked") - public static , AppB extends Applicative, AppC extends Applicative> LiftA2 liftA2() { - return INSTANCE; + public static , AppA extends Applicative, + AppB extends Applicative, + AppC extends Applicative> LiftA2 liftA2() { + return (LiftA2) INSTANCE; } - public static , AppB extends Applicative, AppC extends Applicative> Fn2 liftA2( + public static , AppA extends Applicative, + AppB extends Applicative, + AppC extends Applicative> Fn2 liftA2( BiFunction fn) { return LiftA2.liftA2().apply(fn); } - public static , AppB extends Applicative, AppC extends Applicative> Fn1 liftA2( - BiFunction fn, - AppA appA) { + public static , AppA extends Applicative, + AppB extends Applicative, + AppC extends Applicative> Fn1 liftA2(BiFunction fn, + AppA appA) { return LiftA2.liftA2(fn).apply(appA); } - public static , AppB extends Applicative, AppC extends Applicative> AppC liftA2( - BiFunction fn, - AppA appA, - AppB appB) { + public static , AppA extends Applicative, + AppB extends Applicative, + AppC extends Applicative> AppC liftA2(BiFunction fn, + AppA appA, + AppB appB) { return LiftA2.liftA2(fn, appA).apply(appB); } } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/ScanLeft.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/ScanLeft.java index 9cc780a15..400f1d267 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/ScanLeft.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/ScanLeft.java @@ -20,7 +20,7 @@ */ public final class ScanLeft implements Fn3, B, Iterable, Iterable> { - private static final ScanLeft INSTANCE = new ScanLeft(); + private static final ScanLeft INSTANCE = new ScanLeft<>(); private ScanLeft() { } @@ -32,7 +32,7 @@ public Iterable apply(BiFunction fn, B b, @SuppressWarnings("unchecked") public static ScanLeft scanLeft() { - return INSTANCE; + return (ScanLeft) INSTANCE; } public static Fn2, Iterable> scanLeft(BiFunction fn) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/Times.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/Times.java index cdf33a8d7..a12ab841f 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/Times.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/Times.java @@ -22,7 +22,7 @@ */ public final class Times implements Fn3, A, A> { - private static final Times INSTANCE = new Times(); + private static final Times INSTANCE = new Times<>(); private Times() { } @@ -37,7 +37,7 @@ public A apply(Integer n, Function fn, A a) { @SuppressWarnings("unchecked") public static Times times() { - return INSTANCE; + return (Times) INSTANCE; } public static Fn2, A, A> times(Integer n) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/ZipWith.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/ZipWith.java index 75266b884..4341ca32f 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/ZipWith.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/ZipWith.java @@ -19,7 +19,7 @@ */ public final class ZipWith implements Fn3, Iterable, Iterable, Iterable> { - private static final ZipWith INSTANCE = new ZipWith(); + private static final ZipWith INSTANCE = new ZipWith<>(); private ZipWith() { } @@ -31,7 +31,7 @@ public Iterable apply(BiFunction zipper, I @SuppressWarnings("unchecked") public static ZipWith zipWith() { - return INSTANCE; + return (ZipWith) INSTANCE; } public static Fn2, Iterable, Iterable> zipWith( diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/IfThenElse.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/IfThenElse.java index d67440595..53d40315d 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/IfThenElse.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/IfThenElse.java @@ -9,7 +9,7 @@ public final class IfThenElse implements Fn4, Function, Function, A, B> { - private static final IfThenElse INSTANCE = new IfThenElse(); + private static final IfThenElse INSTANCE = new IfThenElse<>(); private IfThenElse() { } @@ -22,7 +22,7 @@ public B apply(Function predicate, Function IfThenElse ifThenElse() { - return INSTANCE; + return (IfThenElse) INSTANCE; } public static Fn3, Function, A, B> ifThenElse( diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/LiftA3.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/LiftA3.java index a34a1aaae..43c9bc018 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/LiftA3.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/LiftA3.java @@ -22,13 +22,13 @@ * @see Applicative#zip(Applicative) */ public final class LiftA3, AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, AppD extends Applicative> implements Fn4, AppA, AppB, AppC, AppD> { - private static final LiftA3 INSTANCE = new LiftA3(); + private static final LiftA3 INSTANCE = new LiftA3<>(); private LiftA3() { } @@ -40,16 +40,16 @@ public AppD apply(Fn3 fn, AppA appA, AppB appB, AppC appC) { @SuppressWarnings("unchecked") public static , AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, AppD extends Applicative> LiftA3 liftA3() { - return INSTANCE; + return (LiftA3) INSTANCE; } public static , AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, @@ -58,7 +58,7 @@ AppD extends Applicative> Fn3 liftA3(Fn3, AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, @@ -67,7 +67,7 @@ AppD extends Applicative> Fn2 liftA3(Fn3 f } public static , AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, @@ -76,7 +76,7 @@ AppD extends Applicative> Fn1 liftA3(Fn3 fn, App } public static , AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/RateLimit.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/RateLimit.java index 4c7ad843e..970b61dfb 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/RateLimit.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/RateLimit.java @@ -47,7 +47,7 @@ */ public final class RateLimit implements Fn4, Long, Duration, Iterable, Iterable> { - private static final RateLimit INSTANCE = new RateLimit(); + private static final RateLimit INSTANCE = new RateLimit<>(); private RateLimit() { } @@ -62,7 +62,7 @@ public Iterable apply(Supplier instantSupplier, Long limit, Duration @SuppressWarnings("unchecked") public static RateLimit rateLimit() { - return INSTANCE; + return (RateLimit) INSTANCE; } public static Fn3, Iterable> rateLimit(Supplier instantSupplier) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn5/LiftA4.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn5/LiftA4.java index 099d519ca..1187aa320 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn5/LiftA4.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn5/LiftA4.java @@ -25,14 +25,14 @@ * @see Applicative#zip(Applicative) */ public final class LiftA4, AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, AppD extends Applicative, AppE extends Applicative> implements Fn5, AppA, AppB, AppC, AppD, AppE> { - private static final LiftA4 INSTANCE = new LiftA4(); + private static final LiftA4 INSTANCE = new LiftA4<>(); private LiftA4() { } @@ -44,17 +44,17 @@ public AppE apply(Fn4 fn, AppA appA, AppB appB, AppC appC, AppD a @SuppressWarnings("unchecked") public static , AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, AppD extends Applicative, AppE extends Applicative> LiftA4 liftA4() { - return INSTANCE; + return (LiftA4) INSTANCE; } public static , AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, @@ -64,7 +64,7 @@ AppE extends Applicative> Fn4 liftA4(Fn4, AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, @@ -74,7 +74,7 @@ AppE extends Applicative> Fn3 liftA4(Fn4, AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, @@ -85,7 +85,7 @@ AppE extends Applicative> Fn2 liftA4(Fn4, AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, @@ -96,7 +96,7 @@ AppE extends Applicative> Fn1 liftA4(Fn4 fn, } public static , AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn6/LiftA5.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn6/LiftA5.java index f32d44569..24d83bca2 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn6/LiftA5.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn6/LiftA5.java @@ -28,7 +28,7 @@ * @see Applicative#zip(Applicative) */ public final class LiftA5, AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, @@ -36,7 +36,7 @@ public final class LiftA5, AppF extends Applicative> implements Fn6, AppA, AppB, AppC, AppD, AppE, AppF> { - private static final LiftA5 INSTANCE = new LiftA5(); + private static final LiftA5 INSTANCE = new LiftA5<>(); private LiftA5() { } @@ -48,18 +48,18 @@ public AppF apply(Fn5 fn, AppA appA, AppB appB, AppC appC, App @SuppressWarnings("unchecked") public static , AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, AppD extends Applicative, AppE extends Applicative, AppF extends Applicative> LiftA5 liftA5() { - return INSTANCE; + return (LiftA5) INSTANCE; } public static , AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, @@ -70,7 +70,7 @@ AppF extends Applicative> Fn5 liftA5 } public static , AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, @@ -82,7 +82,7 @@ AppF extends Applicative> Fn4 liftA5(Fn5, AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, @@ -94,7 +94,7 @@ AppF extends Applicative> Fn3 liftA5(Fn5, AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, @@ -107,7 +107,7 @@ AppF extends Applicative> Fn2 liftA5(Fn5, AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, @@ -119,7 +119,7 @@ AppF extends Applicative> Fn1 liftA5(Fn5 f } public static , AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn7/LiftA6.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn7/LiftA6.java index 72da45314..804fb7b99 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn7/LiftA6.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn7/LiftA6.java @@ -31,16 +31,17 @@ * @see Applicative#zip(Applicative) */ public final class LiftA6, AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, AppD extends Applicative, AppE extends Applicative, AppF extends Applicative, - AppG extends Applicative> implements Fn7, AppA, AppB, AppC, AppD, AppE, AppF, AppG> { + AppG extends Applicative> implements + Fn7, AppA, AppB, AppC, AppD, AppE, AppF, AppG> { - private static final LiftA6 INSTANCE = new LiftA6(); + private static final LiftA6 INSTANCE = new LiftA6<>(); private LiftA6() { } @@ -54,19 +55,20 @@ public AppG apply(Fn6 fn, AppA appA, AppB appB, AppC appC, @SuppressWarnings("unchecked") public static , AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, AppD extends Applicative, AppE extends Applicative, AppF extends Applicative, - AppG extends Applicative> LiftA6 liftA6() { - return INSTANCE; + AppG extends Applicative> + LiftA6 liftA6() { + return (LiftA6) INSTANCE; } public static , AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, @@ -79,7 +81,7 @@ AppG extends Applicative> Fn6 } public static , AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, @@ -93,7 +95,7 @@ AppG extends Applicative> Fn5 liftA6 } public static , AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, @@ -107,7 +109,7 @@ AppG extends Applicative> Fn4 liftA6(Fn6, AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, @@ -121,7 +123,7 @@ AppG extends Applicative> Fn3 liftA6(Fn6, AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, @@ -135,7 +137,7 @@ AppG extends Applicative> Fn2 liftA6(Fn6, AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, @@ -148,7 +150,7 @@ AppG extends Applicative> Fn1 liftA6(Fn6, AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn8/LiftA7.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn8/LiftA7.java index 6d508f06d..359801ba7 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn8/LiftA7.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn8/LiftA7.java @@ -34,7 +34,7 @@ * @see Applicative#zip(Applicative) */ public final class LiftA7, AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, @@ -44,7 +44,7 @@ public final class LiftA7, AppH extends Applicative> implements Fn8, AppA, AppB, AppC, AppD, AppE, AppF, AppG, AppH> { - private static final LiftA7 INSTANCE = new LiftA7(); + private static final LiftA7 INSTANCE = new LiftA7<>(); private LiftA7() { } @@ -57,7 +57,7 @@ public AppH apply(Fn7 fn, AppA appA, AppB appB, AppC app @SuppressWarnings("unchecked") public static , AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, @@ -66,11 +66,11 @@ public AppH apply(Fn7 fn, AppA appA, AppB appB, AppC app AppF extends Applicative, AppG extends Applicative, AppH extends Applicative> LiftA7 liftA7() { - return INSTANCE; + return (LiftA7) INSTANCE; } public static , AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, @@ -84,7 +84,7 @@ AppH extends Applicative> Fn7, AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, @@ -98,7 +98,7 @@ AppH extends Applicative> Fn6 } public static , AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, @@ -112,7 +112,7 @@ AppH extends Applicative> Fn5 liftA7 } public static , AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, @@ -127,7 +127,7 @@ AppH extends Applicative> Fn4 liftA7(Fn7, AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, @@ -142,7 +142,7 @@ AppH extends Applicative> Fn3 liftA7(Fn7, AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, @@ -156,7 +156,7 @@ AppH extends Applicative> Fn2 liftA7(Fn7, AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, @@ -171,7 +171,7 @@ AppH extends Applicative> Fn1 liftA7(Fn7, AppA extends Applicative, AppB extends Applicative, AppC extends Applicative, diff --git a/src/main/java/com/jnape/palatable/lambda/functions/recursion/RecursiveResult.java b/src/main/java/com/jnape/palatable/lambda/functions/recursion/RecursiveResult.java index 7da780a1e..afef70f6d 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/recursion/RecursiveResult.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/recursion/RecursiveResult.java @@ -80,9 +80,12 @@ public RecursiveResult discardR(Applicative> @Override @SuppressWarnings("unchecked") - public >, AppB extends Applicative, AppTrav extends Applicative> AppTrav traverse( - Function fn, Function pure) { - return match(__ -> pure.apply(coerce()), b -> fn.apply(b).fmap(this::pure).fmap(Applicative::coerce).coerce()); + public , TravB extends Traversable>, + AppB extends Applicative, + AppTrav extends Applicative> AppTrav traverse(Function fn, + Function pure) { + return match(__ -> pure.apply(coerce()), + b -> fn.apply(b).fmap(this::pure).fmap(RecursiveResult::coerce).coerce()); } public static RecursiveResult recurse(A a) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/recursion/Trampoline.java b/src/main/java/com/jnape/palatable/lambda/functions/recursion/Trampoline.java index a4efb94cc..2d52b95d1 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/recursion/Trampoline.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/recursion/Trampoline.java @@ -22,7 +22,7 @@ */ public final class Trampoline implements Fn2>, A, B> { - private static final Trampoline INSTANCE = new Trampoline<>(); + private static final Trampoline INSTANCE = new Trampoline<>(); @Override public B apply(Function> fn, A a) { @@ -34,7 +34,7 @@ public B apply(Function> fn, A a) { @SuppressWarnings("unchecked") public static Trampoline trampoline() { - return INSTANCE; + return (Trampoline) INSTANCE; } public static Fn1 trampoline(Function> fn) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/Kleisli.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/Kleisli.java index 433ef410f..9157c8e44 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/Kleisli.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/specialized/Kleisli.java @@ -15,7 +15,7 @@ * @param the output {@link Monad} type */ @FunctionalInterface -public interface Kleisli> extends Fn1 { +public interface Kleisli, MB extends Monad> extends Fn1 { /** * Left-to-right composition of two compatible {@link Kleisli} arrows, yielding a new {@link Kleisli} arrow. @@ -83,7 +83,7 @@ default Kleisli diMapL(Function fn) { * @param the returned {@link Monad} instance * @return the function adapted as a {@link Kleisli} arrow */ - static > Kleisli kleisli( + static , MB extends Monad> Kleisli kleisli( Function fn) { return fn::apply; } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/Noop.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/Noop.java index 62c5192f4..509499536 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/Noop.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/specialized/Noop.java @@ -8,7 +8,7 @@ * @param the argument type */ public final class Noop implements Effect { - private static final Noop INSTANCE = new Noop(); + private static final Noop INSTANCE = new Noop<>(); private Noop() { } @@ -25,6 +25,6 @@ public void accept(A a) { */ @SuppressWarnings("unchecked") public static Noop noop() { - return INSTANCE; + return (Noop) INSTANCE; } } diff --git a/src/main/java/com/jnape/palatable/lambda/functor/Applicative.java b/src/main/java/com/jnape/palatable/lambda/functor/Applicative.java index 180d55c80..1f31e2ff3 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/Applicative.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/Applicative.java @@ -28,7 +28,7 @@ * @param The type of the parameter * @param The unification parameter to more tightly type-constrain Applicatives to themselves */ -public interface Applicative extends Functor { +public interface Applicative> extends Functor { /** * Lift the value b into this applicative functor. @@ -100,7 +100,7 @@ default Applicative discardR(Applicative appB) { * @param the concrete applicative instance to coerce this applicative to * @return the coerced applicative */ - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked"}) default > Concrete coerce() { return (Concrete) this; } diff --git a/src/main/java/com/jnape/palatable/lambda/functor/Bifunctor.java b/src/main/java/com/jnape/palatable/lambda/functor/Bifunctor.java index 695c71a8f..abdbd7024 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/Bifunctor.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/Bifunctor.java @@ -17,7 +17,7 @@ * @see com.jnape.palatable.lambda.adt.hlist.Tuple2 */ @FunctionalInterface -public interface Bifunctor extends BoundedBifunctor { +public interface Bifunctor> extends BoundedBifunctor { /** * Covariantly map over the left parameter. diff --git a/src/main/java/com/jnape/palatable/lambda/functor/BoundedBifunctor.java b/src/main/java/com/jnape/palatable/lambda/functor/BoundedBifunctor.java index 02fc7775f..8096ae1cb 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/BoundedBifunctor.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/BoundedBifunctor.java @@ -16,7 +16,12 @@ * @see Bifunctor */ @FunctionalInterface -public interface BoundedBifunctor { +public interface BoundedBifunctor< + A extends ContraA, + B extends ContraB, + ContraA, + ContraB, + BF extends BoundedBifunctor> { /** * Covariantly map the left parameter into a value that is covariant to ContraA. diff --git a/src/main/java/com/jnape/palatable/lambda/functor/Contravariant.java b/src/main/java/com/jnape/palatable/lambda/functor/Contravariant.java index 07d548d1a..bce1d114a 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/Contravariant.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/Contravariant.java @@ -14,7 +14,7 @@ * @param the unification parameter * @see Profunctor */ -public interface Contravariant { +public interface Contravariant> { /** * Contravariantly map A <- B. diff --git a/src/main/java/com/jnape/palatable/lambda/functor/Functor.java b/src/main/java/com/jnape/palatable/lambda/functor/Functor.java index 769aae816..7645f1013 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/Functor.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/Functor.java @@ -20,7 +20,7 @@ * @see com.jnape.palatable.lambda.adt.Either */ @FunctionalInterface -public interface Functor { +public interface Functor> { /** * Covariantly transmute this functor's parameter using the given mapping function. Generally this method is diff --git a/src/main/java/com/jnape/palatable/lambda/functor/Profunctor.java b/src/main/java/com/jnape/palatable/lambda/functor/Profunctor.java index 0e7235b44..865f2e2d5 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/Profunctor.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/Profunctor.java @@ -22,7 +22,7 @@ * @see Lens */ @FunctionalInterface -public interface Profunctor extends Contravariant> { +public interface Profunctor> extends Contravariant> { /** * Dually map contravariantly over the left parameter and covariantly over the right parameter. This is isomorphic diff --git a/src/main/java/com/jnape/palatable/lambda/functor/Strong.java b/src/main/java/com/jnape/palatable/lambda/functor/Strong.java index c6b4929c2..0be4c230d 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/Strong.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/Strong.java @@ -13,7 +13,7 @@ * @param the unification parameter * @see com.jnape.palatable.lambda.functions.Fn1 */ -public interface Strong extends Profunctor { +public interface Strong> extends Profunctor { /** * Pair some type C to this profunctor's carrier types. diff --git a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Compose.java b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Compose.java index 965567501..5a08211dc 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Compose.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Compose.java @@ -13,7 +13,8 @@ * @param The inner applicative * @param The carrier type */ -public final class Compose implements Applicative> { +public final class Compose, G extends Applicative, A> implements + Applicative> { private final Applicative, F> fga; diff --git a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Const.java b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Const.java index 6ef443106..fdb81f8ef 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Const.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Const.java @@ -17,7 +17,10 @@ * @param the left parameter type, and the type of the stored value * @param the right (phantom) parameter type */ -public final class Const implements Monad>, Bifunctor, Traversable> { +public final class Const implements + Monad>, + Bifunctor>, + Traversable> { private final A a; @@ -98,8 +101,10 @@ public Const flatMap(Function>, AppB extends Applicative, AppTrav extends Applicative> AppTrav traverse( - Function fn, Function pure) { + public , TravB extends Traversable>, + AppB extends Applicative, + AppTrav extends Applicative> AppTrav traverse(Function fn, + Function pure) { return pure.apply(coerce()); } diff --git a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Identity.java b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Identity.java index d9781e8cc..f5beb02c9 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Identity.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Identity.java @@ -12,7 +12,7 @@ * * @param the value type */ -public final class Identity implements Monad, Traversable { +public final class Identity implements Monad>, Traversable> { private final A a; @@ -33,7 +33,7 @@ public A runIdentity() { * {@inheritDoc} */ @Override - public Identity flatMap(Function> f) { + public Identity flatMap(Function>> f) { return f.apply(runIdentity()).coerce(); } @@ -57,7 +57,7 @@ public Identity pure(B b) { * {@inheritDoc} */ @Override - public Identity zip(Applicative, Identity> appFn) { + public Identity zip(Applicative, Identity> appFn) { return new Identity<>(appFn.>>coerce().runIdentity().apply(a)); } @@ -65,8 +65,7 @@ public Identity zip(Applicative, Identit * {@inheritDoc} */ @Override - public Lazy> lazyZip( - Lazy, Identity>> lazyAppFn) { + public Lazy> lazyZip(Lazy, Identity>> lazyAppFn) { return Monad.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); } @@ -74,7 +73,7 @@ public Lazy> lazyZip( * {@inheritDoc} */ @Override - public Identity discardL(Applicative appB) { + public Identity discardL(Applicative> appB) { return Monad.super.discardL(appB).coerce(); } @@ -82,7 +81,7 @@ public Identity discardL(Applicative appB) { * {@inheritDoc} */ @Override - public Identity discardR(Applicative appB) { + public Identity discardR(Applicative> appB) { return Monad.super.discardR(appB).coerce(); } @@ -91,8 +90,10 @@ public Identity discardR(Applicative appB) { */ @Override @SuppressWarnings("unchecked") - public , AppB extends Applicative, AppTrav extends Applicative> AppTrav traverse( - Function fn, Function pure) { + public , TravB extends Traversable>, + AppB extends Applicative, + AppTrav extends Applicative> AppTrav traverse(Function fn, + Function pure) { return (AppTrav) fn.apply(runIdentity()).fmap(Identity::new); } diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/ImmutableQueue.java b/src/main/java/com/jnape/palatable/lambda/iteration/ImmutableQueue.java index 5a734a88c..c7b109d3b 100644 --- a/src/main/java/com/jnape/palatable/lambda/iteration/ImmutableQueue.java +++ b/src/main/java/com/jnape/palatable/lambda/iteration/ImmutableQueue.java @@ -45,11 +45,11 @@ public A next() { @SuppressWarnings("unchecked") public static ImmutableQueue empty() { - return Empty.INSTANCE; + return (ImmutableQueue) Empty.INSTANCE; } private static final class Empty extends ImmutableQueue { - private static final Empty INSTANCE = new Empty(); + private static final Empty INSTANCE = new Empty<>(); @Override ImmutableQueue pushFront(A a) { diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/ImmutableStack.java b/src/main/java/com/jnape/palatable/lambda/iteration/ImmutableStack.java index 619619efb..e2ca4a8a2 100644 --- a/src/main/java/com/jnape/palatable/lambda/iteration/ImmutableStack.java +++ b/src/main/java/com/jnape/palatable/lambda/iteration/ImmutableStack.java @@ -42,11 +42,11 @@ public A next() { @SuppressWarnings("unchecked") public static ImmutableStack empty() { - return Empty.INSTANCE; + return (ImmutableStack) Empty.INSTANCE; } private static final class Empty extends ImmutableStack { - private static final Empty INSTANCE = new Empty(); + private static final Empty INSTANCE = new Empty<>(); @Override Maybe head() { diff --git a/src/main/java/com/jnape/palatable/lambda/lens/Iso.java b/src/main/java/com/jnape/palatable/lambda/lens/Iso.java index bff042842..7d7be3d3c 100644 --- a/src/main/java/com/jnape/palatable/lambda/lens/Iso.java +++ b/src/main/java/com/jnape/palatable/lambda/lens/Iso.java @@ -52,14 +52,14 @@ @FunctionalInterface public interface Iso extends LensLike { -

, FT extends Functor, +

, F extends Functor, FB extends Functor, FT extends Functor, PAFB extends Profunctor, PSFT extends Profunctor> PSFT apply(PAFB pafb); @Override - default , FB extends Functor> FT apply( + default , FT extends Functor, FB extends Functor> FT apply( Function fn, S s) { - return this., Fn1>apply(fn1(fn)).apply(s); + return this., F, FB, FT, Fn1, Fn1>apply(fn1(fn)).apply(s); } /** @@ -70,7 +70,7 @@ default , FB extends Functor> default Lens toLens() { return new Lens() { @Override - public , FB extends Functor> FT apply( + public , FT extends Functor, FB extends Functor> FT apply( Function fn, S s) { return Iso.this.apply(fn, s); } @@ -93,7 +93,7 @@ default Iso mirror() { * @return the destructured iso */ default Tuple2, Fn1> unIso() { - return Tuple2.fill(this., Identity, Identity, Identity, + return Tuple2.fill(this., Identity, Identity, Identity, Exchange>, Exchange>>apply(new Exchange<>(id(), Identity::new)).diMapR(Identity::runIdentity)) .biMap(e -> fn1(e.sa()), e -> fn1(e.bt())); @@ -226,8 +226,9 @@ static Iso iso(Function f, return new Iso() { @Override @SuppressWarnings("unchecked") - public

, FT extends Functor, PAFB extends Profunctor, PSFT extends Profunctor> PSFT apply( - PAFB pafb) { + public

, F extends Functor, FB extends Functor, + FT extends Functor, PAFB extends Profunctor, + PSFT extends Profunctor> PSFT apply(PAFB pafb) { return (PSFT) pafb.diMap(f, fb -> (FT) fb.fmap(g)); } }; @@ -311,9 +312,14 @@ default Lens.Simple andThen(LensLike.Simple f) { * @param A/B * @return the simple iso */ - @SuppressWarnings("unchecked") static Iso.Simple adapt(Iso iso) { - return iso::apply; + return new Iso.Simple() { + @Override + public

, F extends Functor, FB extends Functor, FT extends Functor, PAFB extends Profunctor, PSFT extends Profunctor> PSFT apply( + PAFB pafb) { + return iso.apply(pafb); + } + }; } } } \ No newline at end of file diff --git a/src/main/java/com/jnape/palatable/lambda/lens/Lens.java b/src/main/java/com/jnape/palatable/lambda/lens/Lens.java index 3f832d351..ba74b982a 100644 --- a/src/main/java/com/jnape/palatable/lambda/lens/Lens.java +++ b/src/main/java/com/jnape/palatable/lambda/lens/Lens.java @@ -246,7 +246,7 @@ static Lens lens(Function gette return new Lens() { @Override @SuppressWarnings("unchecked") - public , FB extends Functor> FT apply( + public , FT extends Functor, FB extends Functor> FT apply( Function fn, S s) { return (FT) fn.apply(getter.apply(s)).fmap(b -> setter.apply(s, b)); @@ -325,9 +325,14 @@ default Lens.Simple andThen(LensLike.Simple f) { * @param A/B * @return the simple lens */ - @SuppressWarnings("unchecked") static Lens.Simple adapt(Lens lens) { - return lens::apply; + return new Lens.Simple() { + @Override + public , FT extends Functor, FB extends Functor> FT apply( + Function fn, S s) { + return lens.apply(fn, s); + } + }; } /** diff --git a/src/main/java/com/jnape/palatable/lambda/lens/LensLike.java b/src/main/java/com/jnape/palatable/lambda/lens/LensLike.java index 5551e172a..4975544ba 100644 --- a/src/main/java/com/jnape/palatable/lambda/lens/LensLike.java +++ b/src/main/java/com/jnape/palatable/lambda/lens/LensLike.java @@ -20,9 +20,11 @@ * @see Lens * @see Iso */ -public interface LensLike extends Monad>, Profunctor> { +public interface LensLike extends + Monad>, + Profunctor> { - , FB extends Functor> FT apply( + , FT extends Functor, FB extends Functor> FT apply( Function fn, S s); /** diff --git a/src/main/java/com/jnape/palatable/lambda/lens/functions/Over.java b/src/main/java/com/jnape/palatable/lambda/lens/functions/Over.java index 5c1de0104..a0c1eaedd 100644 --- a/src/main/java/com/jnape/palatable/lambda/lens/functions/Over.java +++ b/src/main/java/com/jnape/palatable/lambda/lens/functions/Over.java @@ -25,14 +25,16 @@ */ public final class Over implements Fn3, Function, S, T> { - private static final Over INSTANCE = new Over(); + private static final Over INSTANCE = new Over<>(); private Over() { } @Override public T apply(LensLike lens, Function fn, S s) { - return lens., Identity>apply(fn.andThen((Function>) Identity::new), s).runIdentity(); + return lens., Identity, Identity>apply(fn.andThen((Function>) Identity::new), + s) + .runIdentity(); } @SuppressWarnings("unchecked") diff --git a/src/main/java/com/jnape/palatable/lambda/lens/functions/Set.java b/src/main/java/com/jnape/palatable/lambda/lens/functions/Set.java index 07c97b804..cebf0647f 100644 --- a/src/main/java/com/jnape/palatable/lambda/lens/functions/Set.java +++ b/src/main/java/com/jnape/palatable/lambda/lens/functions/Set.java @@ -25,7 +25,7 @@ */ public final class Set implements Fn3, B, S, T> { - private static final Set INSTANCE = new Set(); + private static final Set INSTANCE = new Set<>(); private Set() { } @@ -37,7 +37,7 @@ public T apply(LensLike lens, B b, S s) { @SuppressWarnings("unchecked") public static Set set() { - return INSTANCE; + return (Set) INSTANCE; } public static Fn2 set(LensLike lens) { diff --git a/src/main/java/com/jnape/palatable/lambda/lens/functions/Under.java b/src/main/java/com/jnape/palatable/lambda/lens/functions/Under.java index 11c37a1e5..1bdae90bf 100644 --- a/src/main/java/com/jnape/palatable/lambda/lens/functions/Under.java +++ b/src/main/java/com/jnape/palatable/lambda/lens/functions/Under.java @@ -23,7 +23,7 @@ */ public final class Under implements Fn3, Function, B, A> { - private static final Under INSTANCE = new Under(); + private static final Under INSTANCE = new Under<>(); private Under() { } @@ -35,7 +35,7 @@ public A apply(Iso iso, Function fn, B b) { @SuppressWarnings("unchecked") public static Under under() { - return INSTANCE; + return (Under) INSTANCE; } public static Fn2, B, A> under(Iso iso) { diff --git a/src/main/java/com/jnape/palatable/lambda/lens/functions/View.java b/src/main/java/com/jnape/palatable/lambda/lens/functions/View.java index a6d1cb883..b4df1138d 100644 --- a/src/main/java/com/jnape/palatable/lambda/lens/functions/View.java +++ b/src/main/java/com/jnape/palatable/lambda/lens/functions/View.java @@ -20,7 +20,7 @@ */ public final class View implements Fn2, S, A> { - private static final View INSTANCE = new View(); + private static final View INSTANCE = new View<>(); private View() { } @@ -32,7 +32,7 @@ public A apply(LensLike lens, S s) { @SuppressWarnings("unchecked") public static View view() { - return INSTANCE; + return (View) INSTANCE; } public static Fn1 view(LensLike lens) { diff --git a/src/main/java/com/jnape/palatable/lambda/monad/Monad.java b/src/main/java/com/jnape/palatable/lambda/monad/Monad.java index e56d0ca39..ef1e26a2b 100644 --- a/src/main/java/com/jnape/palatable/lambda/monad/Monad.java +++ b/src/main/java/com/jnape/palatable/lambda/monad/Monad.java @@ -27,7 +27,7 @@ * @param the type of the parameter * @param the unification parameter to more tightly type-constrain Monads to themselves */ -public interface Monad extends Applicative { +public interface Monad> extends Applicative { /** * Chain dependent computations that may continue or short-circuit based on previous results. @@ -65,7 +65,7 @@ default Monad zip(Applicative, M> app */ @Override default Lazy> lazyZip(Lazy, M>> lazyAppFn) { - return Applicative.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); + return Applicative.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); } /** @@ -93,7 +93,7 @@ default Monad discardR(Applicative appB) { * @param the nested monad * @return the nested monad */ - static > MA join(Monad mma) { + static , A, MA extends Monad> MA join(Monad mma) { return mma.flatMap(id()).coerce(); } } \ No newline at end of file diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/AddAll.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/AddAll.java index 6cce48bfd..5b93eac91 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/AddAll.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/AddAll.java @@ -21,7 +21,7 @@ */ public final class AddAll> implements MonoidFactory, C> { - private static final AddAll INSTANCE = new AddAll(); + private static final AddAll INSTANCE = new AddAll<>(); private AddAll() { } @@ -54,7 +54,7 @@ public C foldMap(Function fn, Iterable bs) { @SuppressWarnings("unchecked") public static > AddAll addAll() { - return INSTANCE; + return (AddAll) INSTANCE; } public static > Monoid addAll(Supplier collectionSupplier) { diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Collapse.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Collapse.java index 51cf36970..336e3cf6e 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Collapse.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Collapse.java @@ -23,7 +23,7 @@ */ public final class Collapse<_1, _2> implements BiMonoidFactory, Monoid<_2>, Tuple2<_1, _2>> { - private static final Collapse INSTANCE = new Collapse(); + private static final Collapse INSTANCE = new Collapse<>(); private Collapse() { } @@ -36,7 +36,7 @@ public Monoid> apply(Monoid<_1> _1Monoid, Monoid<_2> _2Monoid) { @SuppressWarnings("unchecked") public static <_1, _2> Collapse<_1, _2> collapse() { - return INSTANCE; + return (Collapse<_1, _2>) INSTANCE; } public static <_1, _2> MonoidFactory, Tuple2<_1, _2>> collapse(Monoid<_1> _1Monoid) { diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Compose.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Compose.java index ca27bb28f..6c9945784 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Compose.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Compose.java @@ -24,7 +24,7 @@ */ public final class Compose implements MonoidFactory, CompletableFuture> { - private static final Compose INSTANCE = new Compose(); + private static final Compose INSTANCE = new Compose<>(); private Compose() { } @@ -37,7 +37,7 @@ public Monoid> apply(Monoid aMonoid) { @SuppressWarnings("unchecked") public static Compose compose() { - return INSTANCE; + return (Compose) INSTANCE; } public static Monoid> compose(Monoid aMonoid) { diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Concat.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Concat.java index 2d164bbdc..dd1ae290e 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Concat.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Concat.java @@ -17,7 +17,7 @@ */ public final class Concat implements Monoid> { - private static final Concat INSTANCE = new Concat(); + private static final Concat INSTANCE = new Concat<>(); private Concat() { } @@ -39,7 +39,7 @@ public Iterable foldMap(Function> fn, It @SuppressWarnings("unchecked") public static Concat concat() { - return INSTANCE; + return (Concat) INSTANCE; } public static Fn1, Iterable> concat(Iterable xs) { diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/First.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/First.java index cb3b65f4c..9d074aaea 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/First.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/First.java @@ -23,7 +23,7 @@ */ public final class First implements Monoid> { - private static final First INSTANCE = new First(); + private static final First INSTANCE = new First<>(); private First() { } @@ -45,7 +45,7 @@ public Maybe foldMap(Function> fn, Iterable @SuppressWarnings("unchecked") public static First first() { - return INSTANCE; + return (First) INSTANCE; } public static Fn1, Maybe> first(Maybe x) { diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Last.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Last.java index bb039c09a..775e6448f 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Last.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Last.java @@ -19,7 +19,7 @@ * @see Maybe */ public final class Last implements Monoid> { - private static final Last INSTANCE = new Last(); + private static final Last INSTANCE = new Last<>(); private Last() { } @@ -36,7 +36,7 @@ public Maybe apply(Maybe x, Maybe y) { @SuppressWarnings("unchecked") public static Last last() { - return INSTANCE; + return (Last) INSTANCE; } public static Fn1, Maybe> last(Maybe x) { diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/LeftAll.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/LeftAll.java index 5026328fb..906a34658 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/LeftAll.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/LeftAll.java @@ -29,7 +29,7 @@ */ public final class LeftAll implements MonoidFactory, Either> { - private static final LeftAll INSTANCE = new LeftAll(); + private static final LeftAll INSTANCE = new LeftAll<>(); private LeftAll() { } @@ -42,7 +42,7 @@ public Monoid> apply(Monoid lMonoid) { @SuppressWarnings("unchecked") public static LeftAll leftAll() { - return INSTANCE; + return (LeftAll) INSTANCE; } public static Monoid> leftAll(Monoid lMonoid) { diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/LeftAny.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/LeftAny.java index a9035d67c..9ba5a8cc7 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/LeftAny.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/LeftAny.java @@ -29,7 +29,7 @@ */ public final class LeftAny implements MonoidFactory, Either> { - private static final LeftAny INSTANCE = new LeftAny(); + private static final LeftAny INSTANCE = new LeftAny<>(); private LeftAny() { } @@ -42,7 +42,7 @@ public Monoid> apply(Monoid lMonoid) { @SuppressWarnings("unchecked") public static LeftAny leftAny() { - return INSTANCE; + return (LeftAny) INSTANCE; } public static Monoid> leftAny(Monoid lMonoid) { diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Merge.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Merge.java index 798b6041a..5b6f7f8df 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Merge.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Merge.java @@ -22,7 +22,7 @@ */ public final class Merge implements BiMonoidFactory, Monoid, Either> { - private static final Merge INSTANCE = new Merge(); + private static final Merge INSTANCE = new Merge<>(); private Merge() { } @@ -35,7 +35,7 @@ public Monoid> apply(Semigroup lSemigroup, Monoid rMonoid) { @SuppressWarnings("unchecked") public static Merge merge() { - return INSTANCE; + return (Merge) INSTANCE; } public static MonoidFactory, Either> merge(Semigroup lSemigroup) { diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/MergeMaps.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/MergeMaps.java index 104d6f7d5..4e5b54ea2 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/MergeMaps.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/MergeMaps.java @@ -21,7 +21,7 @@ */ public final class MergeMaps implements BiMonoidFactory>, Semigroup, Map> { - private static final MergeMaps INSTANCE = new MergeMaps(); + private static final MergeMaps INSTANCE = new MergeMaps<>(); private MergeMaps() { } @@ -38,7 +38,7 @@ public Monoid> apply(Supplier> mSupplier, Semigroup semig @SuppressWarnings("unchecked") public static MergeMaps mergeMaps() { - return INSTANCE; + return (MergeMaps) INSTANCE; } public static MonoidFactory, Map> mergeMaps(Supplier> mSupplier) { diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/RightAny.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/RightAny.java index f357d5da4..ff25246c7 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/RightAny.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/RightAny.java @@ -29,7 +29,7 @@ */ public final class RightAny implements MonoidFactory, Either> { - private static final RightAny INSTANCE = new RightAny(); + private static final RightAny INSTANCE = new RightAny<>(); private RightAny() { } @@ -42,7 +42,7 @@ public Monoid> apply(Monoid rMonoid) { @SuppressWarnings("unchecked") public static RightAny rightAny() { - return INSTANCE; + return (RightAny) INSTANCE; } public static Monoid> rightAny(Monoid rMonoid) { diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/RunAll.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/RunAll.java index 871deebb1..b3ab1c93e 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/RunAll.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/RunAll.java @@ -17,7 +17,7 @@ */ public final class RunAll implements MonoidFactory, IO> { - private static final RunAll INSTANCE = new RunAll(); + private static final RunAll INSTANCE = new RunAll<>(); private RunAll() { } @@ -30,7 +30,7 @@ public Monoid> apply(Monoid monoid) { @SuppressWarnings("unchecked") public static RunAll runAll() { - return INSTANCE; + return (RunAll) INSTANCE; } public static Monoid> runAll(Monoid monoid) { diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Union.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Union.java index d119e0a50..4594f328e 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Union.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Union.java @@ -15,7 +15,7 @@ */ public final class Union implements Monoid> { - private static final Union INSTANCE = new Union(); + private static final Union INSTANCE = new Union<>(); private Union() { } @@ -32,7 +32,7 @@ public Iterable apply(Iterable xs, Iterable ys) { @SuppressWarnings("unchecked") public static Union union() { - return INSTANCE; + return (Union) INSTANCE; } public static Fn1, Iterable> union(Iterable xs) { diff --git a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Absent.java b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Absent.java index 9c5392860..f2991e238 100644 --- a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Absent.java +++ b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Absent.java @@ -32,7 +32,7 @@ private Absent() { @Override public Semigroup> apply(Semigroup aSemigroup) { - return LiftA2., Maybe, Maybe>liftA2(aSemigroup.toBiFunction())::apply; + return LiftA2., Maybe, Maybe, Maybe>liftA2(aSemigroup.toBiFunction())::apply; } @SuppressWarnings("unchecked") diff --git a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Collapse.java b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Collapse.java index 9c2046632..d1a3b6eca 100644 --- a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Collapse.java +++ b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Collapse.java @@ -21,7 +21,7 @@ */ public final class Collapse<_1, _2> implements BiSemigroupFactory, Semigroup<_2>, Tuple2<_1, _2>> { - private static final Collapse INSTANCE = new Collapse(); + private static final Collapse INSTANCE = new Collapse<>(); private Collapse() { } @@ -34,7 +34,7 @@ public Semigroup> apply(Semigroup<_1> _1Semigroup, Semigroup<_2> @SuppressWarnings("unchecked") public static <_1, _2> Collapse<_1, _2> collapse() { - return INSTANCE; + return (Collapse<_1, _2>) INSTANCE; } public static <_1, _2> SemigroupFactory, Tuple2<_1, _2>> collapse(Semigroup<_1> _1Semigroup) { diff --git a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Compose.java b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Compose.java index 9857ab413..0bb9a2a41 100644 --- a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Compose.java +++ b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Compose.java @@ -20,7 +20,7 @@ */ public final class Compose implements SemigroupFactory, CompletableFuture> { - private static final Compose INSTANCE = new Compose(); + private static final Compose INSTANCE = new Compose<>(); private Compose() { } @@ -32,7 +32,7 @@ public Semigroup> apply(Semigroup aSemigroup) { @SuppressWarnings("unchecked") public static Compose compose() { - return INSTANCE; + return (Compose) INSTANCE; } public static Semigroup> compose(Semigroup aSemigroup) { diff --git a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/LeftAll.java b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/LeftAll.java index b8955b2e0..780c61f89 100644 --- a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/LeftAll.java +++ b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/LeftAll.java @@ -30,7 +30,7 @@ */ public final class LeftAll implements SemigroupFactory, Either> { - private static final LeftAll INSTANCE = new LeftAll(); + private static final LeftAll INSTANCE = new LeftAll<>(); private LeftAll() { } @@ -42,7 +42,7 @@ public Semigroup> apply(Semigroup lSemigroup) { @SuppressWarnings("unchecked") public static LeftAll leftAll() { - return INSTANCE; + return (LeftAll) INSTANCE; } public static Semigroup> leftAll(Semigroup lSemigroup) { diff --git a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/LeftAny.java b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/LeftAny.java index b93133143..233246b89 100644 --- a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/LeftAny.java +++ b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/LeftAny.java @@ -29,7 +29,7 @@ */ public final class LeftAny implements SemigroupFactory, Either> { - private static final LeftAny INSTANCE = new LeftAny(); + private static final LeftAny INSTANCE = new LeftAny<>(); private LeftAny() { } @@ -43,7 +43,7 @@ public Semigroup> apply(Semigroup lSemigroup) { @SuppressWarnings("unchecked") public static LeftAny leftAny() { - return INSTANCE; + return (LeftAny) INSTANCE; } public static Semigroup> leftAny(Semigroup lSemigroup) { diff --git a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Max.java b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Max.java index 3687a5187..001a39a3e 100644 --- a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Max.java +++ b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Max.java @@ -20,7 +20,7 @@ */ public final class Max> implements Semigroup { - private static final Max INSTANCE = new Max(); + private static final Max INSTANCE = new Max<>(); private Max() { } @@ -32,7 +32,7 @@ public A apply(A x, A y) { @SuppressWarnings("unchecked") public static > Max max() { - return INSTANCE; + return (Max) INSTANCE; } public static > Fn1 max(A x) { diff --git a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/MaxBy.java b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/MaxBy.java index 5e6cbbe5c..d00bcbb4b 100644 --- a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/MaxBy.java +++ b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/MaxBy.java @@ -24,7 +24,7 @@ */ public final class MaxBy> implements SemigroupFactory, A> { - private static final MaxBy INSTANCE = new MaxBy(); + private static final MaxBy INSTANCE = new MaxBy<>(); private MaxBy() { } @@ -36,7 +36,7 @@ public Semigroup apply(Function compareFn) { @SuppressWarnings("unchecked") public static > MaxBy maxBy() { - return INSTANCE; + return (MaxBy) INSTANCE; } public static > Semigroup maxBy( diff --git a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Merge.java b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Merge.java index 75bd81ffd..eaf5e355b 100644 --- a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Merge.java +++ b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Merge.java @@ -20,7 +20,7 @@ */ public final class Merge implements BiSemigroupFactory, Semigroup, Either> { - private static final Merge INSTANCE = new Merge(); + private static final Merge INSTANCE = new Merge<>(); private Merge() { } @@ -32,7 +32,7 @@ public Semigroup> apply(Semigroup lSemigroup, Semigroup rSemi @SuppressWarnings("unchecked") public static Merge merge() { - return INSTANCE; + return (Merge) INSTANCE; } public static SemigroupFactory, Either> merge(Semigroup lSemigroup) { diff --git a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Min.java b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Min.java index 742055ed5..f700e4612 100644 --- a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Min.java +++ b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Min.java @@ -20,7 +20,7 @@ */ public final class Min> implements Semigroup { - private static final Min INSTANCE = new Min(); + private static final Min INSTANCE = new Min<>(); private Min() { } @@ -32,7 +32,7 @@ public A apply(A x, A y) { @SuppressWarnings("unchecked") public static > Min min() { - return INSTANCE; + return (Min) INSTANCE; } public static > Fn1 min(A x) { diff --git a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/MinBy.java b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/MinBy.java index 3a7ea9a71..4458a55bc 100644 --- a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/MinBy.java +++ b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/MinBy.java @@ -24,7 +24,7 @@ */ public final class MinBy> implements SemigroupFactory, A> { - private static final MinBy INSTANCE = new MinBy(); + private static final MinBy INSTANCE = new MinBy<>(); private MinBy() { } @@ -36,7 +36,7 @@ public Semigroup apply(Function compareFn) { @SuppressWarnings("unchecked") public static > MinBy minBy() { - return INSTANCE; + return (MinBy) INSTANCE; } public static > Semigroup minBy( diff --git a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/RightAll.java b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/RightAll.java index 7f1bdab5b..8c69fbd94 100644 --- a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/RightAll.java +++ b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/RightAll.java @@ -29,7 +29,7 @@ */ public final class RightAll implements SemigroupFactory, Either> { - private static final RightAll INSTANCE = new RightAll(); + private static final RightAll INSTANCE = new RightAll<>(); private RightAll() { } @@ -41,7 +41,7 @@ public Semigroup> apply(Semigroup rSemigroup) { @SuppressWarnings("unchecked") public static RightAll rightAll() { - return INSTANCE; + return (RightAll) INSTANCE; } public static Semigroup> rightAll(Semigroup rSemigroup) { diff --git a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/RightAny.java b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/RightAny.java index 00f528054..7d2f1d864 100644 --- a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/RightAny.java +++ b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/RightAny.java @@ -30,7 +30,7 @@ */ public final class RightAny implements SemigroupFactory, Either> { - private static final RightAny INSTANCE = new RightAny(); + private static final RightAny INSTANCE = new RightAny<>(); private RightAny() { } @@ -44,7 +44,7 @@ public Semigroup> apply(Semigroup rSemigroup) { @SuppressWarnings("unchecked") public static RightAny rightAny() { - return INSTANCE; + return (RightAny) INSTANCE; } public static Semigroup> rightAny(Semigroup rSemigroup) { diff --git a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/RunAll.java b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/RunAll.java index b46ff9612..34a2eeb2b 100644 --- a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/RunAll.java +++ b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/RunAll.java @@ -13,7 +13,7 @@ */ public final class RunAll implements SemigroupFactory, IO> { - private static final RunAll INSTANCE = new RunAll(); + private static final RunAll INSTANCE = new RunAll<>(); private RunAll() { } @@ -25,7 +25,7 @@ public Semigroup> apply(Semigroup semigroup) { @SuppressWarnings("unchecked") public static RunAll runAll() { - return INSTANCE; + return (RunAll) INSTANCE; } public static Semigroup> runAll(Semigroup semigroup) { diff --git a/src/main/java/com/jnape/palatable/lambda/traversable/LambdaIterable.java b/src/main/java/com/jnape/palatable/lambda/traversable/LambdaIterable.java index 0dfb2b7e3..81928dc81 100644 --- a/src/main/java/com/jnape/palatable/lambda/traversable/LambdaIterable.java +++ b/src/main/java/com/jnape/palatable/lambda/traversable/LambdaIterable.java @@ -23,7 +23,7 @@ * @param the {@link Iterable} element type * @see LambdaMap */ -public final class LambdaIterable implements Monad, Traversable { +public final class LambdaIterable implements Monad>, Traversable> { private final Iterable as; @SuppressWarnings("unchecked") @@ -67,7 +67,7 @@ public LambdaIterable pure(B b) { * @return the zipped LambdaIterable */ @Override - public LambdaIterable zip(Applicative, LambdaIterable> appFn) { + public LambdaIterable zip(Applicative, LambdaIterable> appFn) { return Monad.super.zip(appFn).coerce(); } @@ -76,7 +76,7 @@ public LambdaIterable zip(Applicative, L */ @Override public Lazy> lazyZip( - Lazy, LambdaIterable>> lazyAppFn) { + Lazy, LambdaIterable>> lazyAppFn) { return Empty.empty(as) ? lazy(LambdaIterable.empty()) : Monad.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); @@ -86,7 +86,7 @@ public Lazy> lazyZip( * {@inheritDoc} */ @Override - public LambdaIterable discardL(Applicative appB) { + public LambdaIterable discardL(Applicative> appB) { return Monad.super.discardL(appB).coerce(); } @@ -94,7 +94,7 @@ public LambdaIterable discardL(Applicative appB) { * {@inheritDoc} */ @Override - public LambdaIterable discardR(Applicative appB) { + public LambdaIterable discardR(Applicative> appB) { return Monad.super.discardR(appB).coerce(); } @@ -102,7 +102,7 @@ public LambdaIterable discardR(Applicative appB) { * {@inheritDoc} */ @Override - public LambdaIterable flatMap(Function> f) { + public LambdaIterable flatMap(Function>> f) { return wrap(flatten(map(a -> f.apply(a).>coerce().unwrap(), as))); } @@ -111,7 +111,8 @@ public LambdaIterable flatMap(Function, AppB extends Applicative, + public , TravB extends Traversable>, + AppB extends Applicative, AppTrav extends Applicative> AppTrav traverse(Function fn, Function pure) { return FoldRight.foldRight( diff --git a/src/main/java/com/jnape/palatable/lambda/traversable/LambdaMap.java b/src/main/java/com/jnape/palatable/lambda/traversable/LambdaMap.java index 20205a419..5b683de69 100644 --- a/src/main/java/com/jnape/palatable/lambda/traversable/LambdaMap.java +++ b/src/main/java/com/jnape/palatable/lambda/traversable/LambdaMap.java @@ -46,12 +46,15 @@ public LambdaMap fmap(Function fn) { @Override @SuppressWarnings("unchecked") - public >, AppC extends Applicative, AppTrav extends Applicative> AppTrav traverse( - Function fn, Function pure) { - return foldLeft(Fn2., AppTrav>fn2(appTrav -> into((k, appV) -> (AppTrav) appTrav.zip(appV.fmap(v -> m -> { - ((LambdaMap) m).unwrap().put(k, v); - return (TravC) m; - })))).toBiFunction(), + public , TravC extends Traversable>, + AppC extends Applicative, + AppTrav extends Applicative> AppTrav traverse(Function fn, + Function pure) { + return foldLeft(Fn2., AppTrav>fn2( + appTrav -> into((k, appV) -> (AppTrav) appTrav.zip(appV.fmap(v -> m -> { + ((LambdaMap) m).unwrap().put(k, v); + return (TravC) m; + })))).toBiFunction(), pure.apply((TravC) LambdaMap.wrap(new HashMap<>())), this.fmap(fn).unwrap().entrySet()); } diff --git a/src/main/java/com/jnape/palatable/lambda/traversable/Traversable.java b/src/main/java/com/jnape/palatable/lambda/traversable/Traversable.java index aff6884da..ec52e4e51 100644 --- a/src/main/java/com/jnape/palatable/lambda/traversable/Traversable.java +++ b/src/main/java/com/jnape/palatable/lambda/traversable/Traversable.java @@ -30,7 +30,7 @@ * @param The type of the parameter * @param The unification parameter */ -public interface Traversable extends Functor { +public interface Traversable> extends Functor { /** * Apply fn to each element of this traversable from left to right, and collapse the results into @@ -45,7 +45,7 @@ public interface Traversable extends Functor { * @param the full inferred resulting type from the traversal * @return the traversed Traversable, wrapped inside an applicative */ - , AppB extends Applicative, + , TravB extends Traversable, AppB extends Applicative, AppTrav extends Applicative> AppTrav traverse( Function fn, Function pure); diff --git a/src/test/java/com/jnape/palatable/lambda/functions/specialized/KleisliTest.java b/src/test/java/com/jnape/palatable/lambda/functions/specialized/KleisliTest.java index bd40b2dca..8be6844fe 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/specialized/KleisliTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functions/specialized/KleisliTest.java @@ -9,8 +9,8 @@ public class KleisliTest { - private static final Kleisli> G = kleisli(i -> new Identity<>(i.toString())); - private static final Kleisli> F = kleisli(s -> new Identity<>(parseInt(s))); + private static final Kleisli, Identity> G = kleisli(i -> new Identity<>(i.toString())); + private static final Kleisli, Identity> F = kleisli(s -> new Identity<>(parseInt(s))); @Test public void leftToRightComposition() { diff --git a/src/test/java/com/jnape/palatable/lambda/functor/BifunctorTest.java b/src/test/java/com/jnape/palatable/lambda/functor/BifunctorTest.java index ce89ba26e..4cb93cf08 100644 --- a/src/test/java/com/jnape/palatable/lambda/functor/BifunctorTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functor/BifunctorTest.java @@ -15,7 +15,8 @@ public class BifunctorTest { @Test public void biMapLUsesIdentityForRightBiMapFunction() { AtomicReference rightInvocation = new AtomicReference<>(); - Bifunctor bifunctor = new InvocationRecordingBifunctor<>(new AtomicReference<>(), rightInvocation); + Bifunctor> bifunctor = + new InvocationRecordingBifunctor<>(new AtomicReference<>(), rightInvocation); bifunctor.biMapL(String::toUpperCase); assertThat(rightInvocation.get(), is(id())); } @@ -23,7 +24,8 @@ public void biMapLUsesIdentityForRightBiMapFunction() { @Test public void biMapRUsesIdentityForLeftBiMapFunction() { AtomicReference leftInvocation = new AtomicReference<>(); - Bifunctor bifunctor = new InvocationRecordingBifunctor<>(leftInvocation, new AtomicReference<>()); + Bifunctor> bifunctor = + new InvocationRecordingBifunctor<>(leftInvocation, new AtomicReference<>()); bifunctor.biMapR(String::valueOf); assertThat(leftInvocation.get(), is(id())); } diff --git a/src/test/java/com/jnape/palatable/lambda/functor/ProfunctorTest.java b/src/test/java/com/jnape/palatable/lambda/functor/ProfunctorTest.java index 0f7358250..f2fb6980d 100644 --- a/src/test/java/com/jnape/palatable/lambda/functor/ProfunctorTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functor/ProfunctorTest.java @@ -15,7 +15,8 @@ public class ProfunctorTest { @Test public void diMapLUsesIdentityForRightDiMapFunction() { AtomicReference rightInvocation = new AtomicReference<>(); - Profunctor profunctor = new InvocationRecordingProfunctor<>(new AtomicReference<>(), rightInvocation); + Profunctor> profunctor = + new InvocationRecordingProfunctor<>(new AtomicReference<>(), rightInvocation); profunctor.diMapL(Object::toString); assertThat(rightInvocation.get(), is(id())); } @@ -23,7 +24,8 @@ public void diMapLUsesIdentityForRightDiMapFunction() { @Test public void diMapRUsesIdentityForLeftDiMapFunction() { AtomicReference leftInvocation = new AtomicReference<>(); - Profunctor profunctor = new InvocationRecordingProfunctor<>(leftInvocation, new AtomicReference<>()); + Profunctor> profunctor = + new InvocationRecordingProfunctor<>(leftInvocation, new AtomicReference<>()); profunctor.diMapR(String::valueOf); assertThat(leftInvocation.get(), is(id())); } diff --git a/src/test/java/com/jnape/palatable/lambda/functor/builtin/ComposeTest.java b/src/test/java/com/jnape/palatable/lambda/functor/builtin/ComposeTest.java index 3cc6198fc..66303c375 100644 --- a/src/test/java/com/jnape/palatable/lambda/functor/builtin/ComposeTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functor/builtin/ComposeTest.java @@ -17,7 +17,7 @@ public class ComposeTest { @TestTraits({FunctorLaws.class, ApplicativeLaws.class}) - public Compose testSubject() { + public Compose, Identity, Integer> testSubject() { return new Compose<>(new Identity<>(new Identity<>(1))); } diff --git a/src/test/java/com/jnape/palatable/lambda/lens/LensTest.java b/src/test/java/com/jnape/palatable/lambda/lens/LensTest.java index f5478be8f..7d609e980 100644 --- a/src/test/java/com/jnape/palatable/lambda/lens/LensTest.java +++ b/src/test/java/com/jnape/palatable/lambda/lens/LensTest.java @@ -47,7 +47,7 @@ public class LensTest { @Test public void setsUnderIdentity() { - Set ints = LENS.>, Identity>apply(s -> new Identity<>(s.length()), asList("foo", "bar", "baz")).runIdentity(); + Set ints = LENS., Identity>, Identity>apply(s -> new Identity<>(s.length()), asList("foo", "bar", "baz")).runIdentity(); assertEquals(singleton(3), ints); } @@ -67,7 +67,7 @@ public void mapsIndividuallyOverParameters() { .mapB((Maybe maybeI) -> maybeI.orElse(-1)); assertEquals(just(true), - theGambit.>, Identity>>apply( + theGambit., Identity>, Identity>>apply( maybeC -> new Identity<>(maybeC.fmap(c -> parseInt(Character.toString(c)))), just("321")).runIdentity() ); diff --git a/src/test/java/testsupport/EquatableM.java b/src/test/java/testsupport/EquatableM.java index 2478e5a97..72feb443d 100644 --- a/src/test/java/testsupport/EquatableM.java +++ b/src/test/java/testsupport/EquatableM.java @@ -6,7 +6,7 @@ import java.util.Objects; import java.util.function.Function; -public final class EquatableM, A> implements Monad> { +public final class EquatableM, A> implements Monad> { private final Monad ma; private final Function equatable; diff --git a/src/test/java/testsupport/applicatives/InvocationRecordingBifunctor.java b/src/test/java/testsupport/applicatives/InvocationRecordingBifunctor.java index e1ab75465..92565e2de 100644 --- a/src/test/java/testsupport/applicatives/InvocationRecordingBifunctor.java +++ b/src/test/java/testsupport/applicatives/InvocationRecordingBifunctor.java @@ -5,7 +5,7 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; -public final class InvocationRecordingBifunctor implements Bifunctor { +public final class InvocationRecordingBifunctor implements Bifunctor> { private final AtomicReference leftFn; private final AtomicReference rightFn; diff --git a/src/test/java/testsupport/applicatives/InvocationRecordingProfunctor.java b/src/test/java/testsupport/applicatives/InvocationRecordingProfunctor.java index 4f440bb38..ac9e53fba 100644 --- a/src/test/java/testsupport/applicatives/InvocationRecordingProfunctor.java +++ b/src/test/java/testsupport/applicatives/InvocationRecordingProfunctor.java @@ -5,7 +5,7 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; -public final class InvocationRecordingProfunctor implements Profunctor { +public final class InvocationRecordingProfunctor implements Profunctor> { private final AtomicReference leftFn; private final AtomicReference rightFn; diff --git a/src/test/java/testsupport/traits/ApplicativeLaws.java b/src/test/java/testsupport/traits/ApplicativeLaws.java index 42fd8bbde..11397da5a 100644 --- a/src/test/java/testsupport/traits/ApplicativeLaws.java +++ b/src/test/java/testsupport/traits/ApplicativeLaws.java @@ -16,7 +16,7 @@ import static java.util.Arrays.asList; import static java.util.function.Function.identity; -public class ApplicativeLaws implements Trait> { +public class ApplicativeLaws> implements Trait> { @Override public void test(Applicative applicative) { diff --git a/src/test/java/testsupport/traits/BifunctorLaws.java b/src/test/java/testsupport/traits/BifunctorLaws.java index b8bb42856..55278590e 100644 --- a/src/test/java/testsupport/traits/BifunctorLaws.java +++ b/src/test/java/testsupport/traits/BifunctorLaws.java @@ -12,7 +12,7 @@ import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id; import static java.util.Arrays.asList; -public class BifunctorLaws implements Trait> { +public class BifunctorLaws> implements Trait> { @Override public void test(Bifunctor bifunctor) { @@ -30,19 +30,19 @@ public void test(Bifunctor bifunctor) { private Maybe testLeftIdentity(Bifunctor bifunctor) { return bifunctor.biMapL(id()).equals(bifunctor) - ? nothing() - : just("left identity (bifunctor.biMapL(id()).equals(bifunctor))"); + ? nothing() + : just("left identity (bifunctor.biMapL(id()).equals(bifunctor))"); } private Maybe testRightIdentity(Bifunctor bifunctor) { return bifunctor.biMapR(id()).equals(bifunctor) - ? nothing() - : just("right identity (bifunctor.biMapR(id()).equals(bifunctor))"); + ? nothing() + : just("right identity (bifunctor.biMapR(id()).equals(bifunctor))"); } private Maybe testMutualIdentity(Bifunctor bifunctor) { return bifunctor.biMapL(id()).biMapR(id()).equals(bifunctor.biMap(id(), id())) - ? nothing() - : just("mutual identity (bifunctor.biMapL(id()).biMapR(id()).equals(bifunctor.biMap(id(),id()))"); + ? nothing() + : just("mutual identity (bifunctor.biMapL(id()).biMapR(id()).equals(bifunctor.biMap(id(),id()))"); } } diff --git a/src/test/java/testsupport/traits/FunctorLaws.java b/src/test/java/testsupport/traits/FunctorLaws.java index a6b5f3d0e..dbe96c6e5 100644 --- a/src/test/java/testsupport/traits/FunctorLaws.java +++ b/src/test/java/testsupport/traits/FunctorLaws.java @@ -13,7 +13,7 @@ import static java.util.Arrays.asList; import static java.util.function.Function.identity; -public class FunctorLaws implements Trait> { +public class FunctorLaws> implements Trait> { @Override public void test(Functor f) { @@ -29,8 +29,8 @@ public void test(Functor f) { private Maybe testIdentity(Functor f) { return f.fmap(identity()).equals(f) - ? nothing() - : just("identity (f.fmap(identity()).equals(f))"); + ? nothing() + : just("identity (f.fmap(identity()).equals(f))"); } private Maybe testComposition(Functor functor) { @@ -38,7 +38,7 @@ private Maybe testComposition(Functor functor) { Function f = x -> x * 3; Function g = x -> x - 2; return subject.fmap(f.compose(g)).equals(subject.fmap(g).fmap(f)) - ? nothing() - : just("composition (functor.fmap(f.compose(g)).equals(functor.fmap(g).fmap(f)))"); + ? nothing() + : just("composition (functor.fmap(f.compose(g)).equals(functor.fmap(g).fmap(f)))"); } } diff --git a/src/test/java/testsupport/traits/MonadLaws.java b/src/test/java/testsupport/traits/MonadLaws.java index 038fc6789..98738eb57 100644 --- a/src/test/java/testsupport/traits/MonadLaws.java +++ b/src/test/java/testsupport/traits/MonadLaws.java @@ -16,7 +16,7 @@ import static com.jnape.palatable.lambda.monad.Monad.join; import static java.util.Arrays.asList; -public class MonadLaws implements Trait> { +public class MonadLaws> implements Trait> { @Override public void test(Monad m) { diff --git a/src/test/java/testsupport/traits/TraversableLaws.java b/src/test/java/testsupport/traits/TraversableLaws.java index 8ce0ab0f0..a9095fd97 100644 --- a/src/test/java/testsupport/traits/TraversableLaws.java +++ b/src/test/java/testsupport/traits/TraversableLaws.java @@ -18,7 +18,7 @@ import static java.util.Arrays.asList; @SuppressWarnings("Convert2MethodRef") -public class TraversableLaws implements Trait> { +public class TraversableLaws> implements Trait> { @Override public void test(Traversable traversable) { @@ -38,31 +38,30 @@ private Maybe testNaturality(Traversable trav) { Function> f = Identity::new; Function, Either> t = id -> right(id.runIdentity()); - Function, Applicative, Identity>> pureFn = x -> new Identity<>(x); + Function, Applicative, Identity>> pureFn = x -> new Identity<>(x); Function, Applicative, Either>> pureFn2 = x -> right(x); return t.apply(trav.traverse(f, pureFn).fmap(id()).coerce()) - .equals(trav.traverse(t.compose(f), pureFn2).fmap(id()).coerce()) - ? nothing() - : just("naturality (t.apply(trav.traverse(f, pureFn).fmap(id()).coerce())\n" + - " .equals(trav.traverse(t.compose(f), pureFn2).fmap(id()).coerce()))"); + .equals(trav.traverse(t.compose(f), pureFn2).fmap(id()).coerce()) + ? nothing() + : just("naturality (t.apply(trav.traverse(f, pureFn).fmap(id()).coerce())\n" + + " .equals(trav.traverse(t.compose(f), pureFn2).fmap(id()).coerce()))"); } private Maybe testIdentity(Traversable trav) { return trav.traverse(Identity::new, x -> new Identity<>(x)).equals(new Identity<>(trav)) - ? nothing() - : just("identity (trav.traverse(Identity::new, x -> new Identity<>(x)).equals(new Identity<>(trav))"); + ? nothing() + : just("identity (trav.traverse(Identity::new, x -> new Identity<>(x)).equals(new Identity<>(trav))"); } - @SuppressWarnings("unchecked") private Maybe testComposition(Traversable trav) { Function> f = Identity::new; - Function> g = x -> new Identity<>(x); + Function>> g = x -> new Identity<>(x); return trav.traverse(f.andThen(x -> x.fmap(g)).andThen(Compose::new), x -> new Compose<>(new Identity<>(new Identity<>(x)))) .equals(new Compose<>(trav.traverse(f, x -> new Identity<>(x)).fmap(t -> t.traverse(g, x -> new Identity<>(x))))) - ? nothing() - : just("compose (trav.traverse(f.andThen(x -> x.fmap(g)).andThen(Compose::new), x -> new Compose<>(new Identity<>(new Identity<>(x))))\n" + - " .equals(new Compose>(trav.traverse(f, x -> new Identity<>(x)).fmap(t -> t.traverse(g, x -> new Identity<>(x))))))"); + ? nothing() + : just("compose (trav.traverse(f.andThen(x -> x.fmap(g)).andThen(Compose::new), x -> new Compose<>(new Identity<>(new Identity<>(x))))\n" + + " .equals(new Compose>(trav.traverse(f, x -> new Identity<>(x)).fmap(t -> t.traverse(g, x -> new Identity<>(x))))))"); } } From f7c3008b94710b51cc7717a13e9886499882a531 Mon Sep 17 00:00:00 2001 From: jnape Date: Sun, 14 Apr 2019 17:02:07 -0500 Subject: [PATCH 10/69] More elimination of warnings --- .../jnape/palatable/lambda/adt/Either.java | 3 +- .../com/jnape/palatable/lambda/adt/Maybe.java | 5 +-- .../com/jnape/palatable/lambda/adt/These.java | 5 +-- .../com/jnape/palatable/lambda/adt/Try.java | 4 ++- .../palatable/lambda/adt/choice/Choice2.java | 3 +- .../palatable/lambda/adt/choice/Choice3.java | 3 +- .../palatable/lambda/adt/choice/Choice4.java | 3 +- .../palatable/lambda/adt/choice/Choice5.java | 3 +- .../palatable/lambda/adt/choice/Choice6.java | 3 +- .../palatable/lambda/adt/choice/Choice7.java | 3 +- .../palatable/lambda/adt/choice/Choice8.java | 3 +- .../lambda/adt/hlist/SingletonHList.java | 4 +-- .../palatable/lambda/adt/hlist/Tuple2.java | 2 +- .../palatable/lambda/adt/hlist/Tuple3.java | 4 +-- .../palatable/lambda/adt/hlist/Tuple4.java | 4 +-- .../palatable/lambda/adt/hlist/Tuple5.java | 4 +-- .../palatable/lambda/adt/hlist/Tuple6.java | 4 +-- .../palatable/lambda/adt/hlist/Tuple7.java | 4 +-- .../palatable/lambda/adt/hlist/Tuple8.java | 5 +-- .../jnape/palatable/lambda/adt/hmap/HMap.java | 20 +++++------ .../palatable/lambda/adt/hmap/Schema.java | 36 +++++++++++++------ .../lambda/adt/hmap/TypeSafeKey.java | 7 +++- .../jnape/palatable/lambda/functions/Fn1.java | 4 ++- .../lambda/functions/builtin/fn1/Cycle.java | 1 + .../lambda/functions/builtin/fn1/Upcast.java | 4 +-- .../lambda/functions/specialized/Kleisli.java | 2 ++ .../palatable/lambda/functor/Applicative.java | 4 +-- .../lambda/functor/builtin/Compose.java | 12 ++++--- .../lambda/functor/builtin/Const.java | 7 ++-- .../lambda/functor/builtin/Identity.java | 7 ++-- .../com/jnape/palatable/lambda/io/IO.java | 6 ++-- .../IterationInterruptedException.java | 1 + .../com/jnape/palatable/lambda/lens/Iso.java | 22 +++++++----- .../com/jnape/palatable/lambda/lens/Lens.java | 14 ++++---- .../jnape/palatable/lambda/lens/LensLike.java | 4 +-- .../lambda/lens/lenses/CollectionLens.java | 3 +- .../jnape/palatable/lambda/monad/Monad.java | 4 ++- .../lambda/monoid/builtin/Present.java | 4 +-- .../lambda/semigroup/builtin/Absent.java | 4 +-- .../lambda/traversable/LambdaIterable.java | 8 +++-- .../lambda/traversable/LambdaMap.java | 2 +- .../lambda/adt/hlist/SingletonHListTest.java | 2 +- .../lambda/adt/hlist/Tuple2Test.java | 3 +- .../lambda/adt/hlist/Tuple3Test.java | 2 +- .../lambda/adt/hlist/Tuple4Test.java | 2 +- .../lambda/adt/hlist/Tuple5Test.java | 2 +- .../lambda/adt/hlist/Tuple6Test.java | 2 +- .../lambda/adt/hlist/Tuple7Test.java | 2 +- .../lambda/adt/hlist/Tuple8Test.java | 2 +- .../palatable/lambda/adt/hmap/HMapTest.java | 4 +-- .../functions/builtin/fn1/CycleTest.java | 2 +- .../functions/builtin/fn1/DistinctTest.java | 2 +- .../functions/builtin/fn1/InitTest.java | 2 +- .../functions/builtin/fn1/InitsTest.java | 2 +- .../builtin/fn1/OccurrencesTest.java | 5 +-- .../functions/builtin/fn1/RepeatTest.java | 2 +- .../functions/builtin/fn1/ReverseTest.java | 2 +- .../functions/builtin/fn1/SizeTest.java | 1 + .../functions/builtin/fn1/TailTest.java | 2 +- .../functions/builtin/fn1/TailsTest.java | 2 +- .../functions/builtin/fn1/UnconsTest.java | 2 +- .../functions/builtin/fn2/FilterTest.java | 2 +- .../functions/builtin/fn2/GroupByTest.java | 4 ++- .../functions/builtin/fn2/IterateTest.java | 2 +- .../lambda/functions/builtin/fn2/MapTest.java | 2 +- .../functions/builtin/fn2/PartitionTest.java | 2 +- .../functions/builtin/fn2/ToMapTest.java | 1 + .../functions/builtin/fn2/UnfoldrTest.java | 2 +- .../lambda/functor/builtin/ConstTest.java | 2 +- .../lambda/functor/builtin/IdentityTest.java | 2 +- .../jnape/palatable/lambda/lens/IsoTest.java | 9 +++-- .../jnape/palatable/lambda/lens/LensTest.java | 2 +- .../lambda/lens/lenses/MapLensTest.java | 1 + .../lambda/monoid/builtin/AddAllTest.java | 1 + .../lambda/traversable/LambdaMapTest.java | 1 + src/test/java/testsupport/EquatableM.java | 5 +++ .../traits/EmptyIterableSupport.java | 6 ++-- .../testsupport/traits/FiniteIteration.java | 6 ++-- .../traits/ImmutableIteration.java | 6 ++-- .../traits/InfiniteIterableSupport.java | 4 +-- .../testsupport/traits/InfiniteIteration.java | 6 ++-- .../java/testsupport/traits/Laziness.java | 6 ++-- 82 files changed, 223 insertions(+), 139 deletions(-) diff --git a/src/main/java/com/jnape/palatable/lambda/adt/Either.java b/src/main/java/com/jnape/palatable/lambda/adt/Either.java index cea6eac17..85b538c47 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/Either.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/Either.java @@ -256,10 +256,11 @@ public final Either zip(Applicative Lazy> lazyZip( - Lazy, Either>> lazyAppFn) { + Lazy, Either>> lazyAppFn) { return match(l -> lazy(left(l)), r -> lazyAppFn.fmap(eitherLF -> eitherLF.fmap(f -> f.apply(r)).coerce())); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/Maybe.java b/src/main/java/com/jnape/palatable/lambda/adt/Maybe.java index aeaf59d3c..67c1fd886 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/Maybe.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/Maybe.java @@ -141,12 +141,13 @@ public final Maybe zip(Applicative, Mayb /** * Terminate early if this is a {@link Nothing}; otherwise, continue the {@link Applicative#zip zip}. * - * @param lazyAppFn the lazy other applicative instance * @param the result type + * @param lazyAppFn the lazy other applicative instance * @return the zipped {@link Maybe} */ @Override - public Lazy> lazyZip(Lazy, Maybe>> lazyAppFn) { + public Lazy> lazyZip( + Lazy, Maybe>> lazyAppFn) { return match(constantly(lazy(nothing())), a -> lazyAppFn.fmap(maybeF -> maybeF.fmap(f -> f.apply(a)).coerce())); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/These.java b/src/main/java/com/jnape/palatable/lambda/adt/These.java index e25d0e741..4416135de 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/These.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/These.java @@ -101,9 +101,10 @@ public final These zip(Applicative, T } @Override - public Lazy> lazyZip(Lazy, These>> lazyAppFn) { + public Lazy> lazyZip( + Lazy, These>> lazyAppFn) { return projectA().>>fmap(a -> lazy(a(a))) - .orElseGet(() -> Monad.super.lazyZip(lazyAppFn).fmap(Applicative::coerce)); + .orElseGet(() -> Monad.super.lazyZip(lazyAppFn).fmap(Monad>::coerce)); } /** diff --git a/src/main/java/com/jnape/palatable/lambda/adt/Try.java b/src/main/java/com/jnape/palatable/lambda/adt/Try.java index 63b915122..e714739ed 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/Try.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/Try.java @@ -174,7 +174,8 @@ public Try zip(Applicative, Try } @Override - public Lazy> lazyZip(Lazy, Try>> lazyAppFn) { + public Lazy> lazyZip( + Lazy, Try>> lazyAppFn) { return match(f -> lazy(failure(f)), s -> lazyAppFn.fmap(tryF -> tryF.fmap(f -> f.apply(s)).coerce())); } @@ -315,6 +316,7 @@ public static Try trying(CheckedRunnable runna * @param the function return type * @return a {@link Try} representing the result of the function's application to the resource */ + @SuppressWarnings("try") public static Try withResources( CheckedSupplier aSupplier, CheckedFn1> fn) { diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice2.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice2.java index 52eeb2455..b63ed4745 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice2.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice2.java @@ -114,10 +114,11 @@ public Choice2 zip(Applicative, Choic /** * {@inheritDoc} + * @param lazyAppFn */ @Override public Lazy>> lazyZip( - Lazy, Choice2>> lazyAppFn) { + Lazy, Choice2>> lazyAppFn) { return match(a -> lazy(a(a)), b -> lazyAppFn.fmap(choiceF -> choiceF.fmap(f -> f.apply(b)).coerce())); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice3.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice3.java index 7ea524505..c3d8d2697 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice3.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice3.java @@ -114,10 +114,11 @@ public Choice3 zip(Applicative, Ch /** * {@inheritDoc} + * @param lazyAppFn */ @Override public Lazy> lazyZip( - Lazy, Choice3>> lazyAppFn) { + Lazy, Choice3>> lazyAppFn) { return match(a -> lazy(a(a)), b -> lazy(b(b)), c -> lazyAppFn.fmap(choiceF -> choiceF.fmap(f -> f.apply(c)).coerce())); diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice4.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice4.java index be222cbac..a707afc69 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice4.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice4.java @@ -115,10 +115,11 @@ public Choice4 zip(Applicative, /** * {@inheritDoc} + * @param lazyAppFn */ @Override public Lazy> lazyZip( - Lazy, Choice4>> lazyAppFn) { + Lazy, Choice4>> lazyAppFn) { return match(a -> lazy(a(a)), b -> lazy(b(b)), c -> lazy(c(c)), diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice5.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice5.java index a4c12d21d..ed4b4a5b6 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice5.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice5.java @@ -120,10 +120,11 @@ public Choice5 zip(Applicative Lazy> lazyZip( - Lazy, Choice5>> lazyAppFn) { + Lazy, Choice5>> lazyAppFn) { return match(a -> lazy(a(a)), b -> lazy(b(b)), c -> lazy(c(c)), diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice6.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice6.java index 86e2648f5..e3ab3d48f 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice6.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice6.java @@ -123,10 +123,11 @@ public Choice6 zip( /** * {@inheritDoc} + * @param lazyAppFn */ @Override public Lazy> lazyZip( - Lazy, Choice6>> lazyAppFn) { + Lazy, Choice6>> lazyAppFn) { return match(a -> lazy(a(a)), b -> lazy(b(b)), c -> lazy(c(c)), diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice7.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice7.java index 40c678f87..1348293a5 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice7.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice7.java @@ -126,10 +126,11 @@ public Choice7 zip( /** * {@inheritDoc} + * @param lazyAppFn */ @Override public Lazy> lazyZip( - Lazy, Choice7>> lazyAppFn) { + Lazy, Choice7>> lazyAppFn) { return match(a -> lazy(a(a)), b -> lazy(b(b)), c -> lazy(c(c)), diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice8.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice8.java index e8fb9debe..b0a70c530 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice8.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice8.java @@ -119,10 +119,11 @@ public Choice8 zip( /** * {@inheritDoc} + * @param lazyAppFn */ @Override public Lazy> lazyZip( - Lazy, Choice8>> lazyAppFn) { + Lazy, Choice8>> lazyAppFn) { return match(a -> lazy(a(a)), b -> lazy(b(b)), c -> lazy(c(c)), diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/SingletonHList.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/SingletonHList.java index 8a5be88b9..44bff3484 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/SingletonHList.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/SingletonHList.java @@ -50,8 +50,8 @@ public <_1Prime> SingletonHList<_1Prime> zip( @Override public <_1Prime> Lazy> lazyZip( - Lazy, SingletonHList>> lazyAppFn) { - return Monad.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); + Lazy, SingletonHList>> lazyAppFn) { + return Monad.super.lazyZip(lazyAppFn).fmap(Monad<_1Prime, SingletonHList>::coerce); } @Override diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple2.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple2.java index 06dc1a20a..9f952849b 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple2.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple2.java @@ -112,7 +112,7 @@ public <_2Prime> Tuple2<_1, _2Prime> zip( @Override public <_2Prime> Lazy> lazyZip( - Lazy, Tuple2<_1, ?>>> lazyAppFn) { + Lazy, Tuple2<_1, ?>>> lazyAppFn) { return Monad.super.lazyZip(lazyAppFn).fmap(Monad<_2Prime, Tuple2<_1, ?>>::coerce); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple3.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple3.java index a4601ce19..dd57f1771 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple3.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple3.java @@ -114,8 +114,8 @@ public <_3Prime> Tuple3<_1, _2, _3Prime> zip( @Override public <_3Prime> Lazy> lazyZip( - Lazy, Tuple3<_1, _2, ?>>> lazyAppFn) { - return Monad.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); + Lazy, Tuple3<_1, _2, ?>>> lazyAppFn) { + return Monad.super.lazyZip(lazyAppFn).fmap(Monad<_3Prime, Tuple3<_1, _2, ?>>::coerce); } @Override diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple4.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple4.java index 6b3c410a5..7ffeb72c5 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple4.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple4.java @@ -129,8 +129,8 @@ public <_4Prime> Tuple4<_1, _2, _3, _4Prime> zip( @Override public <_4Prime> Lazy> lazyZip( - Lazy, Tuple4<_1, _2, _3, ?>>> lazyAppFn) { - return Monad.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); + Lazy, Tuple4<_1, _2, _3, ?>>> lazyAppFn) { + return Monad.super.lazyZip(lazyAppFn).fmap(Monad<_4Prime, Tuple4<_1, _2, _3, ?>>::coerce); } @Override diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple5.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple5.java index fe2961fd5..7e6eeb24f 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple5.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple5.java @@ -149,8 +149,8 @@ public <_5Prime> Tuple5<_1, _2, _3, _4, _5Prime> zip( @Override public <_5Prime> Lazy> lazyZip( - Lazy, Tuple5<_1, _2, _3, _4, ?>>> lazyAppFn) { - return Monad.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); + Lazy, Tuple5<_1, _2, _3, _4, ?>>> lazyAppFn) { + return Monad.super.lazyZip(lazyAppFn).fmap(Monad<_5Prime, Tuple5<_1, _2, _3, _4, ?>>::coerce); } @Override diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple6.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple6.java index 2231c6a63..464a5abcd 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple6.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple6.java @@ -169,8 +169,8 @@ public <_6Prime> Tuple6<_1, _2, _3, _4, _5, _6Prime> zip( @Override public <_6Prime> Lazy> lazyZip( - Lazy, Tuple6<_1, _2, _3, _4, _5, ?>>> lazyAppFn) { - return Monad.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); + Lazy, Tuple6<_1, _2, _3, _4, _5, ?>>> lazyAppFn) { + return Monad.super.lazyZip(lazyAppFn).fmap(Monad<_6Prime, Tuple6<_1, _2, _3, _4, _5, ?>>::coerce); } @Override diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple7.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple7.java index 36e39bca8..bd0c6bbf4 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple7.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple7.java @@ -188,8 +188,8 @@ public <_7Prime> Tuple7<_1, _2, _3, _4, _5, _6, _7Prime> zip( @Override public <_7Prime> Lazy> lazyZip( - Lazy, Tuple7<_1, _2, _3, _4, _5, _6, ?>>> lazyAppFn) { - return Monad.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); + Lazy, Tuple7<_1, _2, _3, _4, _5, _6, ?>>> lazyAppFn) { + return Monad.super.lazyZip(lazyAppFn).fmap(Monad<_7Prime, Tuple7<_1, _2, _3, _4, _5, _6, ?>>::coerce); } @Override diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple8.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple8.java index bbc2123cd..b30e68a76 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple8.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple8.java @@ -207,8 +207,9 @@ public <_8Prime> Tuple8<_1, _2, _3, _4, _5, _6, _7, _8Prime> zip( @Override public <_8Prime> Lazy> lazyZip( - Lazy, Tuple8<_1, _2, _3, _4, _5, _6, _7, ?>>> lazyAppFn) { - return Monad.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); + Lazy, + Tuple8<_1, _2, _3, _4, _5, _6, _7, ?>>> lazyAppFn) { + return Monad.super.lazyZip(lazyAppFn).fmap(Monad<_8Prime, Tuple8<_1, _2, _3, _4, _5, _6, _7, ?>>::coerce); } @Override diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hmap/HMap.java b/src/main/java/com/jnape/palatable/lambda/adt/hmap/HMap.java index df5cf50d7..19a166bc1 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hmap/HMap.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hmap/HMap.java @@ -27,13 +27,13 @@ * @see TypeSafeKey * @see com.jnape.palatable.lambda.adt.hlist.HList */ -public final class HMap implements Iterable> { +public final class HMap implements Iterable, Object>> { private static final HMap EMPTY = new HMap(emptyMap()); - private final Map table; + private final Map, Object> table; - private HMap(Map table) { + private HMap(Map, Object> table) { this.table = table; } @@ -90,7 +90,7 @@ public HMap putAll(HMap hMap) { * @param key the key * @return true if the key is mapped; false otherwise */ - public boolean containsKey(TypeSafeKey key) { + public boolean containsKey(TypeSafeKey key) { return table.containsKey(key); } @@ -100,7 +100,7 @@ public boolean containsKey(TypeSafeKey key) { * @param key the key * @return the updated HMap */ - public HMap remove(TypeSafeKey key) { + public HMap remove(TypeSafeKey key) { return alter(t -> t.remove(key)); } @@ -122,7 +122,7 @@ public HMap removeAll(HMap hMap) { * * @return a {@link Set} of all the mapped keys */ - public Set keys() { + public Set> keys() { return new HashSet<>(table.keySet()); } @@ -141,12 +141,12 @@ public Collection values() { * * @return the map view */ - public Map toMap() { + public Map, Object> toMap() { return new HashMap<>(table); } @Override - public Iterator> iterator() { + public Iterator, Object>> iterator() { return map(Tuple2::fromEntry, table.entrySet()).iterator(); } @@ -171,8 +171,8 @@ public String toString() { '}'; } - private HMap alter(Consumer> alterFn) { - HashMap copy = new HashMap<>(table); + private HMap alter(Consumer, Object>> alterFn) { + HashMap, Object> copy = new HashMap<>(table); alterFn.accept(copy); return new HMap(copy); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hmap/Schema.java b/src/main/java/com/jnape/palatable/lambda/adt/hmap/Schema.java index a7e3eb371..6a57cbbbd 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hmap/Schema.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hmap/Schema.java @@ -12,8 +12,11 @@ import com.jnape.palatable.lambda.adt.hlist.Tuple7; import com.jnape.palatable.lambda.adt.hlist.Tuple8; import com.jnape.palatable.lambda.functions.builtin.fn2.Both; +import com.jnape.palatable.lambda.functor.Functor; import com.jnape.palatable.lambda.lens.Lens; +import java.util.function.Function; + import static com.jnape.palatable.lambda.functions.builtin.fn2.Into.into; import static com.jnape.palatable.lambda.lens.lenses.HMapLens.valueAt; @@ -27,21 +30,34 @@ */ public interface Schema> extends Lens.Simple> { - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "RedundantTypeArguments"}) default > Schema add(TypeSafeKey key) { - return Lens.both(this, valueAt(key)) - .>mapA(into((maybeValues, maybeA) -> maybeValues.zip(maybeA.fmap(a -> values -> (NewValues) values.cons(a))))) - .>mapB(Both.both(maybeNewValues -> maybeNewValues.fmap(HCons::tail), - maybeNewValues -> maybeNewValues.fmap(HCons::head))) - ::apply; + Lens, Maybe> lens = Lens.both(this, valueAt(key)) + .>mapA(into((maybeValues, maybeA) -> maybeValues + .zip(maybeA.fmap(a -> values -> (NewValues) values.cons(a))))) + .>mapB(Both.both(maybeNewValues -> maybeNewValues.fmap(HCons::tail), + maybeNewValues -> maybeNewValues.fmap(HCons::head))); + return new Schema() { + @Override + public , FT extends Functor, FB extends Functor, F>> + FT apply(Function, ? extends FB> fn, HMap hmap) { + return lens.apply(fn, hmap); + } + }; } - @SuppressWarnings("unchecked") static Schema> schema(TypeSafeKey key) { - return valueAt(key) + Lens>, Maybe>> lens = valueAt(key) .mapA(ma -> ma.fmap(HList::singletonHList)) - .>>mapB(maybeSingletonA -> maybeSingletonA.fmap(HCons::head)) - ::apply; + .mapB(maybeSingletonA -> maybeSingletonA.fmap(HCons::head)); + return new Schema>() { + @Override + public , FT extends Functor, + FB extends Functor>, F>> FT apply( + Function>, ? extends FB> fn, HMap hmap) { + return lens.apply(fn, hmap); + } + }; } static Schema> schema(TypeSafeKey aKey, diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hmap/TypeSafeKey.java b/src/main/java/com/jnape/palatable/lambda/adt/hmap/TypeSafeKey.java index e07936a2f..2ee0c6622 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hmap/TypeSafeKey.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hmap/TypeSafeKey.java @@ -24,7 +24,7 @@ public interface TypeSafeKey extends Iso.Simple { @Override - default TypeSafeKey discardR(Applicative> appB) { + default TypeSafeKey discardR(Applicative>> appB) { Iso.Simple discarded = Iso.Simple.super.discardR(appB); return new TypeSafeKey() { @Override @@ -95,6 +95,11 @@ static Simple typeSafeKey() { public boolean equals(Object obj) { return obj instanceof Simple ? this == obj : Objects.equals(obj, this); } + + @Override + public int hashCode() { + return super.hashCode(); + } }; } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java index 9bff01745..6384641a8 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java @@ -97,9 +97,11 @@ default Fn1 zip(Fn2 appFn) { /** * {@inheritDoc} + * @param lazyAppFn */ @Override - default Lazy> lazyZip(Lazy, Fn1>> lazyAppFn) { + default Lazy> lazyZip( + Lazy, Fn1>> lazyAppFn) { return Monad.super.lazyZip(lazyAppFn).fmap(Monad>::coerce); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Cycle.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Cycle.java index 10fd2039b..df61e9fa0 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Cycle.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Cycle.java @@ -33,6 +33,7 @@ public static Iterable cycle(Iterable as) { } @SafeVarargs + @SuppressWarnings("varargs") public static Iterable cycle(A... as) { return cycle(asList(as)); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Upcast.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Upcast.java index 08f6fe519..89cfaa864 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Upcast.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Upcast.java @@ -22,7 +22,7 @@ */ public final class Upcast implements Fn1 { - private static final Upcast INSTANCE = new Upcast<>(); + private static final Upcast INSTANCE = new Upcast<>(); private Upcast() { } @@ -34,7 +34,7 @@ public B apply(A a) { @SuppressWarnings("unchecked") public static Upcast upcast() { - return INSTANCE; + return (Upcast) INSTANCE; } public static B upcast(A a) { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/Kleisli.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/Kleisli.java index 9157c8e44..4fae5b021 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/Kleisli.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/specialized/Kleisli.java @@ -25,6 +25,7 @@ public interface Kleisli, MB extends Monad> ex * @param the {@link Monad} instance to return * @return the composition of the two arrows as a new {@link Kleisli} arrow */ + @SuppressWarnings("overloads") default > Kleisli andThen(Kleisli after) { return a -> apply(a).flatMap(after).coerce(); } @@ -37,6 +38,7 @@ default > Kleisli andThen(Kleisli the {@link Monad} instance to flatMap with this arrow * @return the composition of the two arrows as a new {@link Kleisli} arrow */ + @SuppressWarnings("overloads") default > Kleisli compose(Kleisli before) { return z -> before.apply(z).flatMap(this).coerce(); } diff --git a/src/main/java/com/jnape/palatable/lambda/functor/Applicative.java b/src/main/java/com/jnape/palatable/lambda/functor/Applicative.java index 1f31e2ff3..9bd495727 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/Applicative.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/Applicative.java @@ -54,14 +54,14 @@ public interface Applicative> extends Functor * using whatever application semantics the current applicative supports. This is useful for applicatives that * support lazy evaluation and early termination. * - * @param lazyAppFn the lazy other applicative instance * @param the resulting applicative parameter type + * @param lazyAppFn the lazy other applicative instance * @return the mapped applicative * @see com.jnape.palatable.lambda.adt.Maybe * @see com.jnape.palatable.lambda.adt.Either */ default Lazy> lazyZip( - Lazy, App>> lazyAppFn) { + Lazy, App>> lazyAppFn) { return lazyAppFn.fmap(this::zip); } diff --git a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Compose.java b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Compose.java index 5a08211dc..df6d857c2 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Compose.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Compose.java @@ -22,8 +22,9 @@ public Compose(Applicative, F> fga) { this.fga = fga; } + @SuppressWarnings("RedundantTypeArguments") public , FGA extends Applicative> FGA getCompose() { - return fga.fmap(Applicative::coerce).coerce(); + return fga.fmap(Applicative::coerce).coerce(); } /** @@ -47,16 +48,19 @@ public Compose pure(B b) { */ @Override public Compose zip(Applicative, Compose> appFn) { - return new Compose<>(fga.zip(appFn.>>coerce().getCompose().fmap(gFn -> g -> g.zip(gFn)))); + return new Compose<>(fga.zip(appFn.>>coerce() + .getCompose().fmap(gFn -> g -> g.zip(gFn)))); } /** * {@inheritDoc} + * + * @param lazyAppFn */ @Override public Lazy> lazyZip( - Lazy, Compose>> lazyAppFn) { - return Applicative.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); + Lazy, Compose>> lazyAppFn) { + return Applicative.super.lazyZip(lazyAppFn).fmap(Applicative>::coerce); } /** diff --git a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Const.java b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Const.java index fdb81f8ef..220c41598 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Const.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Const.java @@ -66,10 +66,13 @@ public Const zip(Applicative, Const Lazy> lazyZip(Lazy, Const>> lazyAppFn) { - return Monad.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); + public Lazy> lazyZip( + Lazy, Const>> lazyAppFn) { + return Monad.super.lazyZip(lazyAppFn).fmap(Monad>::coerce); } /** diff --git a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Identity.java b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Identity.java index f5beb02c9..6ade25ffa 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Identity.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Identity.java @@ -63,10 +63,13 @@ public Identity zip(Applicative, Identit /** * {@inheritDoc} + * + * @param lazyAppFn */ @Override - public Lazy> lazyZip(Lazy, Identity>> lazyAppFn) { - return Monad.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); + public Lazy> lazyZip( + Lazy, Identity>> lazyAppFn) { + return Monad.super.lazyZip(lazyAppFn).fmap(Monad>::coerce); } /** diff --git a/src/main/java/com/jnape/palatable/lambda/io/IO.java b/src/main/java/com/jnape/palatable/lambda/io/IO.java index 7c21845a2..a9d735bc0 100644 --- a/src/main/java/com/jnape/palatable/lambda/io/IO.java +++ b/src/main/java/com/jnape/palatable/lambda/io/IO.java @@ -122,10 +122,12 @@ public final IO zip(Applicative, IO> /** * {@inheritDoc} + * + * @param lazyAppFn */ @Override - public Lazy> lazyZip(Lazy, IO>> lazyAppFn) { - return Monad.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); + public Lazy> lazyZip(Lazy, IO>> lazyAppFn) { + return Monad.super.lazyZip(lazyAppFn).fmap(Monad>::coerce); } /** diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/IterationInterruptedException.java b/src/main/java/com/jnape/palatable/lambda/iteration/IterationInterruptedException.java index 69b26f335..ed3308961 100644 --- a/src/main/java/com/jnape/palatable/lambda/iteration/IterationInterruptedException.java +++ b/src/main/java/com/jnape/palatable/lambda/iteration/IterationInterruptedException.java @@ -9,6 +9,7 @@ * * @see RateLimit */ +@SuppressWarnings("serial") public final class IterationInterruptedException extends RuntimeException { public IterationInterruptedException(InterruptedException cause) { diff --git a/src/main/java/com/jnape/palatable/lambda/lens/Iso.java b/src/main/java/com/jnape/palatable/lambda/lens/Iso.java index 7d7be3d3c..bc3e76389 100644 --- a/src/main/java/com/jnape/palatable/lambda/lens/Iso.java +++ b/src/main/java/com/jnape/palatable/lambda/lens/Iso.java @@ -50,7 +50,7 @@ * @param the smaller type for mirrored focusing */ @FunctionalInterface -public interface Iso extends LensLike { +public interface Iso extends LensLike> {

+ * While any two {@link com.jnape.palatable.lambda.functor.Functor functors} and any two + * {@link Applicative applicatives} can be composed in general, the same is not true in general of any two + * {@link Monad monads}. However, there exist {@link Monad monads} that do compose, in general, with any other + * {@link Monad}, provided that they are embedded inside the other {@link Monad}. When this is the case, they can offer + * implementations of {@link Monad#pure pure} and {@link Monad#flatMap(Function) flatMap} for free, simply by relying + * on the outer {@link Monad monad's} implementation of both, as well as their own privileged knowledge about how to + * merge the nested {@link Monad#flatMap(Function) flatMap} call. + *

+ * The term "monad transformer" describes a particular encoding of monadic composition. Because this general composition + * of a particular {@link Monad} with any other {@link Monad} relies on privileged knowledge about the embedded + * {@link Monad}, the {@link MonadT transformer} representing this compositions is described from the embedded + * {@link Monad monad's} perspective (e.g. {@link MaybeT} describing the embedding + * {@link Monad}<{@link com.jnape.palatable.lambda.adt.Maybe}<A>>). + *

+ * Additionally, monad transformers connected by compatible {@link Monad monads} also compose. When two or more monad + * transformers are composed, this is generally referred to as a "monad transformer stack". + *

+ * For more information, read more about + * monad transformers. + * + * @param the outer {@link Monad monad} + * @param the inner {@link Monad monad} + * @param the carrier type + * @see MaybeT + */ +public interface MonadT, G extends Monad, A> + extends Monad> { + + /** + * Extract out the composed monad out of this transformer. + * + * @param the inferred embedded monad + * @param the inferred composed monad + * @return the composed monad + */ + , FGA extends Monad> FGA run(); + + /** + * {@inheritDoc} + */ + @Override + MonadT flatMap(Function>> f); + + /** + * {@inheritDoc} + */ + @Override + MonadT pure(B b); + + /** + * {@inheritDoc} + */ + @Override + default MonadT fmap(Function fn) { + return Monad.super.fmap(fn).coerce(); + } + + /** + * {@inheritDoc} + */ + @Override + default MonadT zip(Applicative, MonadT> appFn) { + return Monad.super.zip(appFn).coerce(); + } + + /** + * {@inheritDoc} + */ + @Override + default Lazy> lazyZip( + Lazy, MonadT>> lazyAppFn) { + return Monad.super.lazyZip(lazyAppFn).fmap(Monad>::coerce); + } + + /** + * {@inheritDoc} + */ + @Override + default MonadT discardL(Applicative> appB) { + return Monad.super.discardL(appB).coerce(); + } + + /** + * {@inheritDoc} + */ + @Override + default MonadT discardR(Applicative> appB) { + return Monad.super.discardR(appB).coerce(); + } +} diff --git a/src/test/java/com/jnape/palatable/lambda/monad/transformer/MaybeTTest.java b/src/test/java/com/jnape/palatable/lambda/monad/transformer/MaybeTTest.java new file mode 100644 index 000000000..f39c40ff1 --- /dev/null +++ b/src/test/java/com/jnape/palatable/lambda/monad/transformer/MaybeTTest.java @@ -0,0 +1,41 @@ +package com.jnape.palatable.lambda.monad.transformer; + +import com.jnape.palatable.lambda.adt.Either; +import com.jnape.palatable.traitor.annotations.TestTraits; +import com.jnape.palatable.traitor.framework.Subjects; +import com.jnape.palatable.traitor.runners.Traits; +import org.junit.Test; +import org.junit.runner.RunWith; +import testsupport.traits.ApplicativeLaws; +import testsupport.traits.FunctorLaws; +import testsupport.traits.MonadLaws; + +import static com.jnape.palatable.lambda.adt.Either.left; +import static com.jnape.palatable.lambda.adt.Either.right; +import static com.jnape.palatable.lambda.adt.Maybe.just; +import static com.jnape.palatable.lambda.adt.Maybe.nothing; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; +import static com.jnape.palatable.lambda.monad.transformer.MaybeT.maybeT; +import static com.jnape.palatable.traitor.framework.Subjects.subjects; +import static org.junit.Assert.assertEquals; + +@RunWith(Traits.class) +public class MaybeTTest { + + @TestTraits({FunctorLaws.class, ApplicativeLaws.class, MonadLaws.class}) + public Subjects, Integer>> testSubject() { + return subjects(maybeT(right(just(1))), + maybeT(right(nothing())), + maybeT(left("foo"))); + } + + @Test + public void lazyZip() { + assertEquals(maybeT(right(just(2))), + maybeT(right(just(1))).lazyZip(lazy(maybeT(right(just(x -> x + 1))))).value()); + assertEquals(maybeT(left("foo")), + maybeT(left("foo")).lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + } +} \ No newline at end of file From ea2cc49f963a5f7a2477ee8cbf943d9c6c35c32b Mon Sep 17 00:00:00 2001 From: jnape Date: Wed, 17 Apr 2019 20:10:40 -0500 Subject: [PATCH 13/69] Endo, a monoid for fn1 using composition --- CHANGELOG.md | 1 + .../palatable/lambda/monoid/builtin/Endo.java | 57 +++++++++++++++++++ .../lambda/semigroup/builtin/EndoTest.java | 21 +++++++ 3 files changed, 79 insertions(+) create mode 100644 src/main/java/com/jnape/palatable/lambda/monoid/builtin/Endo.java create mode 100644 src/test/java/com/jnape/palatable/lambda/semigroup/builtin/EndoTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index bf372699b..753f944bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ might need to be reworked, and subtyping is obviously no longer supported. - `Applicative#lazyZip`, for zipping two applicatives in a way that might not require evaluation of one applicative - `MonadT`, a general interface representing monad transformers - `MaybeT`, a monad transformer for `Maybe` +- `Endo`, a monoid formed by `Fn1` under composition ## [3.3.0] - 2019-02-18 ### Added diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Endo.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Endo.java new file mode 100644 index 000000000..a5f1fcc0d --- /dev/null +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Endo.java @@ -0,0 +1,57 @@ +package com.jnape.palatable.lambda.monoid.builtin; + +import com.jnape.palatable.lambda.functions.Fn1; +import com.jnape.palatable.lambda.functions.Fn2; +import com.jnape.palatable.lambda.monoid.Monoid; + +import static com.jnape.palatable.lambda.functions.Fn2.fn2; +import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id; + +/** + * A {@link Monoid} formed by {@link Fn1} under composition. + * + * @param the input/output type to the {@link Fn1} + */ +public final class Endo implements Monoid> { + + private static final Endo INSTANCE = new Endo<>(); + + private Endo() { + } + + @Override + public Fn1 identity() { + return id(); + } + + public A apply(Fn1 f, Fn1 g, A a) { + return apply(f, g).apply(a); + } + + @Override + public Fn1 apply(Fn1 f, Fn1 g) { + return f.fmap(g); + } + + @Override + public Fn2, A, A> apply(Fn1 f) { + return fn2(Monoid.super.apply(f)); + } + + @SuppressWarnings("unchecked") + public static Endo endo() { + return (Endo) INSTANCE; + } + + public static Fn2, A, A> endo(Fn1 f) { + return Endo.endo().apply(f); + } + + public static Fn1 endo(Fn1 f, Fn1 g) { + return endo(f).apply(g); + } + + public static A endo(Fn1 f, Fn1 g, A a) { + return endo(f, g).apply(a); + } +} diff --git a/src/test/java/com/jnape/palatable/lambda/semigroup/builtin/EndoTest.java b/src/test/java/com/jnape/palatable/lambda/semigroup/builtin/EndoTest.java new file mode 100644 index 000000000..4da982462 --- /dev/null +++ b/src/test/java/com/jnape/palatable/lambda/semigroup/builtin/EndoTest.java @@ -0,0 +1,21 @@ +package com.jnape.palatable.lambda.semigroup.builtin; + +import com.jnape.palatable.lambda.monoid.builtin.Endo; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class EndoTest { + + @Test + public void identity() { + assertEquals((Integer) 1, Endo.endo().identity().apply(1)); + } + + @Test + public void semigroup() { + assertEquals((Integer) 2, Endo.endo().apply(x -> x + 1, x -> x + 1).apply(0)); + assertEquals((Integer) 2, Endo.endo().apply(x -> x + 1, x -> x + 1, 0)); + assertEquals((Integer) 2, Endo.endo(x -> x + 1, x -> x + 1, 0)); + } +} \ No newline at end of file From 0b7a3f2ec104aedda73bc6a644ea9319ed657728 Mon Sep 17 00:00:00 2001 From: jnape Date: Wed, 17 Apr 2019 21:48:16 -0500 Subject: [PATCH 14/69] EItherT, a monad transformer for Either --- CHANGELOG.md | 1 + .../lambda/monad/transformer/MonadT.java | 1 + .../monad/transformer/builtin/EitherT.java | 121 ++++++++++++++++++ .../transformer/{ => builtin}/MaybeT.java | 3 +- .../transformer/builtin/EitherTTest.java | 39 ++++++ .../transformer/{ => builtin}/MaybeTTest.java | 5 +- 6 files changed, 167 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/EitherT.java rename src/main/java/com/jnape/palatable/lambda/monad/transformer/{ => builtin}/MaybeT.java (96%) create mode 100644 src/test/java/com/jnape/palatable/lambda/monad/transformer/builtin/EitherTTest.java rename src/test/java/com/jnape/palatable/lambda/monad/transformer/{ => builtin}/MaybeTTest.java (87%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 753f944bf..284d3bfbf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ might need to be reworked, and subtyping is obviously no longer supported. - `Applicative#lazyZip`, for zipping two applicatives in a way that might not require evaluation of one applicative - `MonadT`, a general interface representing monad transformers - `MaybeT`, a monad transformer for `Maybe` +- `EitherT`, a monad transformer for `Either` - `Endo`, a monoid formed by `Fn1` under composition ## [3.3.0] - 2019-02-18 diff --git a/src/main/java/com/jnape/palatable/lambda/monad/transformer/MonadT.java b/src/main/java/com/jnape/palatable/lambda/monad/transformer/MonadT.java index 8098d2ba6..1afb4d426 100644 --- a/src/main/java/com/jnape/palatable/lambda/monad/transformer/MonadT.java +++ b/src/main/java/com/jnape/palatable/lambda/monad/transformer/MonadT.java @@ -3,6 +3,7 @@ import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; +import com.jnape.palatable.lambda.monad.transformer.builtin.MaybeT; import java.util.function.Function; diff --git a/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/EitherT.java b/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/EitherT.java new file mode 100644 index 000000000..592bd6b9f --- /dev/null +++ b/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/EitherT.java @@ -0,0 +1,121 @@ +package com.jnape.palatable.lambda.monad.transformer.builtin; + +import com.jnape.palatable.lambda.adt.Either; +import com.jnape.palatable.lambda.functor.Applicative; +import com.jnape.palatable.lambda.functor.builtin.Compose; +import com.jnape.palatable.lambda.functor.builtin.Lazy; +import com.jnape.palatable.lambda.monad.Monad; +import com.jnape.palatable.lambda.monad.transformer.MonadT; + +import java.util.Objects; +import java.util.function.Function; + +import static com.jnape.palatable.lambda.adt.Either.left; +import static com.jnape.palatable.lambda.adt.Either.right; + +/** + * A {@link MonadT monad transformer} for {@link Either}. + * + * @param the outer {@link Monad} + * @param the left type + * @param the right type + */ +public final class EitherT, L, R> implements MonadT, R> { + + private final Monad, M> melr; + + private EitherT(Monad, M> melr) { + this.melr = melr; + } + + /** + * {@inheritDoc} + */ + @Override + public >, FGA extends Monad> FGA run() { + return melr.fmap(Either::coerce).coerce(); + } + + /** + * {@inheritDoc} + */ + @Override + public EitherT flatMap(Function, ?>>> f) { + return eitherT(melr.flatMap(lr -> lr.match(l -> melr.pure(left(l)), + r -> f.apply(r).>coerce().run()))); + } + + /** + * {@inheritDoc} + */ + @Override + public EitherT pure(R2 r2) { + return eitherT(melr.pure(right(r2))); + } + + /** + * {@inheritDoc} + */ + @Override + public EitherT fmap(Function fn) { + return MonadT.super.fmap(fn).coerce(); + } + + /** + * {@inheritDoc} + */ + @Override + public EitherT zip( + Applicative, MonadT, ?>> appFn) { + return MonadT.super.zip(appFn).coerce(); + } + + /** + * {@inheritDoc} + */ + @Override + public Lazy> lazyZip( + Lazy, MonadT, ?>>> lazyAppFn) { + return new Compose<>(melr) + .lazyZip(lazyAppFn.fmap(maybeT -> new Compose<>( + maybeT.>>coerce() + .>, + Monad>, M>>run()))) + .fmap(compose -> eitherT(compose.getCompose())); + } + + /** + * {@inheritDoc} + */ + @Override + public EitherT discardL(Applicative, ?>> appB) { + return MonadT.super.discardL(appB).coerce(); + } + + /** + * {@inheritDoc} + */ + @Override + public EitherT discardR(Applicative, ?>> appB) { + return MonadT.super.discardR(appB).coerce(); + } + + @Override + public boolean equals(Object other) { + return other instanceof EitherT && Objects.equals(melr, ((EitherT) other).melr); + } + + @Override + public int hashCode() { + return Objects.hash(melr); + } + + @Override + public String toString() { + return "EitherT{melr=" + melr + '}'; + } + + public static , L, R> EitherT eitherT(Monad, M> melr) { + return new EitherT<>(melr); + } +} diff --git a/src/main/java/com/jnape/palatable/lambda/monad/transformer/MaybeT.java b/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/MaybeT.java similarity index 96% rename from src/main/java/com/jnape/palatable/lambda/monad/transformer/MaybeT.java rename to src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/MaybeT.java index afbf56721..3d765ad1b 100644 --- a/src/main/java/com/jnape/palatable/lambda/monad/transformer/MaybeT.java +++ b/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/MaybeT.java @@ -1,10 +1,11 @@ -package com.jnape.palatable.lambda.monad.transformer; +package com.jnape.palatable.lambda.monad.transformer.builtin; import com.jnape.palatable.lambda.adt.Maybe; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.builtin.Compose; import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; +import com.jnape.palatable.lambda.monad.transformer.MonadT; import java.util.Objects; import java.util.function.Function; diff --git a/src/test/java/com/jnape/palatable/lambda/monad/transformer/builtin/EitherTTest.java b/src/test/java/com/jnape/palatable/lambda/monad/transformer/builtin/EitherTTest.java new file mode 100644 index 000000000..b5d717b69 --- /dev/null +++ b/src/test/java/com/jnape/palatable/lambda/monad/transformer/builtin/EitherTTest.java @@ -0,0 +1,39 @@ +package com.jnape.palatable.lambda.monad.transformer.builtin; + +import com.jnape.palatable.lambda.functor.builtin.Identity; +import com.jnape.palatable.traitor.annotations.TestTraits; +import com.jnape.palatable.traitor.framework.Subjects; +import com.jnape.palatable.traitor.runners.Traits; +import org.junit.Test; +import org.junit.runner.RunWith; +import testsupport.traits.ApplicativeLaws; +import testsupport.traits.FunctorLaws; +import testsupport.traits.MonadLaws; + +import static com.jnape.palatable.lambda.adt.Either.left; +import static com.jnape.palatable.lambda.adt.Either.right; +import static com.jnape.palatable.lambda.adt.Maybe.just; +import static com.jnape.palatable.lambda.adt.Maybe.nothing; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; +import static com.jnape.palatable.lambda.monad.transformer.builtin.EitherT.eitherT; +import static com.jnape.palatable.traitor.framework.Subjects.subjects; +import static org.junit.Assert.assertEquals; + +@RunWith(Traits.class) +public class EitherTTest { + + @TestTraits({FunctorLaws.class, ApplicativeLaws.class, MonadLaws.class}) + public Subjects, String, Integer>> testSubject() { + return subjects(eitherT(new Identity<>(left("foo"))), eitherT(new Identity<>(right(1)))); + } + + @Test + public void lazyZip() { + assertEquals(eitherT(just(right(2))), + eitherT(just(right(1))).lazyZip(lazy(eitherT(just(right(x -> x + 1))))).value()); + assertEquals(eitherT(nothing()), + eitherT(nothing()).lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + } +} \ No newline at end of file diff --git a/src/test/java/com/jnape/palatable/lambda/monad/transformer/MaybeTTest.java b/src/test/java/com/jnape/palatable/lambda/monad/transformer/builtin/MaybeTTest.java similarity index 87% rename from src/test/java/com/jnape/palatable/lambda/monad/transformer/MaybeTTest.java rename to src/test/java/com/jnape/palatable/lambda/monad/transformer/builtin/MaybeTTest.java index f39c40ff1..8060ce8b3 100644 --- a/src/test/java/com/jnape/palatable/lambda/monad/transformer/MaybeTTest.java +++ b/src/test/java/com/jnape/palatable/lambda/monad/transformer/builtin/MaybeTTest.java @@ -1,6 +1,7 @@ -package com.jnape.palatable.lambda.monad.transformer; +package com.jnape.palatable.lambda.monad.transformer.builtin; import com.jnape.palatable.lambda.adt.Either; +import com.jnape.palatable.lambda.monad.transformer.builtin.MaybeT; import com.jnape.palatable.traitor.annotations.TestTraits; import com.jnape.palatable.traitor.framework.Subjects; import com.jnape.palatable.traitor.runners.Traits; @@ -15,7 +16,7 @@ import static com.jnape.palatable.lambda.adt.Maybe.just; import static com.jnape.palatable.lambda.adt.Maybe.nothing; import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; -import static com.jnape.palatable.lambda.monad.transformer.MaybeT.maybeT; +import static com.jnape.palatable.lambda.monad.transformer.builtin.MaybeT.maybeT; import static com.jnape.palatable.traitor.framework.Subjects.subjects; import static org.junit.Assert.assertEquals; From bf890a27eef62b86f0022aa057caaf2b3e54d65f Mon Sep 17 00:00:00 2001 From: jnape Date: Fri, 19 Apr 2019 17:22:28 -0500 Subject: [PATCH 15/69] Adding the State monad --- CHANGELOG.md | 1 + .../lambda/functor/builtin/State.java | 215 ++++++++++++++++++ .../lambda/functor/builtin/StateTest.java | 83 +++++++ 3 files changed, 299 insertions(+) create mode 100644 src/main/java/com/jnape/palatable/lambda/functor/builtin/State.java create mode 100644 src/test/java/com/jnape/palatable/lambda/functor/builtin/StateTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 284d3bfbf..f00e30a94 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ might need to be reworked, and subtyping is obviously no longer supported. - `MaybeT`, a monad transformer for `Maybe` - `EitherT`, a monad transformer for `Either` - `Endo`, a monoid formed by `Fn1` under composition +- `State`, the state `Monad` ## [3.3.0] - 2019-02-18 ### Added diff --git a/src/main/java/com/jnape/palatable/lambda/functor/builtin/State.java b/src/main/java/com/jnape/palatable/lambda/functor/builtin/State.java new file mode 100644 index 000000000..68de3685d --- /dev/null +++ b/src/main/java/com/jnape/palatable/lambda/functor/builtin/State.java @@ -0,0 +1,215 @@ +package com.jnape.palatable.lambda.functor.builtin; + +import com.jnape.palatable.lambda.adt.Unit; +import com.jnape.palatable.lambda.adt.hlist.HList; +import com.jnape.palatable.lambda.adt.hlist.Tuple2; +import com.jnape.palatable.lambda.adt.product.Product2; +import com.jnape.palatable.lambda.functions.Fn1; +import com.jnape.palatable.lambda.functor.Applicative; +import com.jnape.palatable.lambda.monad.Monad; + +import java.util.function.Function; + +import static com.jnape.palatable.lambda.adt.Unit.UNIT; +import static com.jnape.palatable.lambda.adt.hlist.HList.tuple; +import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; +import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id; +import static com.jnape.palatable.lambda.functions.builtin.fn2.Both.both; +import static com.jnape.palatable.lambda.functions.builtin.fn2.Into.into; + +/** + * The state {@link Monad}, useful for iteratively building up state and state-contextualized result. + *

+ * For more information, read about the + * state monad. + * + * @param the state type + * @param the result type + */ +public final class State implements Monad> { + + private final Fn1> stateFn; + + private State(Fn1> stateFn) { + this.stateFn = stateFn; + } + + /** + * Run the stateful computation, returning a {@link Tuple2} of the result and the final state. + * + * @param s the initial state + * @return a {@link Tuple2} of the result and the final state. + */ + public Tuple2 run(S s) { + return stateFn.apply(s).into(HList::tuple); + } + + /** + * Run the stateful computation, returning the result. + * + * @param s the initial state + * @return the result + */ + public A eval(S s) { + return run(s)._1(); + } + + /** + * Run the stateful computation, returning the final state. + * + * @param s the initial state + * @return the final state + */ + public S exec(S s) { + return run(s)._2(); + } + + /** + * Map both the result and the final state to a new result and final state. + * + * @param fn the mapping function + * @param the potentially new final state type + * @return the mapped {@link State} + */ + public State mapState(Fn1, ? extends Product2> fn) { + return state(s -> fn.apply(run(s))); + } + + /** + * Map the final state to a new final state using the provided function. + * + * @param fn the state-mapping function + * @return the mapped {@link State} + */ + public State withState(Fn1 fn) { + return state(s -> run(fn.apply(s))); + } + + /** + * {@inheritDoc} + */ + @Override + public State flatMap(Function>> f) { + return state(s -> run(s).into((a, s2) -> f.apply(a).>coerce().run(s2))); + } + + /** + * {@inheritDoc} + */ + @Override + public State pure(B b) { + return state(s -> tuple(b, s)); + } + + /** + * {@inheritDoc} + */ + @Override + public State fmap(Function fn) { + return Monad.super.fmap(fn).coerce(); + } + + /** + * {@inheritDoc} + */ + @Override + public State zip(Applicative, State> appFn) { + return Monad.super.zip(appFn).coerce(); + } + + /** + * {@inheritDoc} + */ + @Override + public Lazy> lazyZip( + Lazy, State>> lazyAppFn) { + return Monad.super.lazyZip(lazyAppFn).fmap(Monad>::coerce); + } + + /** + * {@inheritDoc} + */ + @Override + public State discardR(Applicative> appB) { + return Monad.super.discardR(appB).coerce(); + } + + /** + * {@inheritDoc} + */ + @Override + public State discardL(Applicative> appB) { + return Monad.super.discardL(appB).coerce(); + } + + /** + * Create a {@link State} that simply returns back the initial state as both the result and the final state + * + * @param the state and result type + * @return the new {@link State} instance + */ + @SuppressWarnings("RedundantTypeArguments") + public static State get() { + return new State<>(Tuple2::fill); + } + + /** + * Create a {@link State} that ignores its initial state, returning a {@link Unit} result and s as its + * final state. + * + * @param s the final state + * @param the state type + * @return the new {@link State} instance + */ + public static State put(S s) { + return new State<>(constantly(tuple(UNIT, s))); + } + + /** + * Create a {@link State} that maps its initial state into its result, but leaves the initial state unchanged. + * + * @param fn the mapping function + * @param the state type + * @param the result type + * @return the new {@link State} instance + */ + public static State gets(Fn1 fn) { + return state(both(fn, id())); + } + + /** + * Create a {@link State} that maps its initial state into its final state, returning a {@link Unit} result type. + * + * @param fn the mapping function + * @param the state type + * @return the new {@link State} instance + */ + public static State modify(Fn1 fn) { + return state(both(constantly(UNIT), fn)); + } + + /** + * Create a {@link State} from stateFn, a function that maps an initial state into a result and a final + * state. + * + * @param stateFn the state function + * @param the state type + * @param the result type + * @return the new {@link State} instance + */ + public static State state(Fn1> stateFn) { + return new State<>(stateFn.fmap(into(HList::tuple))); + } + + /** + * Create a {@link State} that returns a as its result and its initial state as its final state. + * + * @param a the result + * @param the state type + * @param the result type + * @return the new {@link State} instance + */ + public static State state(A a) { + return gets(constantly(a)); + } +} diff --git a/src/test/java/com/jnape/palatable/lambda/functor/builtin/StateTest.java b/src/test/java/com/jnape/palatable/lambda/functor/builtin/StateTest.java new file mode 100644 index 000000000..f2071a27e --- /dev/null +++ b/src/test/java/com/jnape/palatable/lambda/functor/builtin/StateTest.java @@ -0,0 +1,83 @@ +package com.jnape.palatable.lambda.functor.builtin; + +import com.jnape.palatable.lambda.adt.Unit; +import com.jnape.palatable.lambda.adt.hlist.HList; +import com.jnape.palatable.traitor.annotations.TestTraits; +import com.jnape.palatable.traitor.runners.Traits; +import org.junit.Test; +import org.junit.runner.RunWith; +import testsupport.EquatableM; +import testsupport.traits.ApplicativeLaws; +import testsupport.traits.FunctorLaws; +import testsupport.traits.MonadLaws; + +import static com.jnape.palatable.lambda.adt.Unit.UNIT; +import static com.jnape.palatable.lambda.adt.hlist.HList.tuple; +import static com.jnape.palatable.lambda.adt.product.Product2.product; +import static com.jnape.palatable.lambda.functions.builtin.fn2.Into.into; +import static org.junit.Assert.assertEquals; + +@RunWith(Traits.class) +public class StateTest { + + @TestTraits({FunctorLaws.class, ApplicativeLaws.class, MonadLaws.class}) + public EquatableM, Unit> testSubject() { + return new EquatableM<>(State.get(), state -> state.run(UNIT).into(HList::tuple)); + } + + @Test + public void eval() { + State state = State.put(0); + assertEquals(state.run(1)._1(), state.eval(1)); + } + + @Test + public void exec() { + State state = State.put(0); + assertEquals(state.run(1)._2(), state.exec(1)); + } + + @Test + public void get() { + assertEquals(tuple(1, 1), State.get().run(1)); + } + + @Test + public void put() { + assertEquals(tuple(UNIT, 1), State.put(1).run(1)); + } + + @Test + public void gets() { + assertEquals(tuple(0, "0"), State.gets(Integer::parseInt).run("0")); + } + + @Test + public void modify() { + assertEquals(tuple(UNIT, 1), State.modify(x -> x + 1).run(0)); + } + + @Test + public void state() { + assertEquals(tuple(1, UNIT), State.state(1).run(UNIT)); + assertEquals(tuple(1, -1), State.state(x -> product(x + 1, x - 1)).run(0)); + } + + @Test + public void stateAccumulation() { + State counter = State.get().flatMap(i -> State.put(i + 1).discardL(State.state(i))); + assertEquals(tuple(0, 1), counter.run(0)); + } + + @Test + public void withState() { + State modified = State.get().withState(x -> x + 1); + assertEquals(tuple(1, 1), modified.run(0)); + } + + @Test + public void mapState() { + State modified = State.get().mapState(into((a, s) -> product(a + 1, s + 2))); + assertEquals(tuple(1, 2), modified.run(0)); + } +} \ No newline at end of file From 2f04d024cb7c093c27499e8eb1a9c312624dd6ae Mon Sep 17 00:00:00 2001 From: jnape Date: Fri, 19 Apr 2019 17:37:28 -0500 Subject: [PATCH 16/69] Adding Gitter badge to README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d4c933638..476f89ebc 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ ====== [![Build Status](https://img.shields.io/travis/palatable/lambda/master.svg)](https://travis-ci.org/palatable/lambda) [![Lambda](https://img.shields.io/maven-central/v/com.jnape.palatable/lambda.svg)](http://search.maven.org/#search%7Cga%7C1%7Ccom.jnape.palatable.lambda) +[![Join the chat at https://gitter.im/palatable/lambda](https://badges.gitter.im/palatable/lambda.svg)](https://gitter.im/palatable/lambda?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) Functional patterns for Java From 5186c1164bdd49bb095a012c2e5a8a9f544fdaed Mon Sep 17 00:00:00 2001 From: jnape Date: Fri, 19 Apr 2019 18:06:14 -0500 Subject: [PATCH 17/69] Even more new javac warnings --- .../lambda/iteration/MappingIterable.java | 15 ++++++++------- .../lambda/iteration/UnfoldingIterator.java | 1 - .../palatable/lambda/functor/BifunctorTest.java | 4 ++-- .../palatable/lambda/functor/ProfunctorTest.java | 4 ++-- .../lambda/iteration/DroppingIteratorTest.java | 2 +- .../lambda/iteration/ImmutableIteratorTest.java | 4 ++-- .../lambda/iteration/InfiniteIteratorTest.java | 4 ++-- .../lambda/iteration/ReversingIteratorTest.java | 4 +++- .../lambda/iteration/RewindableIteratorTest.java | 2 +- src/test/java/testsupport/Mocking.java | 5 +++-- .../InvocationRecordingBifunctor.java | 8 ++++---- .../InvocationRecordingProfunctor.java | 8 ++++---- .../exceptions/OutOfScopeException.java | 1 + .../matchers/FiniteIterableMatcher.java | 4 ++-- .../testsupport/matchers/IterableMatcher.java | 13 +++++++------ 15 files changed, 42 insertions(+), 37 deletions(-) diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/MappingIterable.java b/src/main/java/com/jnape/palatable/lambda/iteration/MappingIterable.java index 1730a6838..b65510f55 100644 --- a/src/main/java/com/jnape/palatable/lambda/iteration/MappingIterable.java +++ b/src/main/java/com/jnape/palatable/lambda/iteration/MappingIterable.java @@ -9,15 +9,15 @@ import static java.util.Collections.singletonList; public final class MappingIterable implements Iterable { - private final Iterable as; - private final List mappers; + private final Iterable as; + private final List> mappers; @SuppressWarnings("unchecked") public MappingIterable(Function fn, Iterable as) { - List mappers = new ArrayList<>(singletonList(fn)); - while (as instanceof MappingIterable) { + List> mappers = new ArrayList<>(singletonList(fn)); + while (as instanceof MappingIterable) { MappingIterable nested = (MappingIterable) as; - as = (Iterable) nested.as; + as = (Iterable) nested.as; mappers.addAll(0, nested.mappers); } this.as = as; @@ -27,7 +27,8 @@ public MappingIterable(Function fn, Iterable as) { @Override @SuppressWarnings("unchecked") public Iterator iterator() { - Function fnComposedOnTheHeap = o -> foldLeft((x, fn) -> fn.apply(x), o, mappers); - return new MappingIterator<>(fnComposedOnTheHeap, as.iterator()); + Function fnComposedOnTheHeap = a -> foldLeft((x, fn) -> ((Function) fn).apply(x), + a, mappers); + return new MappingIterator<>((Function) fnComposedOnTheHeap, as.iterator()); } } diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/UnfoldingIterator.java b/src/main/java/com/jnape/palatable/lambda/iteration/UnfoldingIterator.java index 418121c7c..0d014df81 100644 --- a/src/main/java/com/jnape/palatable/lambda/iteration/UnfoldingIterator.java +++ b/src/main/java/com/jnape/palatable/lambda/iteration/UnfoldingIterator.java @@ -27,7 +27,6 @@ public boolean hasNext() { } @Override - @SuppressWarnings("ConstantConditions") public A next() { if (!hasNext()) throw new NoSuchElementException(); diff --git a/src/test/java/com/jnape/palatable/lambda/functor/BifunctorTest.java b/src/test/java/com/jnape/palatable/lambda/functor/BifunctorTest.java index 4cb93cf08..bef359ebc 100644 --- a/src/test/java/com/jnape/palatable/lambda/functor/BifunctorTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functor/BifunctorTest.java @@ -14,7 +14,7 @@ public class BifunctorTest { @Test public void biMapLUsesIdentityForRightBiMapFunction() { - AtomicReference rightInvocation = new AtomicReference<>(); + AtomicReference> rightInvocation = new AtomicReference<>(); Bifunctor> bifunctor = new InvocationRecordingBifunctor<>(new AtomicReference<>(), rightInvocation); bifunctor.biMapL(String::toUpperCase); @@ -23,7 +23,7 @@ public void biMapLUsesIdentityForRightBiMapFunction() { @Test public void biMapRUsesIdentityForLeftBiMapFunction() { - AtomicReference leftInvocation = new AtomicReference<>(); + AtomicReference> leftInvocation = new AtomicReference<>(); Bifunctor> bifunctor = new InvocationRecordingBifunctor<>(leftInvocation, new AtomicReference<>()); bifunctor.biMapR(String::valueOf); diff --git a/src/test/java/com/jnape/palatable/lambda/functor/ProfunctorTest.java b/src/test/java/com/jnape/palatable/lambda/functor/ProfunctorTest.java index f2fb6980d..a6650b32a 100644 --- a/src/test/java/com/jnape/palatable/lambda/functor/ProfunctorTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functor/ProfunctorTest.java @@ -14,7 +14,7 @@ public class ProfunctorTest { @Test public void diMapLUsesIdentityForRightDiMapFunction() { - AtomicReference rightInvocation = new AtomicReference<>(); + AtomicReference> rightInvocation = new AtomicReference<>(); Profunctor> profunctor = new InvocationRecordingProfunctor<>(new AtomicReference<>(), rightInvocation); profunctor.diMapL(Object::toString); @@ -23,7 +23,7 @@ public void diMapLUsesIdentityForRightDiMapFunction() { @Test public void diMapRUsesIdentityForLeftDiMapFunction() { - AtomicReference leftInvocation = new AtomicReference<>(); + AtomicReference> leftInvocation = new AtomicReference<>(); Profunctor> profunctor = new InvocationRecordingProfunctor<>(leftInvocation, new AtomicReference<>()); profunctor.diMapR(String::valueOf); diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/DroppingIteratorTest.java b/src/test/java/com/jnape/palatable/lambda/iteration/DroppingIteratorTest.java index 0e28a2dd2..9bbdad7ad 100644 --- a/src/test/java/com/jnape/palatable/lambda/iteration/DroppingIteratorTest.java +++ b/src/test/java/com/jnape/palatable/lambda/iteration/DroppingIteratorTest.java @@ -17,7 +17,7 @@ public class DroppingIteratorTest { @Mock private Iterator iterator; - private DroppingIterator droppingIterator; + private DroppingIterator droppingIterator; @Before public void setUp() { diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/ImmutableIteratorTest.java b/src/test/java/com/jnape/palatable/lambda/iteration/ImmutableIteratorTest.java index d1ffc6ebd..da73c4aef 100644 --- a/src/test/java/com/jnape/palatable/lambda/iteration/ImmutableIteratorTest.java +++ b/src/test/java/com/jnape/palatable/lambda/iteration/ImmutableIteratorTest.java @@ -7,11 +7,11 @@ public class ImmutableIteratorTest { - private ImmutableIterator immutableIterator; + private ImmutableIterator immutableIterator; @Before public void setUp() { - immutableIterator = new ImmutableIterator() { + immutableIterator = new ImmutableIterator() { @Override public boolean hasNext() { throw outOfScope(); diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/InfiniteIteratorTest.java b/src/test/java/com/jnape/palatable/lambda/iteration/InfiniteIteratorTest.java index 9d9f8abd5..7ce772cf6 100644 --- a/src/test/java/com/jnape/palatable/lambda/iteration/InfiniteIteratorTest.java +++ b/src/test/java/com/jnape/palatable/lambda/iteration/InfiniteIteratorTest.java @@ -9,11 +9,11 @@ public class InfiniteIteratorTest { - private InfiniteIterator infiniteIterator; + private InfiniteIterator infiniteIterator; @Before public void setUp() { - infiniteIterator = new InfiniteIterator() { + infiniteIterator = new InfiniteIterator() { @Override public Object next() { throw outOfScope(); diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/ReversingIteratorTest.java b/src/test/java/com/jnape/palatable/lambda/iteration/ReversingIteratorTest.java index 754345bfb..391bcfb26 100644 --- a/src/test/java/com/jnape/palatable/lambda/iteration/ReversingIteratorTest.java +++ b/src/test/java/com/jnape/palatable/lambda/iteration/ReversingIteratorTest.java @@ -22,7 +22,7 @@ public class ReversingIteratorTest { @Mock private Iterator iterator; - private ReversingIterator reversingIterator; + private ReversingIterator reversingIterator; @Before public void setUp() { @@ -47,6 +47,7 @@ public void reversesIterator() { } @Test + @SuppressWarnings("ResultOfMethodCallIgnored") public void doesNotReverseUntilNextIsCalled() { reversingIterator.hasNext(); verify(iterator, never()).next(); @@ -63,6 +64,7 @@ public void doesNotHaveNextIfFinishedReversingIterator() { } @Test + @SuppressWarnings("ResultOfMethodCallIgnored") public void neverInteractsWithIteratorAgainAfterInitialReverse() { mockIteratorToHaveValues(iterator, 1, 2, 3); diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/RewindableIteratorTest.java b/src/test/java/com/jnape/palatable/lambda/iteration/RewindableIteratorTest.java index 3e1498b90..a8bee457c 100644 --- a/src/test/java/com/jnape/palatable/lambda/iteration/RewindableIteratorTest.java +++ b/src/test/java/com/jnape/palatable/lambda/iteration/RewindableIteratorTest.java @@ -18,7 +18,7 @@ public class RewindableIteratorTest { @Mock private Iterator iterator; - private RewindableIterator rewindableIterator; + private RewindableIterator rewindableIterator; @Before public void setUp() { diff --git a/src/test/java/testsupport/Mocking.java b/src/test/java/testsupport/Mocking.java index 041105a7b..cbc86cd7a 100644 --- a/src/test/java/testsupport/Mocking.java +++ b/src/test/java/testsupport/Mocking.java @@ -18,8 +18,9 @@ public static Iterable mockIterable() { } @SafeVarargs - public static void mockIteratorToHaveValues(Iterator iterator, T... values) { - Iterator real = asList(values).iterator(); + @SuppressWarnings("varargs") + public static void mockIteratorToHaveValues(Iterator iterator, T... values) { + Iterator real = asList(values).iterator(); when(iterator.hasNext()).then(delegateTo(real)); when(iterator.next()).then(delegateTo(real)); diff --git a/src/test/java/testsupport/applicatives/InvocationRecordingBifunctor.java b/src/test/java/testsupport/applicatives/InvocationRecordingBifunctor.java index 92565e2de..65ff38cba 100644 --- a/src/test/java/testsupport/applicatives/InvocationRecordingBifunctor.java +++ b/src/test/java/testsupport/applicatives/InvocationRecordingBifunctor.java @@ -6,11 +6,11 @@ import java.util.function.Function; public final class InvocationRecordingBifunctor implements Bifunctor> { - private final AtomicReference leftFn; - private final AtomicReference rightFn; + private final AtomicReference> leftFn; + private final AtomicReference> rightFn; - public InvocationRecordingBifunctor(AtomicReference leftFn, - AtomicReference rightFn) { + public InvocationRecordingBifunctor(AtomicReference> leftFn, + AtomicReference> rightFn) { this.leftFn = leftFn; this.rightFn = rightFn; } diff --git a/src/test/java/testsupport/applicatives/InvocationRecordingProfunctor.java b/src/test/java/testsupport/applicatives/InvocationRecordingProfunctor.java index ac9e53fba..28c34ee0f 100644 --- a/src/test/java/testsupport/applicatives/InvocationRecordingProfunctor.java +++ b/src/test/java/testsupport/applicatives/InvocationRecordingProfunctor.java @@ -6,11 +6,11 @@ import java.util.function.Function; public final class InvocationRecordingProfunctor implements Profunctor> { - private final AtomicReference leftFn; - private final AtomicReference rightFn; + private final AtomicReference> leftFn; + private final AtomicReference> rightFn; - public InvocationRecordingProfunctor(AtomicReference leftFn, - AtomicReference rightFn) { + public InvocationRecordingProfunctor(AtomicReference> leftFn, + AtomicReference> rightFn) { this.leftFn = leftFn; this.rightFn = rightFn; } diff --git a/src/test/java/testsupport/exceptions/OutOfScopeException.java b/src/test/java/testsupport/exceptions/OutOfScopeException.java index b723b7d4c..8e8f0e4b6 100644 --- a/src/test/java/testsupport/exceptions/OutOfScopeException.java +++ b/src/test/java/testsupport/exceptions/OutOfScopeException.java @@ -1,5 +1,6 @@ package testsupport.exceptions; +@SuppressWarnings("serial") public class OutOfScopeException extends RuntimeException { public OutOfScopeException(String s) { diff --git a/src/test/java/testsupport/matchers/FiniteIterableMatcher.java b/src/test/java/testsupport/matchers/FiniteIterableMatcher.java index 609f54d51..7f5b57d58 100644 --- a/src/test/java/testsupport/matchers/FiniteIterableMatcher.java +++ b/src/test/java/testsupport/matchers/FiniteIterableMatcher.java @@ -3,7 +3,7 @@ import org.hamcrest.BaseMatcher; import org.hamcrest.Description; -public class FiniteIterableMatcher extends BaseMatcher { +public class FiniteIterableMatcher extends BaseMatcher> { @Override public boolean matches(Object item) { @@ -21,7 +21,7 @@ public void describeMismatch(Object item, Description description) { } @SuppressWarnings("UnusedDeclaration") - private boolean supportsLessThanInfiniteIterations(Iterable iterable) { + private boolean supportsLessThanInfiniteIterations(Iterable iterable) { long sufficientlyInfinite = 1000000; long elementsIterated = 0; for (Object ignored : iterable) diff --git a/src/test/java/testsupport/matchers/IterableMatcher.java b/src/test/java/testsupport/matchers/IterableMatcher.java index 5313e70af..5478e46e3 100644 --- a/src/test/java/testsupport/matchers/IterableMatcher.java +++ b/src/test/java/testsupport/matchers/IterableMatcher.java @@ -37,16 +37,16 @@ public void describeMismatch(Object item, Description description) { super.describeMismatch(item, description); } - private boolean iterablesIterateSameElementsInOrder(Iterable expected, Iterable actual) { - Iterator actualIterator = actual.iterator(); - Iterator expectedIterator = expected.iterator(); + private boolean iterablesIterateSameElementsInOrder(Iterable expected, Iterable actual) { + Iterator actualIterator = actual.iterator(); + Iterator expectedIterator = expected.iterator(); while (expectedIterator.hasNext() && actualIterator.hasNext()) { Object nextExpected = expectedIterator.next(); Object nextActual = actualIterator.next(); if (nextExpected instanceof Iterable && nextActual instanceof Iterable) { - if (!iterablesIterateSameElementsInOrder((Iterable) nextExpected, (Iterable) nextActual)) + if (!iterablesIterateSameElementsInOrder((Iterable) nextExpected, (Iterable) nextActual)) return false; } else if (!reflectionEquals(nextExpected, nextActual)) return false; @@ -55,9 +55,9 @@ private boolean iterablesIterateSameElementsInOrder(Iterable expected, Iterable return actualIterator.hasNext() == expectedIterator.hasNext(); } - private String stringify(Iterable iterable) { + private String stringify(Iterable iterable) { StringBuilder stringBuilder = new StringBuilder().append("["); - Iterator iterator = iterable.iterator(); + Iterator iterator = iterable.iterator(); while (iterator.hasNext()) { Object next = iterator.next(); if (next instanceof Iterable) @@ -71,6 +71,7 @@ private String stringify(Iterable iterable) { } @SafeVarargs + @SuppressWarnings("varargs") public static IterableMatcher iterates(E... es) { return new IterableMatcher<>(asList(es)); } From a52d18eb035bd10c32e5fdefc8ef838c502dea71 Mon Sep 17 00:00:00 2001 From: jnape Date: Fri, 19 Apr 2019 18:21:53 -0500 Subject: [PATCH 18/69] Adding IdentityT, a monad transformer for Identity --- CHANGELOG.md | 1 + .../monad/transformer/builtin/EitherT.java | 10 ++ .../monad/transformer/builtin/IdentityT.java | 124 ++++++++++++++++++ .../monad/transformer/builtin/MaybeT.java | 4 +- .../transformer/builtin/IdentityTTest.java | 37 ++++++ 5 files changed, 174 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/IdentityT.java create mode 100644 src/test/java/com/jnape/palatable/lambda/monad/transformer/builtin/IdentityTTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index f00e30a94..27fc48fbe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ might need to be reworked, and subtyping is obviously no longer supported. - `MonadT`, a general interface representing monad transformers - `MaybeT`, a monad transformer for `Maybe` - `EitherT`, a monad transformer for `Either` +- `IdentityT`, a monad transformer for `Identity` - `Endo`, a monoid formed by `Fn1` under composition - `State`, the state `Monad` diff --git a/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/EitherT.java b/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/EitherT.java index 592bd6b9f..3b23327d9 100644 --- a/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/EitherT.java +++ b/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/EitherT.java @@ -115,6 +115,16 @@ public String toString() { return "EitherT{melr=" + melr + '}'; } + /** + * Static factory method for lifting a {@link Monad}<{@link Either}<L, R>, M> into an + * {@link EitherT}. + * + * @param melr the {@link Monad}<{@link Either}<L, R>, M> + * @param the outer {@link Monad} unification parameter + * @param the left type + * @param the right type + * @return the {@link EitherT} + */ public static , L, R> EitherT eitherT(Monad, M> melr) { return new EitherT<>(melr); } diff --git a/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/IdentityT.java b/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/IdentityT.java new file mode 100644 index 000000000..932680c8b --- /dev/null +++ b/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/IdentityT.java @@ -0,0 +1,124 @@ +package com.jnape.palatable.lambda.monad.transformer.builtin; + +import com.jnape.palatable.lambda.functor.Applicative; +import com.jnape.palatable.lambda.functor.builtin.Compose; +import com.jnape.palatable.lambda.functor.builtin.Identity; +import com.jnape.palatable.lambda.functor.builtin.Lazy; +import com.jnape.palatable.lambda.monad.Monad; +import com.jnape.palatable.lambda.monad.transformer.MonadT; + +import java.util.Objects; +import java.util.function.Function; + +/** + * A {@link MonadT monad transformer} for {@link Identity}. + * + * @param the outer {@link Monad} + * @param the carrier type + */ +public final class IdentityT, A> implements MonadT, A> { + + private final Monad, M> mia; + + private IdentityT(Monad, M> mia) { + this.mia = mia; + } + + /** + * {@inheritDoc} + */ + @Override + public >, FGA extends Monad> FGA run() { + return mia.fmap(Identity::coerce).coerce(); + } + + /** + * {@inheritDoc} + */ + @Override + public IdentityT flatMap(Function, ?>>> f) { + return identityT(mia.flatMap(identityA -> f.apply(identityA.runIdentity()).>coerce().run())); + } + + /** + * {@inheritDoc} + */ + @Override + public IdentityT pure(B b) { + return identityT(mia.pure(new Identity<>(b))); + } + + /** + * {@inheritDoc} + */ + @Override + public IdentityT fmap(Function fn) { + return MonadT.super.fmap(fn).coerce(); + } + + /** + * {@inheritDoc} + */ + @Override + public IdentityT zip(Applicative, MonadT, ?>> appFn) { + return MonadT.super.zip(appFn).coerce(); + } + + /** + * {@inheritDoc} + */ + @Override + public Lazy> lazyZip( + Lazy, MonadT, ?>>> lazyAppFn) { + return new Compose<>(mia) + .lazyZip(lazyAppFn.fmap(maybeT -> new Compose<>( + maybeT.>>coerce() + .>, + Monad>, M>>run()))) + .fmap(compose -> identityT(compose.getCompose())); + } + + /** + * {@inheritDoc} + */ + @Override + public IdentityT discardL(Applicative, ?>> appB) { + return MonadT.super.discardL(appB).coerce(); + } + + /** + * {@inheritDoc} + */ + @Override + public IdentityT discardR(Applicative, ?>> appB) { + return MonadT.super.discardR(appB).coerce(); + } + + @Override + public boolean equals(Object other) { + return other instanceof IdentityT && Objects.equals(mia, ((IdentityT) other).mia); + } + + @Override + public int hashCode() { + return Objects.hash(mia); + } + + @Override + public String toString() { + return "IdentityT{mia=" + mia + '}'; + } + + /** + * Static factory method for lifting a {@link Monad}<{@link Identity}<A>, M> into a + * {@link IdentityT}. + * + * @param mia the {@link Monad}<{@link Identity}<A>, M> + * @param the outer {@link Monad} unification parameter + * @param the carrier type + * @return the new {@link IdentityT}. + */ + public static , A> IdentityT identityT(Monad, M> mia) { + return new IdentityT<>(mia); + } +} diff --git a/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/MaybeT.java b/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/MaybeT.java index 3d765ad1b..f7d72406a 100644 --- a/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/MaybeT.java +++ b/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/MaybeT.java @@ -116,10 +116,10 @@ public String toString() { } /** - * Static factory method for lifting a {@link Monad}<{@link Maybe}<A>> into a + * Static factory method for lifting a {@link Monad}<{@link Maybe}<A>, M> into a * {@link MaybeT}. * - * @param mma the {@link Monad}<{@link Maybe}<A>> + * @param mma the {@link Monad}<{@link Maybe}<A>, M> * @param the outer {@link Monad} unification parameter * @param the carrier type * @return the {@link MaybeT} diff --git a/src/test/java/com/jnape/palatable/lambda/monad/transformer/builtin/IdentityTTest.java b/src/test/java/com/jnape/palatable/lambda/monad/transformer/builtin/IdentityTTest.java new file mode 100644 index 000000000..fb9a6629d --- /dev/null +++ b/src/test/java/com/jnape/palatable/lambda/monad/transformer/builtin/IdentityTTest.java @@ -0,0 +1,37 @@ +package com.jnape.palatable.lambda.monad.transformer.builtin; + +import com.jnape.palatable.lambda.adt.Maybe; +import com.jnape.palatable.lambda.functor.builtin.Identity; +import com.jnape.palatable.traitor.annotations.TestTraits; +import com.jnape.palatable.traitor.runners.Traits; +import org.junit.Test; +import org.junit.runner.RunWith; +import testsupport.traits.ApplicativeLaws; +import testsupport.traits.FunctorLaws; +import testsupport.traits.MonadLaws; + +import static com.jnape.palatable.lambda.adt.Maybe.just; +import static com.jnape.palatable.lambda.adt.Maybe.nothing; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; +import static com.jnape.palatable.lambda.monad.transformer.builtin.IdentityT.identityT; +import static org.junit.Assert.assertEquals; + +@RunWith(Traits.class) +public class IdentityTTest { + + @TestTraits({FunctorLaws.class, ApplicativeLaws.class, MonadLaws.class}) + public IdentityT, Integer> testSubject() { + return identityT(just(new Identity<>(1))); + } + + @Test + public void lazyZip() { + assertEquals(identityT(just(new Identity<>(2))), + identityT(just(new Identity<>(1))) + .lazyZip(lazy(identityT(just(new Identity<>(x -> x + 1))))).value()); + assertEquals(identityT(nothing()), + identityT(nothing()).lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + } +} \ No newline at end of file From e944b018f540a6bb9acd77cb379e9438f01fb4f1 Mon Sep 17 00:00:00 2001 From: jnape Date: Fri, 19 Apr 2019 18:25:20 -0500 Subject: [PATCH 19/69] Adding Downcast, a first-class version of Applicative#coerce --- CHANGELOG.md | 1 + .../functions/builtin/fn1/Downcast.java | 32 +++++++++++++++++++ .../functions/builtin/fn1/DowncastTest.java | 28 ++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Downcast.java create mode 100644 src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/DowncastTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 27fc48fbe..138ae47c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ might need to be reworked, and subtyping is obviously no longer supported. - `IdentityT`, a monad transformer for `Identity` - `Endo`, a monoid formed by `Fn1` under composition - `State`, the state `Monad` +- `Downcast`, a function supporting unchecked down-casting ## [3.3.0] - 2019-02-18 ### Added diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Downcast.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Downcast.java new file mode 100644 index 000000000..c7efde762 --- /dev/null +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Downcast.java @@ -0,0 +1,32 @@ +package com.jnape.palatable.lambda.functions.builtin.fn1; + +import com.jnape.palatable.lambda.functions.Fn1; + +/** + * Covariantly cast a value of type B to a value of subtype A. Unsafe. + * + * @param the subtype + * @param the supertype + */ +public final class Downcast implements Fn1 { + + private static final Downcast INSTANCE = new Downcast<>(); + + private Downcast() { + } + + @Override + @SuppressWarnings("unchecked") + public A apply(B b) { + return (A) b; + } + + @SuppressWarnings("unchecked") + public static Downcast downcast() { + return (Downcast) INSTANCE; + } + + public static A downcast(B b) { + return Downcast.downcast().apply(b); + } +} diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/DowncastTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/DowncastTest.java new file mode 100644 index 000000000..b21e30b73 --- /dev/null +++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/DowncastTest.java @@ -0,0 +1,28 @@ +package com.jnape.palatable.lambda.functions.builtin.fn1; + +import com.jnape.palatable.lambda.adt.Maybe; +import com.jnape.palatable.lambda.functor.Functor; +import org.junit.Test; + +import static com.jnape.palatable.lambda.adt.Maybe.nothing; +import static com.jnape.palatable.lambda.functions.builtin.fn1.Downcast.downcast; + +public class DowncastTest { + + @Test + @SuppressWarnings("unused") + public void safeDowncast() { + CharSequence charSequence = "123"; + String s = downcast(charSequence); + + Functor> maybeInt = nothing(); + Maybe cast = downcast(maybeInt); + } + + @Test(expected = ClassCastException.class) + @SuppressWarnings({"JavacQuirks", "unused"}) + public void unsafeDowncast() { + CharSequence charSequence = "123"; + Integer explosion = downcast(charSequence); + } +} \ No newline at end of file From eeb1412ef3b1e7cdffac1926dd8a7c1e45e6937b Mon Sep 17 00:00:00 2001 From: jnape Date: Fri, 19 Apr 2019 18:28:35 -0500 Subject: [PATCH 20/69] Moving coerce to Functor --- .../java/com/jnape/palatable/lambda/adt/Try.java | 2 +- .../jnape/palatable/lambda/adt/choice/Choice2.java | 4 +++- .../jnape/palatable/lambda/adt/choice/Choice3.java | 4 +++- .../jnape/palatable/lambda/adt/choice/Choice4.java | 4 +++- .../jnape/palatable/lambda/adt/choice/Choice5.java | 3 ++- .../jnape/palatable/lambda/adt/choice/Choice6.java | 4 +++- .../jnape/palatable/lambda/adt/choice/Choice7.java | 4 +++- .../jnape/palatable/lambda/adt/choice/Choice8.java | 4 +++- .../jnape/palatable/lambda/functor/Applicative.java | 11 ----------- .../com/jnape/palatable/lambda/functor/Functor.java | 12 ++++++++++++ 10 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/jnape/palatable/lambda/adt/Try.java b/src/main/java/com/jnape/palatable/lambda/adt/Try.java index e714739ed..4b0e24b19 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/Try.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/Try.java @@ -206,7 +206,7 @@ public Try discardR(Applicative> appB) { AppTrav extends Applicative> AppTrav traverse(Function fn, Function pure) { return match(t -> pure.apply((TravB) failure(t)), - a -> fn.apply(a).fmap(Try::success).fmap(Applicative::coerce).coerce()); + a -> fn.apply(a).>fmap(Try::success).fmap(Applicative::coerce).coerce()); } /** diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice2.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice2.java index b63ed4745..e16315de9 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice2.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice2.java @@ -7,6 +7,7 @@ import com.jnape.palatable.lambda.adt.hlist.Tuple2; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; +import com.jnape.palatable.lambda.functor.Functor; import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; @@ -114,6 +115,7 @@ public Choice2 zip(Applicative, Choic /** * {@inheritDoc} + * * @param lazyAppFn */ @Override @@ -157,7 +159,7 @@ public final Choice2 flatMap(Function> AppTrav traverse(Function fn, Function pure) { return match(a -> pure.apply((TravB) a(a)), - b -> fn.apply(b).fmap(Choice2::b).fmap(Applicative::coerce).coerce()); + b -> fn.apply(b).>fmap(Choice2::b).fmap(Functor::coerce).coerce()); } /** diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice3.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice3.java index c3d8d2697..953a0ca58 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice3.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice3.java @@ -7,6 +7,7 @@ import com.jnape.palatable.lambda.adt.hlist.Tuple3; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; +import com.jnape.palatable.lambda.functor.Functor; import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; @@ -114,6 +115,7 @@ public Choice3 zip(Applicative, Ch /** * {@inheritDoc} + * * @param lazyAppFn */ @Override @@ -159,7 +161,7 @@ AppTrav extends Applicative> AppTrav traverse(Function pure) { return match(a -> pure.apply((TravB) Choice3.a(a)).coerce(), b -> pure.apply((TravB) Choice3.b(b)).coerce(), - c -> fn.apply(c).fmap(Choice3::c).fmap(Applicative::coerce).coerce()); + c -> fn.apply(c).>fmap(Choice3::c).fmap(Functor::coerce).coerce()); } /** diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice4.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice4.java index a707afc69..8a2efdec7 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice4.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice4.java @@ -7,6 +7,7 @@ import com.jnape.palatable.lambda.adt.hlist.Tuple4; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; +import com.jnape.palatable.lambda.functor.Functor; import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; @@ -115,6 +116,7 @@ public Choice4 zip(Applicative, /** * {@inheritDoc} + * * @param lazyAppFn */ @Override @@ -162,7 +164,7 @@ AppTrav extends Applicative> AppTrav traverse(Function pure.apply((TravB) Choice4.a(a)).coerce(), b -> pure.apply((TravB) Choice4.b(b)).coerce(), c -> pure.apply((TravB) Choice4.c(c)), - d -> fn.apply(d).fmap(Choice4::d).fmap(Applicative::coerce).coerce()); + d -> fn.apply(d).>fmap(Choice4::d).fmap(Functor::coerce).coerce()); } /** diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice5.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice5.java index ed4b4a5b6..fb4a609f3 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice5.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice5.java @@ -169,7 +169,8 @@ AppTrav extends Applicative> AppTrav traverse(Function pure.apply((TravB) Choice5.b(b)).coerce(), c -> pure.apply((TravB) Choice5.c(c)), d -> pure.apply((TravB) Choice5.d(d)), - e -> fn.apply(e).fmap(Choice5::e).fmap(Applicative::coerce).coerce()); + e -> fn.apply(e).>fmap(Choice5::e) + .fmap(Applicative::coerce).coerce()); } /** diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice6.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice6.java index e3ab3d48f..c3696b1a4 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice6.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice6.java @@ -123,6 +123,7 @@ public Choice6 zip( /** * {@inheritDoc} + * * @param lazyAppFn */ @Override @@ -175,7 +176,8 @@ AppTrav extends Applicative> AppTrav traverse(Function pure.apply((TravB) Choice6.c(c)), d -> pure.apply((TravB) Choice6.d(d)), e -> pure.apply((TravB) Choice6.e(e)), - f -> fn.apply(f).fmap(Choice6::f).fmap(Applicative::coerce).coerce()); + f -> fn.apply(f).>fmap(Choice6::f) + .fmap(Applicative::coerce).coerce()); } /** diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice7.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice7.java index 1348293a5..4f6c2708c 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice7.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice7.java @@ -126,6 +126,7 @@ public Choice7 zip( /** * {@inheritDoc} + * * @param lazyAppFn */ @Override @@ -180,7 +181,8 @@ AppTrav extends Applicative> AppTrav traverse(Function pure.apply((TravB) Choice7.d(d)), e -> pure.apply((TravB) Choice7.e(e)), f -> pure.apply((TravB) Choice7.f(f)), - g -> fn.apply(g).fmap(Choice7::g).fmap(Applicative::coerce).coerce()); + g -> fn.apply(g).>fmap(Choice7::g) + .fmap(Applicative::coerce).coerce()); } /** diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice8.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice8.java index b0a70c530..28d47e689 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice8.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice8.java @@ -119,6 +119,7 @@ public Choice8 zip( /** * {@inheritDoc} + * * @param lazyAppFn */ @Override @@ -175,7 +176,8 @@ AppTrav extends Applicative> AppTrav traverse(Function pure.apply((TravB) Choice8.e(e)), f -> pure.apply((TravB) Choice8.f(f)), g -> pure.apply((TravB) Choice8.g(g)), - h -> fn.apply(h).fmap(Choice8::h).fmap(Applicative::coerce).coerce()); + h -> fn.apply(h).>fmap(Choice8::h) + .fmap(Applicative::coerce).coerce()); } /** diff --git a/src/main/java/com/jnape/palatable/lambda/functor/Applicative.java b/src/main/java/com/jnape/palatable/lambda/functor/Applicative.java index 9bd495727..af08c2a00 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/Applicative.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/Applicative.java @@ -93,15 +93,4 @@ default Applicative discardL(Applicative appB) { default Applicative discardR(Applicative appB) { return appB.zip(fmap(constantly())); } - - /** - * Convenience method for coercing this applicative instance into another concrete type. Unsafe. - * - * @param the concrete applicative instance to coerce this applicative to - * @return the coerced applicative - */ - @SuppressWarnings({"unchecked"}) - default > Concrete coerce() { - return (Concrete) this; - } } diff --git a/src/main/java/com/jnape/palatable/lambda/functor/Functor.java b/src/main/java/com/jnape/palatable/lambda/functor/Functor.java index 7645f1013..49e5664cd 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/Functor.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/Functor.java @@ -4,6 +4,8 @@ import java.util.function.Function; +import static com.jnape.palatable.lambda.functions.builtin.fn1.Downcast.downcast; + /** * An interface for the generic covariant functorial operation map over some parameter A. * Functors are foundational to many of the classes provided by this library; generally, anything that can be thought of @@ -31,4 +33,14 @@ public interface Functor> { * @return a functor over B (the new parameter type) */ Functor fmap(Function fn); + + /** + * Convenience method for coercing this functor instance into another concrete type. Unsafe. + * + * @param the concrete functor instance to coerce this functor to + * @return the coerced functor + */ + default > Concrete coerce() { + return downcast(this); + } } From cc11576093339e43c677f84f15dd4cdd331e266e Mon Sep 17 00:00:00 2001 From: jnape Date: Sun, 21 Apr 2019 14:27:08 -0500 Subject: [PATCH 21/69] Renaming Strong to Cartesian to better reflect the type of strength --- CHANGELOG.md | 1 + .../jnape/palatable/lambda/functions/Fn1.java | 14 ++--- .../specialized/checked/CheckedFn1.java | 4 +- .../palatable/lambda/functor/Cartesian.java | 53 +++++++++++++++++++ .../palatable/lambda/functor/Strong.java | 53 ------------------- .../palatable/lambda/functions/Fn1Test.java | 2 +- .../specialized/checked/CheckedFn1Test.java | 2 +- 7 files changed, 65 insertions(+), 64 deletions(-) create mode 100644 src/main/java/com/jnape/palatable/lambda/functor/Cartesian.java delete mode 100644 src/main/java/com/jnape/palatable/lambda/functor/Strong.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 138ae47c4..fa7e60339 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ might need to be reworked, and subtyping is obviously no longer supported. - ***Breaking Change***: `FoldRight` now requires `Lazy` as part of its interface to support short-circuiting operations - ***Breaking Change***: Eliminated all raw types and java11 warnings. This required using capture in unification parameters for Functor and friends, so nearly every functor's type-signature changed. +- ***Breaking Change***: `Strong` is now called `Cartesian` to better reflect the type of strength - `IO` is now stack-safe, regardless of whether the composition nests linearly or recursively ### Added diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java index 6384641a8..291a525d2 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java @@ -2,7 +2,7 @@ import com.jnape.palatable.lambda.adt.hlist.Tuple2; import com.jnape.palatable.lambda.functor.Applicative; -import com.jnape.palatable.lambda.functor.Strong; +import com.jnape.palatable.lambda.functor.Cartesian; import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; @@ -20,7 +20,7 @@ * @param The result type */ @FunctionalInterface -public interface Fn1 extends Monad>, Strong>, Function { +public interface Fn1 extends Monad>, Cartesian>, Function { /** * Invoke this function with the given argument. @@ -131,7 +131,7 @@ default Fn1 discardR(Applicative> appB) { */ @Override default Fn1 diMapL(Function fn) { - return (Fn1) Strong.super.diMapL(fn); + return (Fn1) Cartesian.super.diMapL(fn); } /** @@ -144,7 +144,7 @@ default Fn1 diMapL(Function fn) { */ @Override default Fn1 diMapR(Function fn) { - return (Fn1) Strong.super.diMapR(fn); + return (Fn1) Cartesian.super.diMapR(fn); } /** @@ -168,7 +168,7 @@ default Fn1 diMap(Function lFn, Function Fn1, Tuple2> strengthen() { + default Fn1, Tuple2> cartesian() { return t -> t.fmap(this); } @@ -177,12 +177,12 @@ default Fn1, Tuple2> strengthen() { */ @Override default Fn1> carry() { - return (Fn1>) Strong.super.carry(); + return (Fn1>) Cartesian.super.carry(); } @Override default Fn1 contraMap(Function fn) { - return (Fn1) Strong.super.contraMap(fn); + return (Fn1) Cartesian.super.contraMap(fn); } /** diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedFn1.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedFn1.java index 4b5bd93a7..4fd589c2a 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedFn1.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedFn1.java @@ -112,8 +112,8 @@ default CheckedFn1 diMap(Function lFn, * {@inheritDoc} */ @Override - default CheckedFn1, Tuple2> strengthen() { - return Fn1.super.strengthen()::apply; + default CheckedFn1, Tuple2> cartesian() { + return Fn1.super.cartesian()::apply; } /** diff --git a/src/main/java/com/jnape/palatable/lambda/functor/Cartesian.java b/src/main/java/com/jnape/palatable/lambda/functor/Cartesian.java new file mode 100644 index 000000000..71f3afb5c --- /dev/null +++ b/src/main/java/com/jnape/palatable/lambda/functor/Cartesian.java @@ -0,0 +1,53 @@ +package com.jnape.palatable.lambda.functor; + +import com.jnape.palatable.lambda.adt.hlist.Tuple2; + +import java.util.function.Function; + +/** + * {@link Profunctor} strength in the cartesian sense: p a b -> p (c, a) (c, b) for any type + * c. + * + * @param the type of the left parameter + * @param the type of the left parameter + * @param the unification parameter + * @see com.jnape.palatable.lambda.functions.Fn1 + */ +public interface Cartesian> extends Profunctor { + + /** + * Pair some type C to this profunctor's carrier types. + * + * @param the paired type + * @return the cartesian-strengthened profunctor + */ + Cartesian, Tuple2, S> cartesian(); + + /** + * Pair the covariantly-positioned carrier type with the contravariantly-positioned carrier type. This can be + * thought of as "carrying" or "inspecting" the left parameter. + * + * @return the profunctor with the first parameter carried + */ + default Cartesian, S> carry() { + return this.cartesian().contraMap(Tuple2::fill); + } + + @Override + Cartesian diMap(Function lFn, Function rFn); + + @Override + default Cartesian diMapL(Function fn) { + return (Cartesian) Profunctor.super.diMapL(fn); + } + + @Override + default Cartesian diMapR(Function fn) { + return (Cartesian) Profunctor.super.diMapR(fn); + } + + @Override + default Cartesian contraMap(Function fn) { + return (Cartesian) Profunctor.super.contraMap(fn); + } +} diff --git a/src/main/java/com/jnape/palatable/lambda/functor/Strong.java b/src/main/java/com/jnape/palatable/lambda/functor/Strong.java deleted file mode 100644 index 0be4c230d..000000000 --- a/src/main/java/com/jnape/palatable/lambda/functor/Strong.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.jnape.palatable.lambda.functor; - -import com.jnape.palatable.lambda.adt.hlist.Tuple2; - -import java.util.function.Function; - -/** - * "Strong" {@link Profunctor profunctors} are profunctors that can be "strengthened" to preserve the pairing of an - * arbitrary type under dimap (p a b -> p (c, a) (c, b) for any type c). - * - * @param the type of the left parameter - * @param the type of the left parameter - * @param the unification parameter - * @see com.jnape.palatable.lambda.functions.Fn1 - */ -public interface Strong> extends Profunctor { - - /** - * Pair some type C to this profunctor's carrier types. - * - * @param the paired type - * @return the strengthened profunctor - */ - Strong, Tuple2, S> strengthen(); - - /** - * Pair the covariantly-positioned carrier type with the contravariantly-positioned carrier type. This can be - * thought of as "carrying" or "inspecting" the left parameter. - * - * @return the profunctor with the first parameter carried - */ - default Strong, S> carry() { - return this.strengthen().contraMap(Tuple2::fill); - } - - @Override - Strong diMap(Function lFn, Function rFn); - - @Override - default Strong diMapL(Function fn) { - return (Strong) Profunctor.super.diMapL(fn); - } - - @Override - default Strong diMapR(Function fn) { - return (Strong) Profunctor.super.diMapR(fn); - } - - @Override - default Strong contraMap(Function fn) { - return (Strong) Profunctor.super.contraMap(fn); - } -} diff --git a/src/test/java/com/jnape/palatable/lambda/functions/Fn1Test.java b/src/test/java/com/jnape/palatable/lambda/functions/Fn1Test.java index 20074539b..80af42dc1 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/Fn1Test.java +++ b/src/test/java/com/jnape/palatable/lambda/functions/Fn1Test.java @@ -56,7 +56,7 @@ public void widen() { @Test public void strengthen() { Fn1 add1 = x -> x + 1; - assertEquals(tuple("a", 2), add1.strengthen().apply(tuple("a", 1))); + assertEquals(tuple("a", 2), add1.cartesian().apply(tuple("a", 1))); } @Test diff --git a/src/test/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedFn1Test.java b/src/test/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedFn1Test.java index a8818d684..c5b614755 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedFn1Test.java +++ b/src/test/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedFn1Test.java @@ -22,7 +22,7 @@ public void assignment() { CheckedFn1 diMapL = parseInt.diMapL(id()); CheckedFn1 diMapR = parseInt.diMapR(id()); CheckedFn1 diMap = parseInt.diMap(id(), id()); - CheckedFn1, Tuple2> strengthen = parseInt.strengthen(); + CheckedFn1, Tuple2> strengthen = parseInt.cartesian(); CheckedFn1> carry = parseInt.carry(); CheckedFn1 contraMap = parseInt.contraMap(id()); CheckedFn1 compose = parseInt.compose(id()); From 1d2749f7368694e1309ad7d22ed8267609b83e06 Mon Sep 17 00:00:00 2001 From: jnape Date: Sun, 21 Apr 2019 15:45:05 -0500 Subject: [PATCH 22/69] Cocartesian coproduct strength --- CHANGELOG.md | 1 + .../jnape/palatable/lambda/functions/Fn1.java | 31 ++++++++- .../palatable/lambda/functor/Cartesian.java | 25 +++---- .../palatable/lambda/functor/Cocartesian.java | 66 +++++++++++++++++++ .../palatable/lambda/functor/Profunctor.java | 3 + .../palatable/lambda/functions/Fn1Test.java | 18 ++++- 6 files changed, 130 insertions(+), 14 deletions(-) create mode 100644 src/main/java/com/jnape/palatable/lambda/functor/Cocartesian.java diff --git a/CHANGELOG.md b/CHANGELOG.md index fa7e60339..faf352044 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ might need to be reworked, and subtyping is obviously no longer supported. - `Endo`, a monoid formed by `Fn1` under composition - `State`, the state `Monad` - `Downcast`, a function supporting unchecked down-casting +- `Cocartesian`, profunctorial strength in cocartesian coproduct terms ## [3.3.0] - 2019-02-18 ### Added diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java index 291a525d2..680dc55eb 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java @@ -1,8 +1,11 @@ package com.jnape.palatable.lambda.functions; +import com.jnape.palatable.lambda.adt.Either; +import com.jnape.palatable.lambda.adt.choice.Choice2; import com.jnape.palatable.lambda.adt.hlist.Tuple2; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Cartesian; +import com.jnape.palatable.lambda.functor.Cocartesian; import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; @@ -20,7 +23,11 @@ * @param The result type */ @FunctionalInterface -public interface Fn1 extends Monad>, Cartesian>, Function { +public interface Fn1 extends + Monad>, + Cartesian>, + Cocartesian>, + Function { /** * Invoke this function with the given argument. @@ -97,6 +104,7 @@ default Fn1 zip(Fn2 appFn) { /** * {@inheritDoc} + * * @param lazyAppFn */ @Override @@ -180,6 +188,27 @@ default Fn1> carry() { return (Fn1>) Cartesian.super.carry(); } + /** + * Choose between either applying this function or returning back a different result altogether. + * + * @param the potentially different result + * @return teh strengthened {@link Fn1} + */ + @Override + default Fn1, Choice2> cocartesian() { + return a -> a.fmap(this); + } + + /** + * Choose between a successful result b or returning back the input, a. + * + * @return an {@link Fn1} that chooses between its input (in case of failure) or its output. + */ + @Override + default Fn1> choose() { + return a -> Either.trying(() -> apply(a), constantly(a)).match(Choice2::a, Choice2::b); + } + @Override default Fn1 contraMap(Function fn) { return (Fn1) Cartesian.super.contraMap(fn); diff --git a/src/main/java/com/jnape/palatable/lambda/functor/Cartesian.java b/src/main/java/com/jnape/palatable/lambda/functor/Cartesian.java index 71f3afb5c..97ef582b0 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/Cartesian.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/Cartesian.java @@ -5,15 +5,16 @@ import java.util.function.Function; /** - * {@link Profunctor} strength in the cartesian sense: p a b -> p (c, a) (c, b) for any type + * {@link Profunctor} strength in the cartesian product sense: p a b -> p (c ^ a) (c ^ b) for any type * c. * * @param the type of the left parameter * @param the type of the left parameter - * @param the unification parameter + * @param

the unification parameter * @see com.jnape.palatable.lambda.functions.Fn1 + * @see Cocartesian */ -public interface Cartesian> extends Profunctor { +public interface Cartesian> extends Profunctor { /** * Pair some type C to this profunctor's carrier types. @@ -21,7 +22,7 @@ public interface Cartesian> extends Profuncto * @param the paired type * @return the cartesian-strengthened profunctor */ - Cartesian, Tuple2, S> cartesian(); + Cartesian, Tuple2, P> cartesian(); /** * Pair the covariantly-positioned carrier type with the contravariantly-positioned carrier type. This can be @@ -29,25 +30,25 @@ public interface Cartesian> extends Profuncto * * @return the profunctor with the first parameter carried */ - default Cartesian, S> carry() { + default Cartesian, P> carry() { return this.cartesian().contraMap(Tuple2::fill); } @Override - Cartesian diMap(Function lFn, Function rFn); + Cartesian diMap(Function lFn, Function rFn); @Override - default Cartesian diMapL(Function fn) { - return (Cartesian) Profunctor.super.diMapL(fn); + default Cartesian diMapL(Function fn) { + return (Cartesian) Profunctor.super.diMapL(fn); } @Override - default Cartesian diMapR(Function fn) { - return (Cartesian) Profunctor.super.diMapR(fn); + default Cartesian diMapR(Function fn) { + return (Cartesian) Profunctor.super.diMapR(fn); } @Override - default Cartesian contraMap(Function fn) { - return (Cartesian) Profunctor.super.contraMap(fn); + default Cartesian contraMap(Function fn) { + return (Cartesian) Profunctor.super.contraMap(fn); } } diff --git a/src/main/java/com/jnape/palatable/lambda/functor/Cocartesian.java b/src/main/java/com/jnape/palatable/lambda/functor/Cocartesian.java new file mode 100644 index 000000000..8d76e9c45 --- /dev/null +++ b/src/main/java/com/jnape/palatable/lambda/functor/Cocartesian.java @@ -0,0 +1,66 @@ +package com.jnape.palatable.lambda.functor; + +import com.jnape.palatable.lambda.adt.choice.Choice2; + +import java.util.function.Function; + +/** + * {@link Profunctor} strength in the cocartesian coproduct sense: p a b -> p (c v a) (c v b) for any + * type c. + * + * @param the type of the left parameter + * @param the type of the left parameter + * @param

the unification parameter + * @see com.jnape.palatable.lambda.functions.Fn1 + * @see Cartesian + */ +public interface Cocartesian> extends Profunctor { + + /** + * Choose some type C or this profunctor's carrier types. + * + * @param the choice type + * @return the cocartesian-costrengthened profunctor + */ + Cocartesian, Choice2, P> cocartesian(); + + /** + * Choose between the covariantly-positioned carrier type and the contravariantly-positioned carrier type. This can + * be used to encode partial functions a -> (⊥ v b) as total functions a -> (a v b). + * + * @return the profunctor with a choice + */ + default Cocartesian, P> choose() { + return this.cocartesian().contraMap(Choice2::b); + } + + /** + * {@inheritDoc} + */ + @Override + Cocartesian diMap(Function lFn, Function rFn); + + /** + * {@inheritDoc} + */ + @Override + default Cocartesian diMapL(Function fn) { + return (Cocartesian) Profunctor.super.diMapL(fn); + } + + /** + * {@inheritDoc} + */ + @Override + default Cocartesian diMapR(Function fn) { + return (Cocartesian) Profunctor.super.diMapR(fn); + } + + /** + * {@inheritDoc} + */ + @Override + default Cocartesian contraMap(Function fn) { + return (Cocartesian) Profunctor.super.contraMap(fn); + } +} diff --git a/src/main/java/com/jnape/palatable/lambda/functor/Profunctor.java b/src/main/java/com/jnape/palatable/lambda/functor/Profunctor.java index 865f2e2d5..41a4ec8ae 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/Profunctor.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/Profunctor.java @@ -59,6 +59,9 @@ default Profunctor diMapR(Function fn) { return diMap(id(), fn); } + /** + * {@inheritDoc} + */ @Override default Profunctor contraMap(Function fn) { return diMapL(fn); diff --git a/src/test/java/com/jnape/palatable/lambda/functions/Fn1Test.java b/src/test/java/com/jnape/palatable/lambda/functions/Fn1Test.java index 80af42dc1..a61b5b752 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/Fn1Test.java +++ b/src/test/java/com/jnape/palatable/lambda/functions/Fn1Test.java @@ -12,6 +12,8 @@ import java.util.function.Function; import static com.jnape.palatable.lambda.adt.Maybe.just; +import static com.jnape.palatable.lambda.adt.choice.Choice2.a; +import static com.jnape.palatable.lambda.adt.choice.Choice2.b; import static com.jnape.palatable.lambda.adt.hlist.HList.tuple; import static com.jnape.palatable.lambda.functions.Fn1.fn1; import static com.jnape.palatable.lambda.functions.builtin.fn2.ReduceLeft.reduceLeft; @@ -54,7 +56,7 @@ public void widen() { } @Test - public void strengthen() { + public void cartesian() { Fn1 add1 = x -> x + 1; assertEquals(tuple("a", 2), add1.cartesian().apply(tuple("a", 1))); } @@ -64,4 +66,18 @@ public void carry() { Fn1 add1 = x -> x + 1; assertEquals(tuple(1, 2), add1.carry().apply(1)); } + + @Test + public void cocartesian() { + Fn1 add1 = x -> x + 1; + assertEquals(a("foo"), add1.cocartesian().apply(a("foo"))); + assertEquals(b(2), add1.cocartesian().apply(b(1))); + } + + @Test + public void choose() { + Fn1 add1 = Integer::parseInt; + assertEquals(b(123), add1.choose().apply("123")); + assertEquals(a("foo"), add1.choose().apply("foo")); + } } From 68206c0796571c30f0ccca34c08020fb36b83789 Mon Sep 17 00:00:00 2001 From: jnape Date: Sun, 21 Apr 2019 15:54:32 -0500 Subject: [PATCH 23/69] Adding Optic, a generic supertype for profunctor optics --- CHANGELOG.md | 1 + .../jnape/palatable/lambda/optics/Optic.java | 45 +++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 src/main/java/com/jnape/palatable/lambda/optics/Optic.java diff --git a/CHANGELOG.md b/CHANGELOG.md index faf352044..ab9f8bb10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,7 @@ might need to be reworked, and subtyping is obviously no longer supported. - `IO#unsafePerformAsyncIO` overloads for running `IO`s asynchronously - `IO`s automatically encode parallelism in composition - `IO#exceptionally` for recovering from failure during `IO` operation +- `Optic`, a generic supertype for all profunctor optics ### Fixed - issue where certain ways to compose `Effect`s unintentionally nullified the effect diff --git a/src/main/java/com/jnape/palatable/lambda/optics/Optic.java b/src/main/java/com/jnape/palatable/lambda/optics/Optic.java new file mode 100644 index 000000000..684305785 --- /dev/null +++ b/src/main/java/com/jnape/palatable/lambda/optics/Optic.java @@ -0,0 +1,45 @@ +package com.jnape.palatable.lambda.optics; + +import com.jnape.palatable.lambda.functions.Fn1; +import com.jnape.palatable.lambda.functor.Functor; +import com.jnape.palatable.lambda.functor.Profunctor; + +/** + * A generic supertype representation for profunctor optics. + *

+ * Precisely stated, for some {@link Profunctor} P and some {@link Functor} F, and for the + * types S T A B, an + * {@link Optic}<P, F, S, T, A, B> is a polymorphic function + * (P<A, F<B>> -> P<S, F<T>>) (existentially-quantified allowing for + * covariance). + * + * @param

the {@link Profunctor} type + * @param the {@link Functor} type + * @param the left side of the output profunctor + * @param the right side's functor embedding of the output profunctor + * @param the left side of the input profunctor + * @param the right side's functor embedding of the input profunctor + */ +@FunctionalInterface +public interface Optic

, F extends Functor, S, T, A, B> { + + , ? extends CoP>, + PSFT extends Profunctor, ? extends CoP>> PSFT apply(PAFB pafb); + + /** + * Produce a monomorphic {@link Fn1} backed by this {@link Optic}. + * + * @param the covariant bound on P + * @param the covariant bound on F + * @param the fixed input profunctor type + * @param the fixed output profunctor type + * @return the monomorphic {@link Fn1} backed by this {@link Optic} + */ + default , ? extends CoP>, + PSFT extends Profunctor, ? extends CoP>> + Fn1 monomorphize() { + return Optic.this::apply; + } +} From b643ba836c5916d1d8193822e5efb4e7b40c489a Mon Sep 17 00:00:00 2001 From: jnape Date: Sun, 21 Apr 2019 18:53:09 -0500 Subject: [PATCH 24/69] Lens and Iso are now Optics; retargeting new optic interface for everything --- CHANGELOG.md | 2 + .../jnape/palatable/lambda/adt/hmap/HMap.java | 2 +- .../palatable/lambda/adt/hmap/Schema.java | 21 +- .../lambda/adt/hmap/TypeSafeKey.java | 31 +-- .../palatable/lambda/functor/Profunctor.java | 3 +- .../lambda/functor/builtin/Exchange.java | 1 - .../jnape/palatable/lambda/lens/LensLike.java | 161 -------------- .../lambda/lens/functions/Under.java | 52 ----- .../lambda/{lens => optics}/Iso.java | 153 +++++-------- .../lambda/{lens => optics}/Lens.java | 100 +++++---- .../jnape/palatable/lambda/optics/Optic.java | 208 +++++++++++++++++- .../{lens => optics}/functions/Over.java | 30 +-- .../{lens => optics}/functions/Set.java | 24 +- .../lambda/optics/functions/Under.java | 60 +++++ .../{lens => optics}/functions/View.java | 21 +- .../lenses/CollectionLens.java | 6 +- .../{lens => optics}/lenses/EitherLens.java | 6 +- .../{lens => optics}/lenses/HListLens.java | 6 +- .../{lens => optics}/lenses/HMapLens.java | 6 +- .../{lens => optics}/lenses/IterableLens.java | 12 +- .../{lens => optics}/lenses/ListLens.java | 13 +- .../{lens => optics}/lenses/MapLens.java | 20 +- .../{lens => optics}/lenses/MaybeLens.java | 6 +- .../{lens => optics}/lenses/SetLens.java | 6 +- .../palatable/lambda/adt/hmap/HMapTest.java | 2 +- .../palatable/lambda/adt/hmap/SchemaTest.java | 2 +- .../lambda/adt/hmap/TypeSafeKeyTest.java | 2 +- .../lambda/{lens => optics}/IsoTest.java | 18 +- .../lambda/{lens => optics}/LensTest.java | 36 +-- .../{lens => optics}/functions/OverTest.java | 8 +- .../{lens => optics}/functions/SetTest.java | 8 +- .../{lens => optics}/functions/UnderTest.java | 8 +- .../{lens => optics}/functions/ViewTest.java | 8 +- .../lenses/CollectionLensTest.java | 12 +- .../lenses/EitherLensTest.java | 8 +- .../lenses/HListLensTest.java | 4 +- .../{lens => optics}/lenses/HMapLensTest.java | 2 +- .../lenses/IterableLensTest.java | 14 +- .../{lens => optics}/lenses/ListLensTest.java | 12 +- .../{lens => optics}/lenses/MapLensTest.java | 14 +- .../lenses/MaybeLensTest.java | 18 +- .../{lens => optics}/lenses/SetLensTest.java | 4 +- .../testsupport/assertion/LensAssert.java | 13 +- .../testsupport/matchers/LensMatcher.java | 59 ----- 44 files changed, 588 insertions(+), 614 deletions(-) delete mode 100644 src/main/java/com/jnape/palatable/lambda/lens/LensLike.java delete mode 100644 src/main/java/com/jnape/palatable/lambda/lens/functions/Under.java rename src/main/java/com/jnape/palatable/lambda/{lens => optics}/Iso.java (60%) rename src/main/java/com/jnape/palatable/lambda/{lens => optics}/Lens.java (73%) rename src/main/java/com/jnape/palatable/lambda/{lens => optics}/functions/Over.java (51%) rename src/main/java/com/jnape/palatable/lambda/{lens => optics}/functions/Set.java (57%) create mode 100644 src/main/java/com/jnape/palatable/lambda/optics/functions/Under.java rename src/main/java/com/jnape/palatable/lambda/{lens => optics}/functions/View.java (52%) rename src/main/java/com/jnape/palatable/lambda/{lens => optics}/lenses/CollectionLens.java (94%) rename src/main/java/com/jnape/palatable/lambda/{lens => optics}/lenses/EitherLens.java (91%) rename src/main/java/com/jnape/palatable/lambda/{lens => optics}/lenses/HListLens.java (90%) rename src/main/java/com/jnape/palatable/lambda/{lens => optics}/lenses/HMapLens.java (81%) rename src/main/java/com/jnape/palatable/lambda/{lens => optics}/lenses/IterableLens.java (86%) rename src/main/java/com/jnape/palatable/lambda/{lens => optics}/lenses/ListLens.java (88%) rename src/main/java/com/jnape/palatable/lambda/{lens => optics}/lenses/MapLens.java (93%) rename src/main/java/com/jnape/palatable/lambda/{lens => optics}/lenses/MaybeLens.java (97%) rename src/main/java/com/jnape/palatable/lambda/{lens => optics}/lenses/SetLens.java (91%) rename src/test/java/com/jnape/palatable/lambda/{lens => optics}/IsoTest.java (72%) rename src/test/java/com/jnape/palatable/lambda/{lens => optics}/LensTest.java (72%) rename src/test/java/com/jnape/palatable/lambda/{lens => optics}/functions/OverTest.java (68%) rename src/test/java/com/jnape/palatable/lambda/{lens => optics}/functions/SetTest.java (67%) rename src/test/java/com/jnape/palatable/lambda/{lens => optics}/functions/UnderTest.java (68%) rename src/test/java/com/jnape/palatable/lambda/{lens => optics}/functions/ViewTest.java (67%) rename src/test/java/com/jnape/palatable/lambda/{lens => optics}/lenses/CollectionLensTest.java (80%) rename src/test/java/com/jnape/palatable/lambda/{lens => optics}/lenses/EitherLensTest.java (86%) rename src/test/java/com/jnape/palatable/lambda/{lens => optics}/lenses/HListLensTest.java (90%) rename src/test/java/com/jnape/palatable/lambda/{lens => optics}/lenses/HMapLensTest.java (96%) rename src/test/java/com/jnape/palatable/lambda/{lens => optics}/lenses/IterableLensTest.java (87%) rename src/test/java/com/jnape/palatable/lambda/{lens => optics}/lenses/ListLensTest.java (79%) rename src/test/java/com/jnape/palatable/lambda/{lens => optics}/lenses/MapLensTest.java (94%) rename src/test/java/com/jnape/palatable/lambda/{lens => optics}/lenses/MaybeLensTest.java (80%) rename src/test/java/com/jnape/palatable/lambda/{lens => optics}/lenses/SetLensTest.java (92%) delete mode 100644 src/test/java/testsupport/matchers/LensMatcher.java diff --git a/CHANGELOG.md b/CHANGELOG.md index ab9f8bb10..1263a8cf1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ might need to be reworked, and subtyping is obviously no longer supported. - ***Breaking Change***: Eliminated all raw types and java11 warnings. This required using capture in unification parameters for Functor and friends, so nearly every functor's type-signature changed. - ***Breaking Change***: `Strong` is now called `Cartesian` to better reflect the type of strength +- ***Breaking Change***: new Optic type hierarchy more faithfully encodes profunctor constraints on optics, new `Optic` + type is now the supertype of `Lens` and `Iso`, and `lens` package has been moved to `optics` - `IO` is now stack-safe, regardless of whether the composition nests linearly or recursively ### Added diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hmap/HMap.java b/src/main/java/com/jnape/palatable/lambda/adt/hmap/HMap.java index 19a166bc1..e1677d49f 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hmap/HMap.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hmap/HMap.java @@ -17,7 +17,7 @@ import static com.jnape.palatable.lambda.adt.Maybe.maybe; import static com.jnape.palatable.lambda.functions.builtin.fn2.Map.map; -import static com.jnape.palatable.lambda.lens.functions.View.view; +import static com.jnape.palatable.lambda.optics.functions.View.view; import static java.util.Collections.emptyMap; /** diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hmap/Schema.java b/src/main/java/com/jnape/palatable/lambda/adt/hmap/Schema.java index 6a57cbbbd..f72b9f8b4 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hmap/Schema.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hmap/Schema.java @@ -11,14 +11,14 @@ import com.jnape.palatable.lambda.adt.hlist.Tuple6; import com.jnape.palatable.lambda.adt.hlist.Tuple7; import com.jnape.palatable.lambda.adt.hlist.Tuple8; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functions.builtin.fn2.Both; import com.jnape.palatable.lambda.functor.Functor; -import com.jnape.palatable.lambda.lens.Lens; - -import java.util.function.Function; +import com.jnape.palatable.lambda.functor.Profunctor; +import com.jnape.palatable.lambda.optics.Lens; import static com.jnape.palatable.lambda.functions.builtin.fn2.Into.into; -import static com.jnape.palatable.lambda.lens.lenses.HMapLens.valueAt; +import static com.jnape.palatable.lambda.optics.lenses.HMapLens.valueAt; /** * A lens that focuses on the {@link HList heterogeneous list} of values pointed at by one or more @@ -39,9 +39,9 @@ default > Schema add(TypeSafeKe maybeNewValues -> maybeNewValues.fmap(HCons::head))); return new Schema() { @Override - public , FT extends Functor, FB extends Functor, F>> - FT apply(Function, ? extends FB> fn, HMap hmap) { - return lens.apply(fn, hmap); + public >, CoF extends Functor>, FB extends Functor, ? extends CoF>, FT extends Functor, PAFB extends Profunctor, FB, ? extends CoP>, PSFT extends Profunctor> PSFT apply( + PAFB pafb) { + return lens.apply(pafb); } }; } @@ -52,10 +52,9 @@ static Schema> schema(TypeSafeKey key) { .mapB(maybeSingletonA -> maybeSingletonA.fmap(HCons::head)); return new Schema>() { @Override - public , FT extends Functor, - FB extends Functor>, F>> FT apply( - Function>, ? extends FB> fn, HMap hmap) { - return lens.apply(fn, hmap); + public >, CoF extends Functor>, FB extends Functor>, ? extends CoF>, FT extends Functor, PAFB extends Profunctor>, FB, ? extends CoP>, PSFT extends Profunctor> PSFT apply( + PAFB pafb) { + return lens.apply(pafb); } }; } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hmap/TypeSafeKey.java b/src/main/java/com/jnape/palatable/lambda/adt/hmap/TypeSafeKey.java index 2ee0c6622..ce9361693 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hmap/TypeSafeKey.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hmap/TypeSafeKey.java @@ -3,8 +3,8 @@ import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Functor; import com.jnape.palatable.lambda.functor.Profunctor; -import com.jnape.palatable.lambda.lens.Iso; -import com.jnape.palatable.lambda.lens.LensLike; +import com.jnape.palatable.lambda.optics.Iso; +import com.jnape.palatable.lambda.optics.Optic; import java.util.Objects; @@ -23,14 +23,14 @@ */ public interface TypeSafeKey extends Iso.Simple { + @Override - default TypeSafeKey discardR(Applicative>> appB) { + default TypeSafeKey discardR(Applicative> appB) { Iso.Simple discarded = Iso.Simple.super.discardR(appB); return new TypeSafeKey() { @Override - public

, F extends Functor, FB extends Functor, - FT extends Functor, PAFB extends Profunctor, - PSFT extends Profunctor> PSFT apply(PAFB pafb) { + public >, CoF extends Functor>, FB extends Functor, FT extends Functor, PAFB extends Profunctor, PSFT extends Profunctor> PSFT apply( + PAFB pafb) { return discarded.apply(pafb); } @@ -49,7 +49,7 @@ public boolean equals(Object obj) { /** * Left-to-right composition of this {@link TypeSafeKey} with some other {@link Iso}. Because the first parameter * fundamentally represents an already stored value type, this is the only composition that is possible for - * {@link TypeSafeKey}, which is why only this (and not {@link Iso#compose(Iso)}) is overridden. + * {@link TypeSafeKey}, which is why only this (and not {@link Iso#compose(Optic)}) is overridden. *

* Particularly of note is the fact that values stored at this key are still stored as their original manifest * type, and are not duplicated - which is to say, putting a value at a key, yielding a new key via composition, @@ -61,13 +61,12 @@ public boolean equals(Object obj) { * @return the new {@link TypeSafeKey} */ @Override - default TypeSafeKey andThen(Iso.Simple f) { + default TypeSafeKeyandThen(Iso.Simple f) { Iso.Simple composed = Iso.Simple.super.andThen(f); return new TypeSafeKey() { @Override - public

, F extends Functor, FB extends Functor, - FT extends Functor, PAFB extends Profunctor, - PSFT extends Profunctor> PSFT apply(PAFB pafb) { + public >, CoF extends Functor>, FB extends Functor, FT extends Functor, PAFB extends Profunctor, PSFT extends Profunctor> PSFT apply( + PAFB pafb) { return composed.apply(pafb); } @@ -112,9 +111,13 @@ interface Simple extends TypeSafeKey { @Override @SuppressWarnings("unchecked") - default

, F extends Functor, FB extends Functor, - FT extends Functor, PAFB extends Profunctor, - PSFT extends Profunctor> PSFT apply(PAFB pafb) { + default >, + CoF extends Functor>, + FB extends Functor, + FT extends Functor, + PAFB extends Profunctor, + PSFT extends Profunctor> PSFT apply( + PAFB pafb) { return (PSFT) pafb; } } diff --git a/src/main/java/com/jnape/palatable/lambda/functor/Profunctor.java b/src/main/java/com/jnape/palatable/lambda/functor/Profunctor.java index 41a4ec8ae..2c4b45200 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/Profunctor.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/Profunctor.java @@ -1,7 +1,6 @@ package com.jnape.palatable.lambda.functor; import com.jnape.palatable.lambda.functions.Fn1; -import com.jnape.palatable.lambda.lens.Lens; import java.util.function.Function; @@ -19,7 +18,7 @@ * @see Bifunctor * @see Contravariant * @see Fn1 - * @see Lens + * @see com.jnape.palatable.lambda.optics.Optic */ @FunctionalInterface public interface Profunctor> extends Contravariant> { diff --git a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Exchange.java b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Exchange.java index 6a317784c..d997eaf5d 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Exchange.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Exchange.java @@ -1,7 +1,6 @@ package com.jnape.palatable.lambda.functor.builtin; import com.jnape.palatable.lambda.functor.Profunctor; -import com.jnape.palatable.lambda.lens.Iso; import java.util.function.Function; diff --git a/src/main/java/com/jnape/palatable/lambda/lens/LensLike.java b/src/main/java/com/jnape/palatable/lambda/lens/LensLike.java deleted file mode 100644 index d0c4647f1..000000000 --- a/src/main/java/com/jnape/palatable/lambda/lens/LensLike.java +++ /dev/null @@ -1,161 +0,0 @@ -package com.jnape.palatable.lambda.lens; - -import com.jnape.palatable.lambda.functor.Applicative; -import com.jnape.palatable.lambda.functor.Functor; -import com.jnape.palatable.lambda.functor.Profunctor; -import com.jnape.palatable.lambda.monad.Monad; - -import java.util.function.Function; - -/** - * The generic supertype of all types that can be treated as lenses but should preserve type-specific return types in - * overrides. This type only exists to appease Java's unfortunate parametric type hierarchy constraints. If you're here, - * you're probably looking for {@link Lens} or {@link Iso}. - * - * @param the type of the "larger" value for reading - * @param the type of the "larger" value for putting - * @param the type of the "smaller" value that is read - * @param the type of the "smaller" update value - * @param the concrete lens subtype - * @see Lens - * @see Iso - */ -public interface LensLike> extends - Monad>, - Profunctor> { - - , FT extends Functor, FB extends Functor> FT apply( - Function fn, S s); - - /** - * Right-to-left composition of lenses. Requires compatibility between A and B. - * - * @param g the other lens - * @param the new "larger" value for reading (previously S) - * @param the new "larger" value for putting (previously T) - * @return the composed lens - */ - LensLike compose(LensLike g); - - /** - * Left-to-right composition of lenses. Requires compatibility between S and T. - * - * @param f the other lens - * @param the new "smaller" value to read (previously A) - * @param the new "smaller" update value (previously B) - * @return the composed lens - */ - LensLike andThen(LensLike f); - - /** - * Contravariantly map S to R, yielding a new lens. - * - * @param fn the mapping function - * @param the type of the new "larger" value for reading - * @return the new lens - */ - LensLike mapS(Function fn); - - /** - * Covariantly map T to U, yielding a new lens. - * - * @param fn the mapping function - * @param the type of the new "larger" value for putting - * @return the new lens - */ - LensLike mapT(Function fn); - - /** - * Covariantly map A to C, yielding a new lens. - * - * @param fn the mapping function - * @param the type of the new "smaller" value that is read - * @return the new lens - */ - LensLike mapA(Function fn); - - /** - * Contravariantly map B to Z, yielding a new lens. - * - * @param fn the mapping function - * @param the type of the new "smaller" update value - * @return the new lens - */ - LensLike mapB(Function fn); - - @Override - LensLike flatMap(Function>> f); - - @Override - LensLike pure(U u); - - @Override - default LensLike fmap(Function fn) { - return Monad.super.fmap(fn).coerce(); - } - - @Override - default LensLike zip( - Applicative, LensLike> appFn) { - return Monad.super.zip(appFn).coerce(); - } - - @Override - default LensLike discardL(Applicative> appB) { - return Monad.super.discardL(appB).coerce(); - } - - @Override - default LensLike discardR(Applicative> appB) { - return Monad.super.discardR(appB).coerce(); - } - - @Override - default LensLike diMapL(Function fn) { - return (LensLike) Profunctor.super.diMapL(fn); - } - - @Override - default LensLike diMapR(Function fn) { - return (LensLike) Profunctor.super.diMapR(fn); - } - - @Override - default LensLike diMap(Function lFn, - Function rFn) { - return this.mapS(lFn).mapT(rFn); - } - - @Override - default LensLike contraMap(Function fn) { - return (LensLike) Profunctor.super.contraMap(fn); - } - - /** - * A simpler type signature for lenses where S/T and A/B are equivalent. - * - * @param the "larger" type - * @param the "smaller" type - * @param the concrete lens subtype - */ - interface Simple> extends LensLike { - - /** - * Compose two simple lenses from right to left. - * - * @param g the other simple lens - * @param the other simple lens' larger type - * @return the composed simple lens - */ - LensLike.Simple compose(LensLike.Simple g); - - /** - * Compose two simple lenses from left to right. - * - * @param f the other simple lens - * @param the other simple lens' smaller type - * @return the composed simple lens - */ - LensLike.Simple andThen(LensLike.Simple f); - } -} diff --git a/src/main/java/com/jnape/palatable/lambda/lens/functions/Under.java b/src/main/java/com/jnape/palatable/lambda/lens/functions/Under.java deleted file mode 100644 index 1bdae90bf..000000000 --- a/src/main/java/com/jnape/palatable/lambda/lens/functions/Under.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.jnape.palatable.lambda.lens.functions; - -import com.jnape.palatable.lambda.functions.Fn1; -import com.jnape.palatable.lambda.functions.Fn2; -import com.jnape.palatable.lambda.functions.Fn3; -import com.jnape.palatable.lambda.lens.Iso; -import com.jnape.palatable.lambda.lens.LensLike; - -import java.util.function.Function; - -/** - * The inverse of {@link Over}: given an {@link Iso}, a function from T to S, and a "smaller" - * value B, return a "smaller" value A by traversing around the type ring (B -> T - * -> S -> A). - *

- * Note this is only possible for {@link Iso}s and not general {@link LensLike}s because of the mandatory need for the - * correspondence B -> T. - * - * @param the larger type for focusing - * @param the larger type for mirrored focusing - * @param the smaller type for focusing - * @param the smaller type for mirrored focusing - */ -public final class Under implements Fn3, Function, B, A> { - - private static final Under INSTANCE = new Under<>(); - - private Under() { - } - - @Override - public A apply(Iso iso, Function fn, B b) { - return iso.unIso().into((sa, bt) -> bt.fmap(fn).fmap(sa)).apply(b); - } - - @SuppressWarnings("unchecked") - public static Under under() { - return (Under) INSTANCE; - } - - public static Fn2, B, A> under(Iso iso) { - return Under.under().apply(iso); - } - - public static Fn1 under(Iso iso, Function fn) { - return under(iso).apply(fn); - } - - public static A under(Iso iso, Function fn, B b) { - return under(iso, fn).apply(b); - } -} diff --git a/src/main/java/com/jnape/palatable/lambda/lens/Iso.java b/src/main/java/com/jnape/palatable/lambda/optics/Iso.java similarity index 60% rename from src/main/java/com/jnape/palatable/lambda/lens/Iso.java rename to src/main/java/com/jnape/palatable/lambda/optics/Iso.java index bc3e76389..e84ecb048 100644 --- a/src/main/java/com/jnape/palatable/lambda/lens/Iso.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/Iso.java @@ -1,4 +1,4 @@ -package com.jnape.palatable.lambda.lens; +package com.jnape.palatable.lambda.optics; import com.jnape.palatable.lambda.adt.hlist.Tuple2; import com.jnape.palatable.lambda.functions.Fn1; @@ -8,21 +8,23 @@ import com.jnape.palatable.lambda.functor.Profunctor; import com.jnape.palatable.lambda.functor.builtin.Exchange; import com.jnape.palatable.lambda.functor.builtin.Identity; -import com.jnape.palatable.lambda.lens.functions.Over; -import com.jnape.palatable.lambda.lens.functions.Set; -import com.jnape.palatable.lambda.lens.functions.View; import com.jnape.palatable.lambda.monad.Monad; +import com.jnape.palatable.lambda.optics.functions.Over; +import com.jnape.palatable.lambda.optics.functions.Set; +import com.jnape.palatable.lambda.optics.functions.View; import java.util.function.Function; import static com.jnape.palatable.lambda.functions.Fn1.fn1; import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id; -import static com.jnape.palatable.lambda.lens.Iso.Simple.adapt; -import static com.jnape.palatable.lambda.lens.functions.View.view; +import static com.jnape.palatable.lambda.optics.Iso.Simple.adapt; +import static com.jnape.palatable.lambda.optics.Lens.lens; +import static com.jnape.palatable.lambda.optics.Optic.optic; +import static com.jnape.palatable.lambda.optics.functions.View.view; /** - * An {@link Iso} (short for "isomorphism") is an invertible {@link Lens}: a {@link LensLike} encoding of a + * An {@link Iso} (short for "isomorphism") is an invertible {@link Lens}: an {@link Optic} encoding of a * bi-directional focusing of two types, and like {@link Lens}es, can be {@link View}ed, * {@link Set}, and {@link Over}ed. *

@@ -50,17 +52,10 @@ * @param the smaller type for mirrored focusing */ @FunctionalInterface -public interface Iso extends LensLike> { - -

, F extends Functor, FB extends Functor, FT extends Functor, - PAFB extends Profunctor, - PSFT extends Profunctor> PSFT apply(PAFB pafb); - - @Override - default , FT extends Functor, FB extends Functor> FT apply( - Function fn, S s) { - return this., F, FB, FT, Fn1, Fn1>apply(fn1(fn)).apply(s); - } +public interface Iso extends + Optic, Functor, S, T, A, B>, + Monad>, + Profunctor> { /** * Convert this {@link Iso} into a {@link Lens}. @@ -68,13 +63,7 @@ default , FT extends Functor, FB extends Functor toLens() { - return new Lens() { - @Override - public , FT extends Functor, FB extends Functor> FT apply( - Function fn, S s) { - return Iso.this.apply(fn, s); - } - }; + return lens(this); } /** @@ -93,7 +82,9 @@ default Iso mirror() { * @return the destructured iso */ default Tuple2, Fn1> unIso() { - return Tuple2.fill(this., Identity, Identity, Identity, + return Tuple2.fill(this., Identity, + Identity, + Identity, Exchange>, Exchange>>apply(new Exchange<>(id(), Identity::new)).diMapR(Identity::runIdentity)) .biMap(e -> fn1(e.sa()), e -> fn1(e.bt())); @@ -101,7 +92,7 @@ default Iso mirror() { @Override default Iso fmap(Function fn) { - return LensLike.super.fmap(fn).coerce(); + return Monad.super.fmap(fn).coerce(); } @Override @@ -110,27 +101,23 @@ default Iso pure(U u) { } @Override - default Iso zip( - Applicative, LensLike>> appFn) { - return LensLike.super.zip(appFn).coerce(); + default Iso zip(Applicative, Iso> appFn) { + return Monad.super.zip(appFn).coerce(); } @Override - default Iso discardL(Applicative>> appB) { - return LensLike.super.discardL(appB).coerce(); + default Iso discardL(Applicative> appB) { + return Monad.super.discardL(appB).coerce(); } @Override - default Iso discardR(Applicative>> appB) { - return LensLike.super.discardR(appB).coerce(); + default Iso discardR(Applicative> appB) { + return Monad.super.discardR(appB).coerce(); } @Override - @SuppressWarnings("RedundantTypeArguments") - default Iso flatMap( - Function>>> fn) { - return unIso().fmap(bt -> Fn2.fn2(fn1(bt.andThen( - fn.>andThen(Monad>>::coerce)) + default Iso flatMap(Function>> fn) { + return unIso().fmap(bt -> Fn2.fn2(fn1(bt.andThen(fn.>andThen(Applicative::coerce)) .andThen(Iso::unIso) .andThen(Tuple2::_2) .andThen(Fn1::fn1)))) @@ -141,77 +128,53 @@ default Iso flatMap( @Override default Iso diMapL(Function fn) { - return LensLike.super.diMapL(fn).coerce(); + return (Iso) Profunctor.super.diMapL(fn); } @Override default Iso diMapR(Function fn) { - return LensLike.super.diMapR(fn).coerce(); + return (Iso) Profunctor.super.diMapR(fn); } @Override default Iso diMap(Function lFn, Function rFn) { - return LensLike.super.diMap(lFn, rFn).coerce(); + return this.mapS(lFn).mapT(rFn); } @Override default Iso contraMap(Function fn) { - return LensLike.super.contraMap(fn).coerce(); + return (Iso) Profunctor.super.contraMap(fn); } @Override default Iso mapS(Function fn) { - return unIso().biMapL(f -> f.compose(fn)).into(Iso::iso); + return iso(Optic.super.mapS(fn)); } @Override default Iso mapT(Function fn) { - return unIso().biMapR(f -> f.andThen(fn)).into(Iso::iso); + return iso(Optic.super.mapT(fn)); } @Override default Iso mapA(Function fn) { - return unIso().biMapL(f -> f.andThen(fn)).into(Iso::iso); + return iso(Optic.super.mapA(fn)); } @Override default Iso mapB(Function fn) { - return unIso().biMapR(f -> f.compose(fn)).into(Iso::iso); + return iso(Optic.super.mapB(fn)); } @Override - default Lens andThen(LensLike f) { - return toLens().andThen(f); - } - - /** - * Left-to-right composition of {@link Iso}. - * - * @param f the iso to apply after this one - * @param the smaller type the first larger type can be viewed as - * @param the smaller type that can be viewed as the second larger type - * @return the composed {@link Iso} - */ - default Iso andThen(Iso f) { - return unIso().into((sa, bt) -> f.unIso().into((ac, db) -> iso(sa.andThen(ac), db.andThen(bt)))); - } - - /** - * Right-to-left composition of {@link Iso}. - * - * @param g the iso to apply before this one - * @param the larger type that can be viewed as the first smaller type - * @param the larger type the second smaller type can be viewed as - * @return the composed {@link Iso} - */ - default Iso compose(Iso g) { - return g.andThen(this); + default Iso andThen(Optic, ? super Functor, A, B, Z, C> f) { + return iso(Optic.super.andThen(f)); } @Override - default Lens compose(LensLike f) { - return toLens().compose(f); + default Iso compose(Optic, ? super Functor, R, U, S, T> g) { + return iso(Optic.super.compose(g)); } /** @@ -227,13 +190,16 @@ default Lens compose(LensLike f) { */ static Iso iso(Function f, Function g) { + return iso(optic(pafb -> pafb.diMap(f, fb -> fb.fmap(g)))); + } + + static Iso iso( + Optic, ? super Functor, S, T, A, B> optic) { return new Iso() { @Override - @SuppressWarnings("unchecked") - public

, F extends Functor, FB extends Functor, - FT extends Functor, PAFB extends Profunctor, - PSFT extends Profunctor> PSFT apply(PAFB pafb) { - return (PSFT) pafb.diMap(f, fb -> (FT) fb.fmap(g)); + public >, CoF extends Functor>, FB extends Functor, FT extends Functor, PAFB extends Profunctor, PSFT extends Profunctor> PSFT apply( + PAFB pafb) { + return optic.apply(pafb); } }; } @@ -259,7 +225,7 @@ static Iso.Simple simpleIso(Function f, Fun * @param the type of both "smaller" values */ @FunctionalInterface - interface Simple extends Iso, LensLike.Simple> { + interface Simple extends Iso, Optic.Simple, Functor, S, A> { /** * Compose two simple isos from right to left. @@ -296,34 +262,35 @@ default Lens.Simple toLens() { } @Override - default Iso.Simple discardR(Applicative>> appB) { + default Iso.Simple discardR(Applicative> appB) { return adapt(Iso.super.discardR(appB)); } @Override - default Lens.Simple compose(LensLike.Simple g) { - return toLens().compose(g); + default Iso.Simple andThen(Optic.Simple, ? super Functor, A, B> f) { + return adapt(Iso.super.andThen(f)); } @Override - default Lens.Simple andThen(LensLike.Simple f) { - return toLens().andThen(f); + default Iso.Simple compose(Optic.Simple, ? super Functor, R, S> g) { + return adapt(Iso.super.compose(g)); } /** - * Adapt an {@link Iso} with the right variance to an {@link Iso.Simple}. + * Adapt an {@link Optic} with the right variance to an {@link Iso.Simple}. * - * @param iso the iso - * @param S/T - * @param A/B + * @param optic the optic + * @param S/T + * @param A/B * @return the simple iso */ - static Iso.Simple adapt(Iso iso) { + static Iso.Simple adapt( + Optic, ? super Functor, S, S, A, A> optic) { return new Iso.Simple() { @Override - public

, F extends Functor, FB extends Functor, FT extends Functor, PAFB extends Profunctor, PSFT extends Profunctor> PSFT apply( + public >, CoF extends Functor>, FB extends Functor, FT extends Functor, PAFB extends Profunctor, PSFT extends Profunctor> PSFT apply( PAFB pafb) { - return iso.apply(pafb); + return optic.apply(pafb); } }; } diff --git a/src/main/java/com/jnape/palatable/lambda/lens/Lens.java b/src/main/java/com/jnape/palatable/lambda/optics/Lens.java similarity index 73% rename from src/main/java/com/jnape/palatable/lambda/lens/Lens.java rename to src/main/java/com/jnape/palatable/lambda/optics/Lens.java index edcb93650..c39feabd3 100644 --- a/src/main/java/com/jnape/palatable/lambda/lens/Lens.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/Lens.java @@ -1,20 +1,20 @@ -package com.jnape.palatable.lambda.lens; +package com.jnape.palatable.lambda.optics; import com.jnape.palatable.lambda.adt.hlist.Tuple2; import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functions.builtin.fn2.Both; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Functor; +import com.jnape.palatable.lambda.functor.Profunctor; import com.jnape.palatable.lambda.monad.Monad; import java.util.function.BiFunction; import java.util.function.Function; -import static com.jnape.palatable.lambda.lens.Iso.iso; -import static com.jnape.palatable.lambda.lens.Lens.Simple.adapt; -import static com.jnape.palatable.lambda.lens.functions.Over.over; -import static com.jnape.palatable.lambda.lens.functions.Set.set; -import static com.jnape.palatable.lambda.lens.functions.View.view; +import static com.jnape.palatable.lambda.optics.Iso.iso; +import static com.jnape.palatable.lambda.optics.Lens.Simple.adapt; +import static com.jnape.palatable.lambda.optics.functions.Set.set; +import static com.jnape.palatable.lambda.optics.functions.View.view; /** * An approximation of van Laarhoven lenses. @@ -137,11 +137,14 @@ * @param the type of the "smaller" update value */ @FunctionalInterface -public interface Lens extends LensLike> { +public interface Lens extends + Optic, Functor, S, T, A, B>, + Monad>, + Profunctor> { @Override default Lens fmap(Function fn) { - return LensLike.super.fmap(fn).coerce(); + return Monad.super.fmap(fn).coerce(); } @Override @@ -150,66 +153,65 @@ default Lens pure(U u) { } @Override - default Lens zip( - Applicative, LensLike>> appFn) { - return LensLike.super.zip(appFn).coerce(); + default Lens zip(Applicative, Lens> appFn) { + return Monad.super.zip(appFn).coerce(); } @Override - default Lens discardL(Applicative>> appB) { - return LensLike.super.discardL(appB).coerce(); + default Lens discardL(Applicative> appB) { + return Monad.super.discardL(appB).coerce(); } @Override - default Lens discardR(Applicative>> appB) { - return LensLike.super.discardR(appB).coerce(); + default Lens discardR(Applicative> appB) { + return Monad.super.discardR(appB).coerce(); } @Override - default Lens flatMap( - Function>>> f) { + default Lens flatMap(Function>> f) { + return lens(view(this), (s, b) -> set(f.apply(set(this, b, s)).>coerce(), b, s)); } @Override default Lens diMapL(Function fn) { - return LensLike.super.diMapL(fn).coerce(); + return (Lens) Profunctor.super.diMapL(fn); } @Override default Lens diMapR(Function fn) { - return LensLike.super.diMapR(fn).coerce(); + return (Lens) Profunctor.super.diMapR(fn); } @Override default Lens diMap(Function lFn, Function rFn) { - return LensLike.super.diMap(lFn, rFn).coerce(); + return this.mapS(lFn).mapT(rFn); } @Override default Lens contraMap(Function fn) { - return LensLike.super.contraMap(fn).coerce(); + return (Lens) Profunctor.super.contraMap(fn); } @Override default Lens mapS(Function fn) { - return lens(view(this).compose(fn), (r, b) -> set(this, b, fn.apply(r))); + return lens(Optic.super.mapS(fn)); } @Override default Lens mapT(Function fn) { - return fmap(fn); + return lens(Optic.super.mapT(fn)); } @Override default Lens mapA(Function fn) { - return andThen(lens(fn, (a, b) -> b)); + return lens(Optic.super.mapA(fn)); } @Override default Lens mapB(Function fn) { - return lens(view(this), (s, z) -> set(this, fn.apply(z), s)); + return lens(Optic.super.mapB(fn)); } /** @@ -223,13 +225,13 @@ default Iso toIso(S s) { } @Override - default Lens andThen(LensLike f) { - return lens(view(this).fmap(view(f)), (q, b) -> over(this, set(f, b), q)); + default Lens andThen(Optic, ? super Functor, A, B, C, D> f) { + return lens(Optic.super.andThen(f)); } @Override - default Lens compose(LensLike g) { - return lens(view(g).fmap(view(this)), (q, b) -> over(g, set(this, b), q)); + default Lens compose(Optic, ? super Functor, R, U, S, T> g) { + return lens(Optic.super.compose(g)); } /** @@ -245,13 +247,21 @@ default Lens compose(LensLike g) { */ static Lens lens(Function getter, BiFunction setter) { + return lens(Optic., Functor, + S, T, A, B, + Functor>, + Functor>, + Fn1>>, + Fn1>>>optic(afb -> s -> afb.apply(getter.apply(s)) + .fmap(b -> setter.apply(s, b)))); + } + + static Lens lens(Optic, ? super Functor, S, T, A, B> optic) { return new Lens() { @Override - @SuppressWarnings("unchecked") - public , FT extends Functor, FB extends Functor> FT apply( - Function fn, - S s) { - return (FT) fn.apply(getter.apply(s)).fmap(b -> setter.apply(s, b)); + public >, CoF extends Functor>, FB extends Functor, FT extends Functor, PAFB extends Profunctor, PSFT extends Profunctor> PSFT apply( + PAFB pafb) { + return optic.apply(pafb); } }; } @@ -309,14 +319,16 @@ static Lens.Simple> both(Lens.Simple f, Lens.Sim * @param the type of both "smaller" values */ @FunctionalInterface - interface Simple extends Lens, LensLike.Simple> { + interface Simple extends Lens, Optic.Simple, Functor, S, A> { - default Lens.Simple compose(LensLike.Simple g) { - return Lens.Simple.adapt(Lens.super.compose(g)); + @Override + default Lens.Simple andThen(Optic.Simple, ? super Functor, A, B> f) { + return Lens.Simple.adapt(Lens.super.andThen(f)); } - default Lens.Simple andThen(LensLike.Simple f) { - return Lens.Simple.adapt(Lens.super.andThen(f)); + @Override + default Lens.Simple compose(Optic.Simple, ? super Functor, R, S> g) { + return Lens.Simple.adapt(Lens.super.compose(g)); } /** @@ -327,12 +339,14 @@ default Lens.Simple andThen(LensLike.Simple f) { * @param A/B * @return the simple lens */ - static Lens.Simple adapt(Lens lens) { + static Lens.Simple adapt(Optic, ? super Functor, S, S, A, A> lens) { return new Lens.Simple() { @Override - public , FT extends Functor, FB extends Functor> FT apply( - Function fn, S s) { - return lens.apply(fn, s); + public >, + CoF extends Functor>, FB extends Functor, + FT extends Functor, PAFB extends Profunctor, + PSFT extends Profunctor> PSFT apply(PAFB pafb) { + return lens.apply(pafb); } }; } diff --git a/src/main/java/com/jnape/palatable/lambda/optics/Optic.java b/src/main/java/com/jnape/palatable/lambda/optics/Optic.java index 684305785..c53e200e5 100644 --- a/src/main/java/com/jnape/palatable/lambda/optics/Optic.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/Optic.java @@ -4,6 +4,8 @@ import com.jnape.palatable.lambda.functor.Functor; import com.jnape.palatable.lambda.functor.Profunctor; +import java.util.function.Function; + /** * A generic supertype representation for profunctor optics. *

@@ -21,11 +23,14 @@ * @param the right side's functor embedding of the input profunctor */ @FunctionalInterface -public interface Optic

, F extends Functor, S, T, A, B> { +public interface Optic

, F extends Functor, S, T, A, B> { - , ? extends CoP>, - PSFT extends Profunctor, ? extends CoP>> PSFT apply(PAFB pafb); + , + CoF extends Functor, + FB extends Functor, + FT extends Functor, + PAFB extends Profunctor, + PSFT extends Profunctor> PSFT apply(PAFB pafb); /** * Produce a monomorphic {@link Fn1} backed by this {@link Optic}. @@ -36,10 +41,197 @@ public interface Optic

, F extends Functor, S * @param the fixed output profunctor type * @return the monomorphic {@link Fn1} backed by this {@link Optic} */ - default , ? extends CoP>, - PSFT extends Profunctor, ? extends CoP>> + default , + CoF extends Functor, + FB extends Functor, + FT extends Functor, + PAFB extends Profunctor, + PSFT extends Profunctor> Fn1 monomorphize() { - return Optic.this::apply; + return this::apply; + } + + /** + * Left-to-right composition of optics. Requires compatibility between S> and T. + * + * @param f the other optic + * @param the new left side of the input profunctor + * @param the new right side's functor embedding of the input profunctor + * @return the composed optic + */ + default Optic andThen(Optic f) { + return new Optic() { + @Override + public , + CoF extends Functor, + FC extends Functor, + FT extends Functor, + PZFC extends Profunctor, + PSFT extends Profunctor> + PSFT apply(PZFC pzfc) { + return Optic.this.apply(f.apply(pzfc)); + } + }; + } + + /** + * Right-to-Left composition of optics. Requires compatibility between A and B. + * + * @param g the other optic + * @param the new left side of the output profunctor + * @param the new right side's functor embedding of the output profunctor + * @return the composed optic + */ + default Optic compose(Optic g) { + return new Optic() { + @Override + public , + CoF extends Functor, + FB extends Functor, + FU extends Functor, + PAFB extends Profunctor, + PRFU extends Profunctor> + PRFU apply(PAFB pafb) { + return g., FU, + Profunctor, ? extends CoP>, PRFU>apply(Optic.this.apply(pafb)); + } + }; + } + + /** + * Contravariantly map S to R, yielding a new optic. + * + * @param fn the mapping function + * @param the new left side of the output profunctor + * @return the new optic + */ + default Optic mapS(Function fn) { + return optic(pafb -> { + Profunctor, ? extends P> psft = apply(pafb); + return psft.diMapL(fn); + }); + } + + /** + * Covariantly map T to U, yielding a new optic. + * + * @param fn the mapping function + * @param the new right side's functor embedding of the output profunctor + * @return the new optic + */ + default Optic mapT(Function fn) { + return optic(pafb -> { + Profunctor, ? extends P> psft = apply(pafb); + return psft.diMapR(ft -> ft.fmap(fn)); + }); + } + + /** + * Covariantly map A to C, yielding a new optic. + * + * @param fn the mapping function + * @param the new left side of the input profunctor + * @return the new optic + */ + default Optic mapA(Function fn) { + return optic(pcfb -> { + @SuppressWarnings("UnnecessaryLocalVariable") + Profunctor, ? extends P> psft = apply(pcfb.diMapL(fn)); + return psft; + }); + } + + /** + * Contravariantly map B to Z, yielding a new optic. + * + * @param fn the mapping function + * @param the new right side's functor embedding of the input profunctor + * @return the new optic + */ + default Optic mapB(Function fn) { + return optic(pafz -> apply(pafz.diMapR(fz -> fz.fmap(fn)))); + } + + /** + * Promote a monomorphic function to a compatible {@link Optic}. + * + * @param fn the function + * @param

the {@link Profunctor} type + * @param the {@link Functor} type + * @param the left side of the output profunctor + * @param the right side's functor embedding of the output profunctor + * @param the left side of the input profunctor + * @param the right side's functor embedding of the input profunctor + * @param the input + * @param the output + * @return the {@link Optic} + */ + static

, + F extends Functor, + S, T, A, B, + FB extends Functor, + FT extends Functor, + PAFB extends Profunctor, + PSFT extends Profunctor> Optic optic( + Function fn) { + return new Optic() { + @Override + @SuppressWarnings("unchecked") + public , + CoF extends Functor, + CoFB extends Functor, + CoFT extends Functor, + CoPAFB extends Profunctor, + CoPSFT extends Profunctor> CoPSFT apply( + CoPAFB pafb) { + return (CoPSFT) fn.apply((PAFB) pafb); + } + }; + } + + interface Simple

, F extends Functor, S, A> extends + Optic { + + /** + * Compose two simple optics from left to right. + * + * @param f the other simple optic + * @param the new left side and right side's functor embedding of the input profunctor + * @return the composed simple optic + */ + @SuppressWarnings("overloads") + default Optic.Simple andThen(Optic.Simple f) { + Optic composed = Optic.super.andThen(f); + return new Simple() { + @Override + public , CoF extends Functor, + FB extends Functor, FT extends Functor, + PAFB extends Profunctor, PSFT extends Profunctor> + PSFT apply(PAFB pafb) { + return composed.apply(pafb); + } + }; + } + + /** + * Compose two simple optics from right to left. + * + * @param g the other simple optic + * @param the new left side and right side's functor embedding of the output profunctor + * @return the composed simple optic + */ + @SuppressWarnings("overloads") + default Optic.Simple compose(Optic.Simple g) { + Optic composed = Optic.super.compose(g); + return new Simple() { + @Override + public , CoF extends Functor, + FB extends Functor, FT extends Functor, + PAFB extends Profunctor, PSFT extends Profunctor> + PSFT apply(PAFB pafb) { + return composed.apply(pafb); + } + }; + } } } diff --git a/src/main/java/com/jnape/palatable/lambda/lens/functions/Over.java b/src/main/java/com/jnape/palatable/lambda/optics/functions/Over.java similarity index 51% rename from src/main/java/com/jnape/palatable/lambda/lens/functions/Over.java rename to src/main/java/com/jnape/palatable/lambda/optics/functions/Over.java index a0c1eaedd..de8b4a541 100644 --- a/src/main/java/com/jnape/palatable/lambda/lens/functions/Over.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/functions/Over.java @@ -1,10 +1,10 @@ -package com.jnape.palatable.lambda.lens.functions; +package com.jnape.palatable.lambda.optics.functions; import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functions.Fn2; import com.jnape.palatable.lambda.functions.Fn3; import com.jnape.palatable.lambda.functor.builtin.Identity; -import com.jnape.palatable.lambda.lens.LensLike; +import com.jnape.palatable.lambda.optics.Optic; import java.util.function.Function; @@ -23,7 +23,7 @@ * @see Set * @see View */ -public final class Over implements Fn3, Function, S, T> { +public final class Over implements Fn3, ? super Identity, S, T, A, B>, Function, S, T> { private static final Over INSTANCE = new Over<>(); @@ -31,10 +31,11 @@ private Over() { } @Override - public T apply(LensLike lens, Function fn, S s) { - return lens., Identity, Identity>apply(fn.andThen((Function>) Identity::new), - s) - .runIdentity(); + public T apply(Optic, ? super Identity, S, T, A, B> optic, + Function fn, + S s) { + return optic., Identity, Identity, Identity, Fn1>, Fn1>>apply( + a -> new Identity<>(fn.apply(a))).apply(s).runIdentity(); } @SuppressWarnings("unchecked") @@ -42,15 +43,18 @@ public static Over over() { return (Over) INSTANCE; } - public static Fn2, S, T> over(LensLike lens) { - return Over.over().apply(lens); + public static Fn2, S, T> over( + Optic, ? super Identity, S, T, A, B> optic) { + return Over.over().apply(optic); } - public static Fn1 over(LensLike lens, Function fn) { - return over(lens).apply(fn); + public static Fn1 over(Optic, ? super Identity, S, T, A, B> optic, + Function fn) { + return over(optic).apply(fn); } - public static T over(LensLike lens, Function fn, S s) { - return over(lens, fn).apply(s); + public static T over(Optic, ? super Identity, S, T, A, B> optic, + Function fn, S s) { + return over(optic, fn).apply(s); } } diff --git a/src/main/java/com/jnape/palatable/lambda/lens/functions/Set.java b/src/main/java/com/jnape/palatable/lambda/optics/functions/Set.java similarity index 57% rename from src/main/java/com/jnape/palatable/lambda/lens/functions/Set.java rename to src/main/java/com/jnape/palatable/lambda/optics/functions/Set.java index cebf0647f..c5c7a7110 100644 --- a/src/main/java/com/jnape/palatable/lambda/lens/functions/Set.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/functions/Set.java @@ -1,13 +1,13 @@ -package com.jnape.palatable.lambda.lens.functions; +package com.jnape.palatable.lambda.optics.functions; import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functions.Fn2; import com.jnape.palatable.lambda.functions.Fn3; import com.jnape.palatable.lambda.functor.builtin.Identity; -import com.jnape.palatable.lambda.lens.LensLike; +import com.jnape.palatable.lambda.optics.Optic; import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; -import static com.jnape.palatable.lambda.lens.functions.Over.over; +import static com.jnape.palatable.lambda.optics.functions.Over.over; /** * Given a lens, a "smaller" value B, and a "larger" value S, produce a T by @@ -23,7 +23,7 @@ * @see Over * @see View */ -public final class Set implements Fn3, B, S, T> { +public final class Set implements Fn3, ? super Identity, S, T, A, B>, B, S, T> { private static final Set INSTANCE = new Set<>(); @@ -31,8 +31,8 @@ private Set() { } @Override - public T apply(LensLike lens, B b, S s) { - return over(lens, constantly(b), s); + public T apply(Optic, ? super Identity, S, T, A, B> optic, B b, S s) { + return over(optic, constantly(b), s); } @SuppressWarnings("unchecked") @@ -40,15 +40,15 @@ public static Set set() { return (Set) INSTANCE; } - public static Fn2 set(LensLike lens) { - return Set.set().apply(lens); + public static Fn2 set(Optic, ? super Identity, S, T, A, B> optic) { + return Set.set().apply(optic); } - public static Fn1 set(LensLike lens, B b) { - return set(lens).apply(b); + public static Fn1 set(Optic, ? super Identity, S, T, A, B> optic, B b) { + return set(optic).apply(b); } - public static T set(LensLike lens, B b, S s) { - return set(lens, b).apply(s); + public static T set(Optic, ? super Identity, S, T, A, B> optic, B b, S s) { + return set(optic, b).apply(s); } } diff --git a/src/main/java/com/jnape/palatable/lambda/optics/functions/Under.java b/src/main/java/com/jnape/palatable/lambda/optics/functions/Under.java new file mode 100644 index 000000000..7356d3ec1 --- /dev/null +++ b/src/main/java/com/jnape/palatable/lambda/optics/functions/Under.java @@ -0,0 +1,60 @@ +package com.jnape.palatable.lambda.optics.functions; + +import com.jnape.palatable.lambda.functions.Fn1; +import com.jnape.palatable.lambda.functions.Fn2; +import com.jnape.palatable.lambda.functions.Fn3; +import com.jnape.palatable.lambda.functor.builtin.Exchange; +import com.jnape.palatable.lambda.functor.builtin.Identity; +import com.jnape.palatable.lambda.optics.Iso; +import com.jnape.palatable.lambda.optics.Optic; + +import java.util.function.Function; + +import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id; + +/** + * The inverse of {@link Over}: given an {@link Iso}, a function from T to S, and a "smaller" + * value B, return a "smaller" value A by traversing around the type ring (B -> T + * -> S -> A). + * + * @param the larger type for focusing + * @param the larger type for mirrored focusing + * @param the smaller type for focusing + * @param the smaller type for mirrored focusing + */ +public final class Under implements Fn3, ? super Identity, S, T, A, B>, Function, B, A> { + + private static final Under INSTANCE = new Under<>(); + + private Under() { + } + + @Override + public A apply(Optic, ? super Identity, S, T, A, B> optic, + Function fn, + B b) { + Exchange> exchange = optic.apply(new Exchange<>(id(), Identity::new)); + return exchange.sa().apply(fn.apply(exchange.bt().apply(b).runIdentity())); + } + + @SuppressWarnings("unchecked") + public static Under under() { + return (Under) INSTANCE; + } + + public static Fn2, B, A> under( + Optic, ? super Identity, S, T, A, B> optic) { + return Under.under().apply(optic); + } + + public static Fn1 under( + Optic, ? super Identity, S, T, A, B> optic, + Function fn) { + return under(optic).apply(fn); + } + + public static A under(Optic, ? super Identity, S, T, A, B> optic, + Function fn, B b) { + return under(optic, fn).apply(b); + } +} diff --git a/src/main/java/com/jnape/palatable/lambda/lens/functions/View.java b/src/main/java/com/jnape/palatable/lambda/optics/functions/View.java similarity index 52% rename from src/main/java/com/jnape/palatable/lambda/lens/functions/View.java rename to src/main/java/com/jnape/palatable/lambda/optics/functions/View.java index b4df1138d..b94992d29 100644 --- a/src/main/java/com/jnape/palatable/lambda/lens/functions/View.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/functions/View.java @@ -1,9 +1,9 @@ -package com.jnape.palatable.lambda.lens.functions; +package com.jnape.palatable.lambda.optics.functions; import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functions.Fn2; import com.jnape.palatable.lambda.functor.builtin.Const; -import com.jnape.palatable.lambda.lens.LensLike; +import com.jnape.palatable.lambda.optics.Optic; /** * Given a lens and a "larger" value S, retrieve a "smaller" value A by lifting the lens into @@ -18,16 +18,17 @@ * @see Set * @see Over */ -public final class View implements Fn2, S, A> { +public final class View implements Fn2, ? super Const, S, T, A, B>, S, A> { - private static final View INSTANCE = new View<>(); + private static final View INSTANCE = new View<>(); private View() { } @Override - public A apply(LensLike lens, S s) { - return lens., Const, Const>apply(Const::new, s).runConst(); + public A apply(Optic, ? super Const, S, T, A, B> optic, S s) { + return optic., Const, Const, Const, Fn1>, Fn1>>apply( + Const::new).apply(s).runConst(); } @SuppressWarnings("unchecked") @@ -35,11 +36,11 @@ public static View view() { return (View) INSTANCE; } - public static Fn1 view(LensLike lens) { - return View.view().apply(lens); + public static Fn1 view(Optic, ? super Const, S, T, A, B> optic) { + return View.view().apply(optic); } - public static A view(LensLike lens, S s) { - return view(lens).apply(s); + public static A view(Optic, ? super Const, S, T, A, B> optic, S s) { + return view(optic).apply(s); } } diff --git a/src/main/java/com/jnape/palatable/lambda/lens/lenses/CollectionLens.java b/src/main/java/com/jnape/palatable/lambda/optics/lenses/CollectionLens.java similarity index 94% rename from src/main/java/com/jnape/palatable/lambda/lens/lenses/CollectionLens.java rename to src/main/java/com/jnape/palatable/lambda/optics/lenses/CollectionLens.java index 10c54dca9..9a8a8ee29 100644 --- a/src/main/java/com/jnape/palatable/lambda/lens/lenses/CollectionLens.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/lenses/CollectionLens.java @@ -1,6 +1,6 @@ -package com.jnape.palatable.lambda.lens.lenses; +package com.jnape.palatable.lambda.optics.lenses; -import com.jnape.palatable.lambda.lens.Lens; +import com.jnape.palatable.lambda.optics.Lens; import java.util.Collection; import java.util.HashSet; @@ -8,7 +8,7 @@ import java.util.function.Function; import java.util.stream.Stream; -import static com.jnape.palatable.lambda.lens.Lens.simpleLens; +import static com.jnape.palatable.lambda.optics.Lens.simpleLens; /** * Lenses that operate on {@link Collection}s. diff --git a/src/main/java/com/jnape/palatable/lambda/lens/lenses/EitherLens.java b/src/main/java/com/jnape/palatable/lambda/optics/lenses/EitherLens.java similarity index 91% rename from src/main/java/com/jnape/palatable/lambda/lens/lenses/EitherLens.java rename to src/main/java/com/jnape/palatable/lambda/optics/lenses/EitherLens.java index 50b840e5c..0aa4b86a3 100644 --- a/src/main/java/com/jnape/palatable/lambda/lens/lenses/EitherLens.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/lenses/EitherLens.java @@ -1,11 +1,11 @@ -package com.jnape.palatable.lambda.lens.lenses; +package com.jnape.palatable.lambda.optics.lenses; import com.jnape.palatable.lambda.adt.Either; import com.jnape.palatable.lambda.adt.Maybe; import com.jnape.palatable.lambda.adt.coproduct.CoProduct2; -import com.jnape.palatable.lambda.lens.Lens; +import com.jnape.palatable.lambda.optics.Lens; -import static com.jnape.palatable.lambda.lens.Lens.simpleLens; +import static com.jnape.palatable.lambda.optics.Lens.simpleLens; /** * Lenses that operate on {@link Either}s. diff --git a/src/main/java/com/jnape/palatable/lambda/lens/lenses/HListLens.java b/src/main/java/com/jnape/palatable/lambda/optics/lenses/HListLens.java similarity index 90% rename from src/main/java/com/jnape/palatable/lambda/lens/lenses/HListLens.java rename to src/main/java/com/jnape/palatable/lambda/optics/lenses/HListLens.java index bc0ce452b..2af87a94a 100644 --- a/src/main/java/com/jnape/palatable/lambda/lens/lenses/HListLens.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/lenses/HListLens.java @@ -1,12 +1,12 @@ -package com.jnape.palatable.lambda.lens.lenses; +package com.jnape.palatable.lambda.optics.lenses; import com.jnape.palatable.lambda.adt.hlist.HList; import com.jnape.palatable.lambda.adt.hlist.HList.HCons; import com.jnape.palatable.lambda.adt.hlist.Index; -import com.jnape.palatable.lambda.lens.Lens; +import com.jnape.palatable.lambda.optics.Lens; import static com.jnape.palatable.lambda.adt.hlist.HList.cons; -import static com.jnape.palatable.lambda.lens.Lens.simpleLens; +import static com.jnape.palatable.lambda.optics.Lens.simpleLens; /** * Lenses that operate on {@link HList}s. diff --git a/src/main/java/com/jnape/palatable/lambda/lens/lenses/HMapLens.java b/src/main/java/com/jnape/palatable/lambda/optics/lenses/HMapLens.java similarity index 81% rename from src/main/java/com/jnape/palatable/lambda/lens/lenses/HMapLens.java rename to src/main/java/com/jnape/palatable/lambda/optics/lenses/HMapLens.java index c7fd953da..f98446254 100644 --- a/src/main/java/com/jnape/palatable/lambda/lens/lenses/HMapLens.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/lenses/HMapLens.java @@ -1,11 +1,11 @@ -package com.jnape.palatable.lambda.lens.lenses; +package com.jnape.palatable.lambda.optics.lenses; import com.jnape.palatable.lambda.adt.Maybe; import com.jnape.palatable.lambda.adt.hmap.HMap; import com.jnape.palatable.lambda.adt.hmap.TypeSafeKey; -import com.jnape.palatable.lambda.lens.Lens; +import com.jnape.palatable.lambda.optics.Lens; -import static com.jnape.palatable.lambda.lens.Lens.simpleLens; +import static com.jnape.palatable.lambda.optics.Lens.simpleLens; /** * Lenses that operate on {@link HMap}s. diff --git a/src/main/java/com/jnape/palatable/lambda/lens/lenses/IterableLens.java b/src/main/java/com/jnape/palatable/lambda/optics/lenses/IterableLens.java similarity index 86% rename from src/main/java/com/jnape/palatable/lambda/lens/lenses/IterableLens.java rename to src/main/java/com/jnape/palatable/lambda/optics/lenses/IterableLens.java index cccf68730..3bab7f98c 100644 --- a/src/main/java/com/jnape/palatable/lambda/lens/lenses/IterableLens.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/lenses/IterableLens.java @@ -1,18 +1,18 @@ -package com.jnape.palatable.lambda.lens.lenses; +package com.jnape.palatable.lambda.optics.lenses; import com.jnape.palatable.lambda.adt.Maybe; import com.jnape.palatable.lambda.functions.builtin.fn1.Head; import com.jnape.palatable.lambda.functions.builtin.fn1.Tail; -import com.jnape.palatable.lambda.lens.Iso; -import com.jnape.palatable.lambda.lens.Lens; +import com.jnape.palatable.lambda.optics.Iso; +import com.jnape.palatable.lambda.optics.Lens; import static com.jnape.palatable.lambda.functions.Fn2.fn2; import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id; import static com.jnape.palatable.lambda.functions.builtin.fn2.Cons.cons; import static com.jnape.palatable.lambda.functions.builtin.fn2.Map.map; -import static com.jnape.palatable.lambda.lens.Iso.simpleIso; -import static com.jnape.palatable.lambda.lens.Lens.simpleLens; -import static com.jnape.palatable.lambda.lens.functions.View.view; +import static com.jnape.palatable.lambda.optics.Iso.simpleIso; +import static com.jnape.palatable.lambda.optics.Lens.simpleLens; +import static com.jnape.palatable.lambda.optics.functions.View.view; /** * Lenses that operate on {@link Iterable}s. diff --git a/src/main/java/com/jnape/palatable/lambda/lens/lenses/ListLens.java b/src/main/java/com/jnape/palatable/lambda/optics/lenses/ListLens.java similarity index 88% rename from src/main/java/com/jnape/palatable/lambda/lens/lenses/ListLens.java rename to src/main/java/com/jnape/palatable/lambda/optics/lenses/ListLens.java index b7857df2a..383c1a226 100644 --- a/src/main/java/com/jnape/palatable/lambda/lens/lenses/ListLens.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/lenses/ListLens.java @@ -1,7 +1,7 @@ -package com.jnape.palatable.lambda.lens.lenses; +package com.jnape.palatable.lambda.optics.lenses; import com.jnape.palatable.lambda.adt.Maybe; -import com.jnape.palatable.lambda.lens.Lens; +import com.jnape.palatable.lambda.optics.Lens; import java.util.ArrayList; import java.util.List; @@ -9,9 +9,9 @@ import static com.jnape.palatable.lambda.adt.Maybe.maybe; import static com.jnape.palatable.lambda.functions.builtin.fn1.Repeat.repeat; import static com.jnape.palatable.lambda.functions.builtin.fn2.Take.take; -import static com.jnape.palatable.lambda.lens.Lens.simpleLens; -import static com.jnape.palatable.lambda.lens.lenses.MaybeLens.unLiftA; -import static com.jnape.palatable.lambda.lens.lenses.MaybeLens.unLiftB; +import static com.jnape.palatable.lambda.optics.Lens.simpleLens; +import static com.jnape.palatable.lambda.optics.lenses.MaybeLens.unLiftA; +import static com.jnape.palatable.lambda.optics.lenses.MaybeLens.unLiftB; import static java.lang.Math.abs; /** @@ -73,8 +73,7 @@ public static Lens.Simple, Maybe> elementAt(int index) { * @param the list element type * @return the element at the index, or defaultValue */ - @SuppressWarnings("unchecked") public static Lens.Simple, X> elementAt(int index, X defaultValue) { - return unLiftB(unLiftA(elementAt(index), defaultValue))::apply; + return Lens.Simple.adapt(unLiftB(unLiftA(elementAt(index), defaultValue))); } } diff --git a/src/main/java/com/jnape/palatable/lambda/lens/lenses/MapLens.java b/src/main/java/com/jnape/palatable/lambda/optics/lenses/MapLens.java similarity index 93% rename from src/main/java/com/jnape/palatable/lambda/lens/lenses/MapLens.java rename to src/main/java/com/jnape/palatable/lambda/optics/lenses/MapLens.java index 63823404f..63fb09016 100644 --- a/src/main/java/com/jnape/palatable/lambda/lens/lenses/MapLens.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/lenses/MapLens.java @@ -1,12 +1,12 @@ -package com.jnape.palatable.lambda.lens.lenses; +package com.jnape.palatable.lambda.optics.lenses; import com.jnape.palatable.lambda.adt.Maybe; import com.jnape.palatable.lambda.adt.hlist.Tuple2; import com.jnape.palatable.lambda.functions.Fn1; -import com.jnape.palatable.lambda.io.IO; import com.jnape.palatable.lambda.functions.builtin.fn2.Filter; -import com.jnape.palatable.lambda.lens.Iso; -import com.jnape.palatable.lambda.lens.Lens; +import com.jnape.palatable.lambda.io.IO; +import com.jnape.palatable.lambda.optics.Iso; +import com.jnape.palatable.lambda.optics.Lens; import java.util.ArrayList; import java.util.Collection; @@ -21,12 +21,12 @@ import static com.jnape.palatable.lambda.functions.builtin.fn2.Map.map; import static com.jnape.palatable.lambda.functions.builtin.fn2.ToCollection.toCollection; import static com.jnape.palatable.lambda.functions.builtin.fn2.ToMap.toMap; -import static com.jnape.palatable.lambda.lens.Lens.Simple.adapt; -import static com.jnape.palatable.lambda.lens.Lens.lens; -import static com.jnape.palatable.lambda.lens.Lens.simpleLens; -import static com.jnape.palatable.lambda.lens.functions.View.view; -import static com.jnape.palatable.lambda.lens.lenses.MaybeLens.unLiftA; -import static com.jnape.palatable.lambda.lens.lenses.MaybeLens.unLiftB; +import static com.jnape.palatable.lambda.optics.Lens.Simple.adapt; +import static com.jnape.palatable.lambda.optics.Lens.lens; +import static com.jnape.palatable.lambda.optics.Lens.simpleLens; +import static com.jnape.palatable.lambda.optics.functions.View.view; +import static com.jnape.palatable.lambda.optics.lenses.MaybeLens.unLiftA; +import static com.jnape.palatable.lambda.optics.lenses.MaybeLens.unLiftB; /** * Lenses that operate on {@link Map}s. diff --git a/src/main/java/com/jnape/palatable/lambda/lens/lenses/MaybeLens.java b/src/main/java/com/jnape/palatable/lambda/optics/lenses/MaybeLens.java similarity index 97% rename from src/main/java/com/jnape/palatable/lambda/lens/lenses/MaybeLens.java rename to src/main/java/com/jnape/palatable/lambda/optics/lenses/MaybeLens.java index 0917b07ae..5bb9f93da 100644 --- a/src/main/java/com/jnape/palatable/lambda/lens/lenses/MaybeLens.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/lenses/MaybeLens.java @@ -1,9 +1,9 @@ -package com.jnape.palatable.lambda.lens.lenses; +package com.jnape.palatable.lambda.optics.lenses; import com.jnape.palatable.lambda.adt.Maybe; -import com.jnape.palatable.lambda.lens.Lens; +import com.jnape.palatable.lambda.optics.Lens; -import static com.jnape.palatable.lambda.lens.Lens.simpleLens; +import static com.jnape.palatable.lambda.optics.Lens.simpleLens; /** * Lenses that operate on {@link Maybe}. diff --git a/src/main/java/com/jnape/palatable/lambda/lens/lenses/SetLens.java b/src/main/java/com/jnape/palatable/lambda/optics/lenses/SetLens.java similarity index 91% rename from src/main/java/com/jnape/palatable/lambda/lens/lenses/SetLens.java rename to src/main/java/com/jnape/palatable/lambda/optics/lenses/SetLens.java index b48ceea24..a96e9eb46 100644 --- a/src/main/java/com/jnape/palatable/lambda/lens/lenses/SetLens.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/lenses/SetLens.java @@ -1,12 +1,12 @@ -package com.jnape.palatable.lambda.lens.lenses; +package com.jnape.palatable.lambda.optics.lenses; -import com.jnape.palatable.lambda.lens.Lens; +import com.jnape.palatable.lambda.optics.Lens; import java.util.HashSet; import java.util.Set; import java.util.function.Function; -import static com.jnape.palatable.lambda.lens.Lens.simpleLens; +import static com.jnape.palatable.lambda.optics.Lens.simpleLens; /** * Lenses that operate on {@link Set}s. diff --git a/src/test/java/com/jnape/palatable/lambda/adt/hmap/HMapTest.java b/src/test/java/com/jnape/palatable/lambda/adt/hmap/HMapTest.java index 9c2456ab8..f9e849f78 100644 --- a/src/test/java/com/jnape/palatable/lambda/adt/hmap/HMapTest.java +++ b/src/test/java/com/jnape/palatable/lambda/adt/hmap/HMapTest.java @@ -13,7 +13,7 @@ import static com.jnape.palatable.lambda.adt.hmap.HMap.hMap; import static com.jnape.palatable.lambda.adt.hmap.HMap.singletonHMap; import static com.jnape.palatable.lambda.adt.hmap.TypeSafeKey.typeSafeKey; -import static com.jnape.palatable.lambda.lens.Iso.simpleIso; +import static com.jnape.palatable.lambda.optics.Iso.simpleIso; import static java.math.BigInteger.ONE; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; diff --git a/src/test/java/com/jnape/palatable/lambda/adt/hmap/SchemaTest.java b/src/test/java/com/jnape/palatable/lambda/adt/hmap/SchemaTest.java index 5d76e50cd..3fdbde74f 100644 --- a/src/test/java/com/jnape/palatable/lambda/adt/hmap/SchemaTest.java +++ b/src/test/java/com/jnape/palatable/lambda/adt/hmap/SchemaTest.java @@ -9,7 +9,7 @@ import static com.jnape.palatable.lambda.adt.hmap.HMap.hMap; import static com.jnape.palatable.lambda.adt.hmap.Schema.schema; import static com.jnape.palatable.lambda.adt.hmap.TypeSafeKey.typeSafeKey; -import static com.jnape.palatable.lambda.lens.functions.View.view; +import static com.jnape.palatable.lambda.optics.functions.View.view; import static java.util.Arrays.asList; import static org.junit.Assert.assertEquals; import static testsupport.assertion.LensAssert.assertLensLawfulness; diff --git a/src/test/java/com/jnape/palatable/lambda/adt/hmap/TypeSafeKeyTest.java b/src/test/java/com/jnape/palatable/lambda/adt/hmap/TypeSafeKeyTest.java index b9bb7e802..f03acea5b 100644 --- a/src/test/java/com/jnape/palatable/lambda/adt/hmap/TypeSafeKeyTest.java +++ b/src/test/java/com/jnape/palatable/lambda/adt/hmap/TypeSafeKeyTest.java @@ -6,7 +6,7 @@ import static com.jnape.palatable.lambda.adt.hmap.HMap.emptyHMap; import static com.jnape.palatable.lambda.adt.hmap.TypeSafeKey.typeSafeKey; import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id; -import static com.jnape.palatable.lambda.lens.Iso.simpleIso; +import static com.jnape.palatable.lambda.optics.Iso.simpleIso; import static java.util.Arrays.asList; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; diff --git a/src/test/java/com/jnape/palatable/lambda/lens/IsoTest.java b/src/test/java/com/jnape/palatable/lambda/optics/IsoTest.java similarity index 72% rename from src/test/java/com/jnape/palatable/lambda/lens/IsoTest.java rename to src/test/java/com/jnape/palatable/lambda/optics/IsoTest.java index de5557f15..91c181029 100644 --- a/src/test/java/com/jnape/palatable/lambda/lens/IsoTest.java +++ b/src/test/java/com/jnape/palatable/lambda/optics/IsoTest.java @@ -1,8 +1,6 @@ -package com.jnape.palatable.lambda.lens; +package com.jnape.palatable.lambda.optics; import com.jnape.palatable.lambda.adt.Maybe; -import com.jnape.palatable.lambda.functor.Functor; -import com.jnape.palatable.lambda.functor.builtin.Const; import com.jnape.palatable.traitor.annotations.TestTraits; import com.jnape.palatable.traitor.runners.Traits; import org.junit.Test; @@ -15,9 +13,9 @@ import java.util.List; import static com.jnape.palatable.lambda.adt.Maybe.just; -import static com.jnape.palatable.lambda.lens.Iso.iso; -import static com.jnape.palatable.lambda.lens.functions.Set.set; -import static com.jnape.palatable.lambda.lens.functions.View.view; +import static com.jnape.palatable.lambda.optics.Iso.iso; +import static com.jnape.palatable.lambda.optics.functions.Set.set; +import static com.jnape.palatable.lambda.optics.functions.View.view; import static java.util.Arrays.asList; import static java.util.stream.Collectors.toList; import static org.junit.Assert.assertEquals; @@ -29,12 +27,8 @@ public class IsoTest { iso(Integer::parseInt, dbl -> dbl.toString().chars().mapToObj(x -> (char) x).collect(toList())); @TestTraits({FunctorLaws.class, ApplicativeLaws.class, MonadLaws.class}) - public EquatableM>, List> testSubject() { - return new EquatableM<>(ISO, iso -> { - @SuppressWarnings("UnnecessaryLocalVariable") - Functor> result = iso.apply(Const::new, "123"); - return result; - }); + public EquatableM, List> testSubject() { + return new EquatableM<>(ISO, iso -> view(iso, "123")); } @Test diff --git a/src/test/java/com/jnape/palatable/lambda/lens/LensTest.java b/src/test/java/com/jnape/palatable/lambda/optics/LensTest.java similarity index 72% rename from src/test/java/com/jnape/palatable/lambda/lens/LensTest.java rename to src/test/java/com/jnape/palatable/lambda/optics/LensTest.java index 4ab9622a9..f5b1cbf2a 100644 --- a/src/test/java/com/jnape/palatable/lambda/lens/LensTest.java +++ b/src/test/java/com/jnape/palatable/lambda/optics/LensTest.java @@ -1,7 +1,8 @@ -package com.jnape.palatable.lambda.lens; +package com.jnape.palatable.lambda.optics; import com.jnape.palatable.lambda.adt.Maybe; import com.jnape.palatable.lambda.adt.hlist.Tuple2; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functor.builtin.Const; import com.jnape.palatable.lambda.functor.builtin.Identity; import com.jnape.palatable.traitor.annotations.TestTraits; @@ -19,11 +20,11 @@ import static com.jnape.palatable.lambda.adt.Maybe.just; import static com.jnape.palatable.lambda.adt.hlist.HList.tuple; -import static com.jnape.palatable.lambda.lens.Lens.both; -import static com.jnape.palatable.lambda.lens.Lens.lens; -import static com.jnape.palatable.lambda.lens.Lens.simpleLens; -import static com.jnape.palatable.lambda.lens.functions.Set.set; -import static com.jnape.palatable.lambda.lens.functions.View.view; +import static com.jnape.palatable.lambda.optics.Lens.both; +import static com.jnape.palatable.lambda.optics.Lens.lens; +import static com.jnape.palatable.lambda.optics.Lens.simpleLens; +import static com.jnape.palatable.lambda.optics.functions.Set.set; +import static com.jnape.palatable.lambda.optics.functions.View.view; import static java.lang.Integer.parseInt; import static java.util.Arrays.asList; import static java.util.Collections.emptyMap; @@ -41,19 +42,24 @@ public class LensTest { LENS = lens(xs -> xs.get(0), (xs, i) -> singleton(i)); @TestTraits({FunctorLaws.class, ApplicativeLaws.class, MonadLaws.class}) - public EquatableM, ?, Integer, String, Lens>, ?> testSubject() { - return new EquatableM<>(lens(m -> m.get("foo"), (m, s) -> singletonList(m.get(s))), l -> view(l, emptyMap())); + public EquatableM, ?, Integer, String>, List> testSubject() { + return new EquatableM<>(lens(m -> m.get("foo"), (m, s) -> singletonList(m.get(s))), + lens -> view(lens, emptyMap())); } @Test public void setsUnderIdentity() { - Set ints = LENS., Identity>, Identity>apply(s -> new Identity<>(s.length()), asList("foo", "bar", "baz")).runIdentity(); + Set ints = LENS., Identity, Identity, Identity>, + Fn1>, Fn1, Identity>>>apply( + s -> new Identity<>(s.length())).apply(asList("foo", "bar", "baz")).runIdentity(); assertEquals(singleton(3), ints); } @Test public void viewsUnderConst() { - Integer i = LENS., Const>, Const>apply(s -> new Const<>(s.length()), asList("foo", "bar", "baz")).runConst(); + Integer i = LENS., Const, Const, Const>, + Fn1>, Fn1, Const>>>apply( + s -> new Const<>(s.length())).apply(asList("foo", "bar", "baz")).runConst(); assertEquals((Integer) 3, i); } @@ -67,10 +73,12 @@ public void mapsIndividuallyOverParameters() { .mapB((Maybe maybeI) -> maybeI.orElse(-1)); assertEquals(just(true), - theGambit., Identity>, Identity>>apply( - maybeC -> new Identity<>(maybeC.fmap(c -> parseInt(Character.toString(c)))), - just("321")).runIdentity() - ); + theGambit., Identity, Identity>, Identity>, + Fn1, Identity>>, + Fn1, Identity>>>apply( + maybeC -> new Identity<>(maybeC.fmap(c -> parseInt(Character.toString(c))))) + .apply(just("321")) + .runIdentity()); } @Test diff --git a/src/test/java/com/jnape/palatable/lambda/lens/functions/OverTest.java b/src/test/java/com/jnape/palatable/lambda/optics/functions/OverTest.java similarity index 68% rename from src/test/java/com/jnape/palatable/lambda/lens/functions/OverTest.java rename to src/test/java/com/jnape/palatable/lambda/optics/functions/OverTest.java index e5a95cf4a..ef2adf7a6 100644 --- a/src/test/java/com/jnape/palatable/lambda/lens/functions/OverTest.java +++ b/src/test/java/com/jnape/palatable/lambda/optics/functions/OverTest.java @@ -1,13 +1,13 @@ -package com.jnape.palatable.lambda.lens.functions; +package com.jnape.palatable.lambda.optics.functions; -import com.jnape.palatable.lambda.lens.Lens; +import com.jnape.palatable.lambda.optics.Lens; import org.junit.Test; import java.util.List; import java.util.Set; -import static com.jnape.palatable.lambda.lens.Lens.lens; -import static com.jnape.palatable.lambda.lens.functions.Over.over; +import static com.jnape.palatable.lambda.optics.Lens.lens; +import static com.jnape.palatable.lambda.optics.functions.Over.over; import static java.util.Arrays.asList; import static java.util.Collections.singleton; import static org.junit.Assert.assertEquals; diff --git a/src/test/java/com/jnape/palatable/lambda/lens/functions/SetTest.java b/src/test/java/com/jnape/palatable/lambda/optics/functions/SetTest.java similarity index 67% rename from src/test/java/com/jnape/palatable/lambda/lens/functions/SetTest.java rename to src/test/java/com/jnape/palatable/lambda/optics/functions/SetTest.java index 47fa8a959..11a6bdcc5 100644 --- a/src/test/java/com/jnape/palatable/lambda/lens/functions/SetTest.java +++ b/src/test/java/com/jnape/palatable/lambda/optics/functions/SetTest.java @@ -1,12 +1,12 @@ -package com.jnape.palatable.lambda.lens.functions; +package com.jnape.palatable.lambda.optics.functions; -import com.jnape.palatable.lambda.lens.Lens; +import com.jnape.palatable.lambda.optics.Lens; import org.junit.Test; import java.util.List; -import static com.jnape.palatable.lambda.lens.Lens.lens; -import static com.jnape.palatable.lambda.lens.functions.Set.set; +import static com.jnape.palatable.lambda.optics.Lens.lens; +import static com.jnape.palatable.lambda.optics.functions.Set.set; import static java.util.Arrays.asList; import static java.util.Collections.singleton; import static org.junit.Assert.assertEquals; diff --git a/src/test/java/com/jnape/palatable/lambda/lens/functions/UnderTest.java b/src/test/java/com/jnape/palatable/lambda/optics/functions/UnderTest.java similarity index 68% rename from src/test/java/com/jnape/palatable/lambda/lens/functions/UnderTest.java rename to src/test/java/com/jnape/palatable/lambda/optics/functions/UnderTest.java index 58d44f19f..15827500b 100644 --- a/src/test/java/com/jnape/palatable/lambda/lens/functions/UnderTest.java +++ b/src/test/java/com/jnape/palatable/lambda/optics/functions/UnderTest.java @@ -1,14 +1,14 @@ -package com.jnape.palatable.lambda.lens.functions; +package com.jnape.palatable.lambda.optics.functions; -import com.jnape.palatable.lambda.lens.Iso; +import com.jnape.palatable.lambda.optics.Iso; import org.junit.Test; import java.util.Collections; import java.util.List; import java.util.Set; -import static com.jnape.palatable.lambda.lens.Iso.iso; -import static com.jnape.palatable.lambda.lens.functions.Under.under; +import static com.jnape.palatable.lambda.optics.Iso.iso; +import static com.jnape.palatable.lambda.optics.functions.Under.under; import static java.util.Collections.singletonList; import static org.junit.Assert.assertEquals; diff --git a/src/test/java/com/jnape/palatable/lambda/lens/functions/ViewTest.java b/src/test/java/com/jnape/palatable/lambda/optics/functions/ViewTest.java similarity index 67% rename from src/test/java/com/jnape/palatable/lambda/lens/functions/ViewTest.java rename to src/test/java/com/jnape/palatable/lambda/optics/functions/ViewTest.java index 201ec990a..07f7a047a 100644 --- a/src/test/java/com/jnape/palatable/lambda/lens/functions/ViewTest.java +++ b/src/test/java/com/jnape/palatable/lambda/optics/functions/ViewTest.java @@ -1,13 +1,13 @@ -package com.jnape.palatable.lambda.lens.functions; +package com.jnape.palatable.lambda.optics.functions; -import com.jnape.palatable.lambda.lens.Lens; +import com.jnape.palatable.lambda.optics.Lens; import org.junit.Test; import java.util.List; import java.util.Set; -import static com.jnape.palatable.lambda.lens.Lens.lens; -import static com.jnape.palatable.lambda.lens.functions.View.view; +import static com.jnape.palatable.lambda.optics.Lens.lens; +import static com.jnape.palatable.lambda.optics.functions.View.view; import static java.util.Arrays.asList; import static java.util.Collections.singleton; import static org.junit.Assert.assertEquals; diff --git a/src/test/java/com/jnape/palatable/lambda/lens/lenses/CollectionLensTest.java b/src/test/java/com/jnape/palatable/lambda/optics/lenses/CollectionLensTest.java similarity index 80% rename from src/test/java/com/jnape/palatable/lambda/lens/lenses/CollectionLensTest.java rename to src/test/java/com/jnape/palatable/lambda/optics/lenses/CollectionLensTest.java index 07d88c2de..1c13ef7c9 100644 --- a/src/test/java/com/jnape/palatable/lambda/lens/lenses/CollectionLensTest.java +++ b/src/test/java/com/jnape/palatable/lambda/optics/lenses/CollectionLensTest.java @@ -1,6 +1,6 @@ -package com.jnape.palatable.lambda.lens.lenses; +package com.jnape.palatable.lambda.optics.lenses; -import com.jnape.palatable.lambda.lens.Lens; +import com.jnape.palatable.lambda.optics.Lens; import org.junit.Test; import java.util.ArrayList; @@ -8,10 +8,10 @@ import java.util.List; import java.util.stream.Stream; -import static com.jnape.palatable.lambda.lens.functions.Set.set; -import static com.jnape.palatable.lambda.lens.functions.View.view; -import static com.jnape.palatable.lambda.lens.lenses.CollectionLens.asCopy; -import static com.jnape.palatable.lambda.lens.lenses.CollectionLens.asSet; +import static com.jnape.palatable.lambda.optics.functions.Set.set; +import static com.jnape.palatable.lambda.optics.functions.View.view; +import static com.jnape.palatable.lambda.optics.lenses.CollectionLens.asCopy; +import static com.jnape.palatable.lambda.optics.lenses.CollectionLens.asSet; import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static java.util.Collections.emptySet; diff --git a/src/test/java/com/jnape/palatable/lambda/lens/lenses/EitherLensTest.java b/src/test/java/com/jnape/palatable/lambda/optics/lenses/EitherLensTest.java similarity index 86% rename from src/test/java/com/jnape/palatable/lambda/lens/lenses/EitherLensTest.java rename to src/test/java/com/jnape/palatable/lambda/optics/lenses/EitherLensTest.java index 08bf1d3e3..1d300f389 100644 --- a/src/test/java/com/jnape/palatable/lambda/lens/lenses/EitherLensTest.java +++ b/src/test/java/com/jnape/palatable/lambda/optics/lenses/EitherLensTest.java @@ -1,16 +1,16 @@ -package com.jnape.palatable.lambda.lens.lenses; +package com.jnape.palatable.lambda.optics.lenses; import com.jnape.palatable.lambda.adt.Either; import com.jnape.palatable.lambda.adt.Maybe; -import com.jnape.palatable.lambda.lens.Lens; +import com.jnape.palatable.lambda.optics.Lens; import org.junit.Test; import static com.jnape.palatable.lambda.adt.Either.left; import static com.jnape.palatable.lambda.adt.Either.right; import static com.jnape.palatable.lambda.adt.Maybe.just; import static com.jnape.palatable.lambda.adt.Maybe.nothing; -import static com.jnape.palatable.lambda.lens.functions.Set.set; -import static com.jnape.palatable.lambda.lens.functions.View.view; +import static com.jnape.palatable.lambda.optics.functions.Set.set; +import static com.jnape.palatable.lambda.optics.functions.View.view; import static org.junit.Assert.assertEquals; public class EitherLensTest { diff --git a/src/test/java/com/jnape/palatable/lambda/lens/lenses/HListLensTest.java b/src/test/java/com/jnape/palatable/lambda/optics/lenses/HListLensTest.java similarity index 90% rename from src/test/java/com/jnape/palatable/lambda/lens/lenses/HListLensTest.java rename to src/test/java/com/jnape/palatable/lambda/optics/lenses/HListLensTest.java index 6296ff3ef..09c8de717 100644 --- a/src/test/java/com/jnape/palatable/lambda/lens/lenses/HListLensTest.java +++ b/src/test/java/com/jnape/palatable/lambda/optics/lenses/HListLensTest.java @@ -1,11 +1,11 @@ -package com.jnape.palatable.lambda.lens.lenses; +package com.jnape.palatable.lambda.optics.lenses; import com.jnape.palatable.lambda.adt.hlist.Index; import org.junit.Test; import static com.jnape.palatable.lambda.adt.hlist.HList.singletonHList; import static com.jnape.palatable.lambda.adt.hlist.HList.tuple; -import static com.jnape.palatable.lambda.lens.lenses.HListLens.elementAt; +import static com.jnape.palatable.lambda.optics.lenses.HListLens.elementAt; import static java.util.Arrays.asList; import static java.util.Collections.singletonList; import static testsupport.assertion.LensAssert.assertLensLawfulness; diff --git a/src/test/java/com/jnape/palatable/lambda/lens/lenses/HMapLensTest.java b/src/test/java/com/jnape/palatable/lambda/optics/lenses/HMapLensTest.java similarity index 96% rename from src/test/java/com/jnape/palatable/lambda/lens/lenses/HMapLensTest.java rename to src/test/java/com/jnape/palatable/lambda/optics/lenses/HMapLensTest.java index 66073427e..94041fb6e 100644 --- a/src/test/java/com/jnape/palatable/lambda/lens/lenses/HMapLensTest.java +++ b/src/test/java/com/jnape/palatable/lambda/optics/lenses/HMapLensTest.java @@ -1,4 +1,4 @@ -package com.jnape.palatable.lambda.lens.lenses; +package com.jnape.palatable.lambda.optics.lenses; import com.jnape.palatable.lambda.adt.hmap.TypeSafeKey; import org.junit.Test; diff --git a/src/test/java/com/jnape/palatable/lambda/lens/lenses/IterableLensTest.java b/src/test/java/com/jnape/palatable/lambda/optics/lenses/IterableLensTest.java similarity index 87% rename from src/test/java/com/jnape/palatable/lambda/lens/lenses/IterableLensTest.java rename to src/test/java/com/jnape/palatable/lambda/optics/lenses/IterableLensTest.java index 561bc4d99..3353c9eed 100644 --- a/src/test/java/com/jnape/palatable/lambda/lens/lenses/IterableLensTest.java +++ b/src/test/java/com/jnape/palatable/lambda/optics/lenses/IterableLensTest.java @@ -1,17 +1,17 @@ -package com.jnape.palatable.lambda.lens.lenses; +package com.jnape.palatable.lambda.optics.lenses; import com.jnape.palatable.lambda.adt.Maybe; -import com.jnape.palatable.lambda.lens.Iso; -import com.jnape.palatable.lambda.lens.Lens; +import com.jnape.palatable.lambda.optics.Iso; +import com.jnape.palatable.lambda.optics.Lens; import org.junit.Test; import static com.jnape.palatable.lambda.adt.Maybe.just; import static com.jnape.palatable.lambda.adt.Maybe.nothing; import static com.jnape.palatable.lambda.functions.builtin.fn2.Map.map; -import static com.jnape.palatable.lambda.lens.Iso.simpleIso; -import static com.jnape.palatable.lambda.lens.functions.Over.over; -import static com.jnape.palatable.lambda.lens.functions.Set.set; -import static com.jnape.palatable.lambda.lens.functions.View.view; +import static com.jnape.palatable.lambda.optics.Iso.simpleIso; +import static com.jnape.palatable.lambda.optics.functions.Over.over; +import static com.jnape.palatable.lambda.optics.functions.Set.set; +import static com.jnape.palatable.lambda.optics.functions.View.view; import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; diff --git a/src/test/java/com/jnape/palatable/lambda/lens/lenses/ListLensTest.java b/src/test/java/com/jnape/palatable/lambda/optics/lenses/ListLensTest.java similarity index 79% rename from src/test/java/com/jnape/palatable/lambda/lens/lenses/ListLensTest.java rename to src/test/java/com/jnape/palatable/lambda/optics/lenses/ListLensTest.java index 78949c068..9a283f71c 100644 --- a/src/test/java/com/jnape/palatable/lambda/lens/lenses/ListLensTest.java +++ b/src/test/java/com/jnape/palatable/lambda/optics/lenses/ListLensTest.java @@ -1,16 +1,16 @@ -package com.jnape.palatable.lambda.lens.lenses; +package com.jnape.palatable.lambda.optics.lenses; -import com.jnape.palatable.lambda.lens.Lens; +import com.jnape.palatable.lambda.optics.Lens; import org.junit.Test; import java.util.List; import static com.jnape.palatable.lambda.adt.Maybe.just; import static com.jnape.palatable.lambda.adt.Maybe.nothing; -import static com.jnape.palatable.lambda.lens.functions.Set.set; -import static com.jnape.palatable.lambda.lens.functions.View.view; -import static com.jnape.palatable.lambda.lens.lenses.ListLens.asCopy; -import static com.jnape.palatable.lambda.lens.lenses.ListLens.elementAt; +import static com.jnape.palatable.lambda.optics.functions.Set.set; +import static com.jnape.palatable.lambda.optics.functions.View.view; +import static com.jnape.palatable.lambda.optics.lenses.ListLens.asCopy; +import static com.jnape.palatable.lambda.optics.lenses.ListLens.elementAt; import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; diff --git a/src/test/java/com/jnape/palatable/lambda/lens/lenses/MapLensTest.java b/src/test/java/com/jnape/palatable/lambda/optics/lenses/MapLensTest.java similarity index 94% rename from src/test/java/com/jnape/palatable/lambda/lens/lenses/MapLensTest.java rename to src/test/java/com/jnape/palatable/lambda/optics/lenses/MapLensTest.java index 800dcb876..5a97e5b4a 100644 --- a/src/test/java/com/jnape/palatable/lambda/lens/lenses/MapLensTest.java +++ b/src/test/java/com/jnape/palatable/lambda/optics/lenses/MapLensTest.java @@ -1,6 +1,6 @@ -package com.jnape.palatable.lambda.lens.lenses; +package com.jnape.palatable.lambda.optics.lenses; -import com.jnape.palatable.lambda.lens.Lens; +import com.jnape.palatable.lambda.optics.Lens; import org.junit.Test; import java.util.Collection; @@ -11,11 +11,11 @@ import static com.jnape.palatable.lambda.adt.Maybe.just; import static com.jnape.palatable.lambda.adt.Maybe.nothing; -import static com.jnape.palatable.lambda.lens.Iso.iso; -import static com.jnape.palatable.lambda.lens.functions.Set.set; -import static com.jnape.palatable.lambda.lens.functions.View.view; -import static com.jnape.palatable.lambda.lens.lenses.MapLens.keys; -import static com.jnape.palatable.lambda.lens.lenses.MapLens.mappingValues; +import static com.jnape.palatable.lambda.optics.Iso.iso; +import static com.jnape.palatable.lambda.optics.functions.Set.set; +import static com.jnape.palatable.lambda.optics.functions.View.view; +import static com.jnape.palatable.lambda.optics.lenses.MapLens.keys; +import static com.jnape.palatable.lambda.optics.lenses.MapLens.mappingValues; import static java.util.Arrays.asList; import static java.util.Collections.emptyMap; import static java.util.Collections.emptySet; diff --git a/src/test/java/com/jnape/palatable/lambda/lens/lenses/MaybeLensTest.java b/src/test/java/com/jnape/palatable/lambda/optics/lenses/MaybeLensTest.java similarity index 80% rename from src/test/java/com/jnape/palatable/lambda/lens/lenses/MaybeLensTest.java rename to src/test/java/com/jnape/palatable/lambda/optics/lenses/MaybeLensTest.java index 445aa8a73..4542be84b 100644 --- a/src/test/java/com/jnape/palatable/lambda/lens/lenses/MaybeLensTest.java +++ b/src/test/java/com/jnape/palatable/lambda/optics/lenses/MaybeLensTest.java @@ -1,19 +1,19 @@ -package com.jnape.palatable.lambda.lens.lenses; +package com.jnape.palatable.lambda.optics.lenses; import com.jnape.palatable.lambda.adt.Maybe; -import com.jnape.palatable.lambda.lens.Lens; +import com.jnape.palatable.lambda.optics.Lens; import org.junit.Before; import org.junit.Test; import static com.jnape.palatable.lambda.adt.Maybe.just; import static com.jnape.palatable.lambda.adt.Maybe.nothing; -import static com.jnape.palatable.lambda.lens.Lens.lens; -import static com.jnape.palatable.lambda.lens.functions.Set.set; -import static com.jnape.palatable.lambda.lens.functions.View.view; -import static com.jnape.palatable.lambda.lens.lenses.MaybeLens.liftA; -import static com.jnape.palatable.lambda.lens.lenses.MaybeLens.liftB; -import static com.jnape.palatable.lambda.lens.lenses.MaybeLens.liftS; -import static com.jnape.palatable.lambda.lens.lenses.MaybeLens.liftT; +import static com.jnape.palatable.lambda.optics.Lens.lens; +import static com.jnape.palatable.lambda.optics.functions.Set.set; +import static com.jnape.palatable.lambda.optics.functions.View.view; +import static com.jnape.palatable.lambda.optics.lenses.MaybeLens.liftA; +import static com.jnape.palatable.lambda.optics.lenses.MaybeLens.liftB; +import static com.jnape.palatable.lambda.optics.lenses.MaybeLens.liftS; +import static com.jnape.palatable.lambda.optics.lenses.MaybeLens.liftT; import static java.util.Arrays.asList; import static org.junit.Assert.assertEquals; import static testsupport.assertion.LensAssert.assertLensLawfulness; diff --git a/src/test/java/com/jnape/palatable/lambda/lens/lenses/SetLensTest.java b/src/test/java/com/jnape/palatable/lambda/optics/lenses/SetLensTest.java similarity index 92% rename from src/test/java/com/jnape/palatable/lambda/lens/lenses/SetLensTest.java rename to src/test/java/com/jnape/palatable/lambda/optics/lenses/SetLensTest.java index 9421e50f6..6beff4b53 100644 --- a/src/test/java/com/jnape/palatable/lambda/lens/lenses/SetLensTest.java +++ b/src/test/java/com/jnape/palatable/lambda/optics/lenses/SetLensTest.java @@ -1,11 +1,11 @@ -package com.jnape.palatable.lambda.lens.lenses; +package com.jnape.palatable.lambda.optics.lenses; import org.junit.Test; import java.util.HashSet; import java.util.TreeSet; -import static com.jnape.palatable.lambda.lens.functions.Set.set; +import static com.jnape.palatable.lambda.optics.functions.Set.set; import static java.util.Arrays.asList; import static java.util.Collections.emptySet; import static java.util.Collections.singleton; diff --git a/src/test/java/testsupport/assertion/LensAssert.java b/src/test/java/testsupport/assertion/LensAssert.java index e89678afb..b966e97f2 100644 --- a/src/test/java/testsupport/assertion/LensAssert.java +++ b/src/test/java/testsupport/assertion/LensAssert.java @@ -2,10 +2,13 @@ import com.jnape.palatable.lambda.adt.Maybe; import com.jnape.palatable.lambda.adt.hlist.Tuple2; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functions.Fn2; import com.jnape.palatable.lambda.functions.builtin.fn2.Map; -import com.jnape.palatable.lambda.lens.LensLike; +import com.jnape.palatable.lambda.functor.Functor; +import com.jnape.palatable.lambda.functor.Profunctor; import com.jnape.palatable.lambda.monoid.builtin.Present; +import com.jnape.palatable.lambda.optics.Optic; import java.util.Objects; @@ -15,15 +18,17 @@ import static com.jnape.palatable.lambda.functions.builtin.fn2.CartesianProduct.cartesianProduct; import static com.jnape.palatable.lambda.functions.builtin.fn2.Into.into; import static com.jnape.palatable.lambda.functions.builtin.fn2.ReduceLeft.reduceLeft; -import static com.jnape.palatable.lambda.lens.functions.Set.set; -import static com.jnape.palatable.lambda.lens.functions.View.view; +import static com.jnape.palatable.lambda.optics.functions.Set.set; +import static com.jnape.palatable.lambda.optics.functions.View.view; import static java.lang.String.format; import static java.lang.String.join; import static java.util.Arrays.asList; public final class LensAssert { - public static void assertLensLawfulness(LensLike lens, Iterable ss, Iterable bs) { + public static void assertLensLawfulness(Optic, Functor, S, S, A, A> lens, + Iterable ss, + Iterable bs) { Iterable> cases = cartesianProduct(ss, bs); Present.present((x, y) -> join("\n\n", x, y)) .reduceLeft(asList(falsify("You get back what you put in", (s, b) -> view(lens, set(lens, b, s)), (s, b) -> b, cases), diff --git a/src/test/java/testsupport/matchers/LensMatcher.java b/src/test/java/testsupport/matchers/LensMatcher.java deleted file mode 100644 index c25f1fa86..000000000 --- a/src/test/java/testsupport/matchers/LensMatcher.java +++ /dev/null @@ -1,59 +0,0 @@ -package testsupport.matchers; - -import com.jnape.palatable.lambda.adt.hlist.Tuple2; -import com.jnape.palatable.lambda.lens.Lens; -import org.hamcrest.BaseMatcher; -import org.hamcrest.Description; - -import java.util.HashSet; - -import static com.jnape.palatable.lambda.functions.builtin.fn1.Empty.empty; -import static com.jnape.palatable.lambda.functions.builtin.fn2.All.all; -import static com.jnape.palatable.lambda.functions.builtin.fn2.CartesianProduct.cartesianProduct; -import static com.jnape.palatable.lambda.functions.builtin.fn2.Filter.filter; -import static com.jnape.palatable.lambda.functions.builtin.fn2.Into.into; -import static com.jnape.palatable.lambda.functions.builtin.fn2.ToCollection.toCollection; -import static com.jnape.palatable.lambda.lens.functions.Set.set; -import static com.jnape.palatable.lambda.lens.functions.View.view; - -public class LensMatcher extends BaseMatcher> { - - private final Iterable> combinations; - - private LensMatcher(Iterable> combinations) { - this.combinations = combinations; - } - - @Override - @SuppressWarnings("unchecked") - public boolean matches(Object other) { - if (!(other instanceof Lens)) - return false; - - Lens lens = (Lens) other; - return youGetBackWhatYouPutIn(lens) - && puttingBackWhatYouGotChangesNothing(lens) - && settingTwiceIsEquivalentToSettingOnce(lens); - } - - @Override - public void describeTo(Description description) { - throw new UnsupportedOperationException(); - } - - private boolean youGetBackWhatYouPutIn(Lens lens) { - return all(into((s, b) -> view(lens, set(lens, b, s)).equals(b)), combinations); - } - - private boolean puttingBackWhatYouGotChangesNothing(Lens lens) { - return all(into((s, b) -> set(lens, view(lens, s), s).equals(s)), combinations); - } - - private boolean settingTwiceIsEquivalentToSettingOnce(Lens lens) { - return all(into((s, b) -> set(lens, b, set(lens, b, s)).equals(set(lens, b, s))), combinations); - } - - public static LensMatcher isLawfulForAllSAndB(Iterable ss, Iterable bs) { - return new LensMatcher<>(cartesianProduct(ss, bs)); - } -} From 5a734c52aaf3f1876f57c503de70ba3c29b83266 Mon Sep 17 00:00:00 2001 From: jnape Date: Sun, 21 Apr 2019 23:14:55 -0500 Subject: [PATCH 25/69] Adding Optic#Simple, updating optic documentation --- .../jnape/palatable/lambda/optics/Iso.java | 10 ++-- .../jnape/palatable/lambda/optics/Lens.java | 2 + .../jnape/palatable/lambda/optics/Optic.java | 54 +++++++++++++++++-- .../lambda/optics/functions/Over.java | 9 ++-- .../lambda/optics/functions/Set.java | 8 +-- .../lambda/optics/functions/View.java | 7 +-- .../palatable/lambda/optics/OpticTest.java | 44 +++++++++++++++ 7 files changed, 115 insertions(+), 19 deletions(-) create mode 100644 src/test/java/com/jnape/palatable/lambda/optics/OpticTest.java diff --git a/src/main/java/com/jnape/palatable/lambda/optics/Iso.java b/src/main/java/com/jnape/palatable/lambda/optics/Iso.java index e84ecb048..236c46d07 100644 --- a/src/main/java/com/jnape/palatable/lambda/optics/Iso.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/Iso.java @@ -26,7 +26,7 @@ /** * An {@link Iso} (short for "isomorphism") is an invertible {@link Lens}: an {@link Optic} encoding of a * bi-directional focusing of two types, and like {@link Lens}es, can be {@link View}ed, - * {@link Set}, and {@link Over}ed. + * {@link Set}, and {@link Over updated}. *

* As an example, consider the isomorphism between valid {@link String}s and {@link Integer}s: *

@@ -36,9 +36,9 @@
  * String asString = view(stringIntIso.mirror(), 123); // "123"
  * }
  * 
- * In the previous example, stringIntIso can be viewed as a {@link Lens}<String, String, Integer, - * Integer>, and can be {@link Iso#mirror}ed and viewed as a {@link Lens}<Integer, - * Integer, String, String>. + * In the previous example, stringIntIso can be viewed as an + * {@link Optic}<String, String, Integer, Integer>, and can be {@link Iso#mirror}ed and + * viewed as a {@link Optic}<Integer, Integer, String, String>. *

* As with {@link Lens}, variance is supported between S/T and A/B, and where these pairs do * not vary, a {@link Simple} iso can be used (for instance, in the previous example, stringIntIso could @@ -50,6 +50,8 @@ * @param the larger type for mirrored focusing * @param the smaller type for focusing * @param the smaller type for mirrored focusing + * @see Optic + * @see Lens */ @FunctionalInterface public interface Iso extends diff --git a/src/main/java/com/jnape/palatable/lambda/optics/Lens.java b/src/main/java/com/jnape/palatable/lambda/optics/Lens.java index c39feabd3..4e2583e03 100644 --- a/src/main/java/com/jnape/palatable/lambda/optics/Lens.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/Lens.java @@ -135,6 +135,8 @@ * @param the type of the "larger" value for putting * @param the type of the "smaller" value that is read * @param the type of the "smaller" update value + * @see Optic + * @see Iso */ @FunctionalInterface public interface Lens extends diff --git a/src/main/java/com/jnape/palatable/lambda/optics/Optic.java b/src/main/java/com/jnape/palatable/lambda/optics/Optic.java index c53e200e5..055abf276 100644 --- a/src/main/java/com/jnape/palatable/lambda/optics/Optic.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/Optic.java @@ -15,8 +15,8 @@ * (P<A, F<B>> -> P<S, F<T>>) (existentially-quantified allowing for * covariance). * - * @param

the {@link Profunctor} type - * @param the {@link Functor} type + * @param

the {@link Profunctor} bound + * @param the {@link Functor} bound * @param the left side of the output profunctor * @param the right side's functor embedding of the output profunctor * @param the left side of the input profunctor @@ -156,8 +156,8 @@ default Optic mapB(Function fn) { * Promote a monomorphic function to a compatible {@link Optic}. * * @param fn the function - * @param

the {@link Profunctor} type - * @param the {@link Functor} type + * @param

the {@link Profunctor} bound + * @param the {@link Functor} bound * @param the left side of the output profunctor * @param the right side's functor embedding of the output profunctor * @param the left side of the input profunctor @@ -189,6 +189,28 @@ default Optic mapB(Function fn) { }; } + /** + * Reframe an {@link Optic} according to covariant bounds. + * + * @param optic the {@link Optic} + * @param

the {@link Profunctor} type + * @param the {@link Functor} type + * @param the left side of the output profunctor + * @param the right side's functor embedding of the output profunctor + * @param the left side of the input profunctor + * @param the right side's functor embedding of the input profunctor + * @return the covariantly reframed {@link Optic} + */ + static

, + F extends Functor, + S, T, A, B> Optic reframe(Optic optic) { + return Optic.optic(optic., + Functor, + Profunctor, ? extends P>, + Profunctor, ? extends P>>monomorphize()); + } + interface Simple

, F extends Functor, S, A> extends Optic { @@ -233,5 +255,29 @@ PSFT apply(PAFB pafb) { } }; } + + /** + * Adapt an {@link Optic} with S/T and A/B unified into a {@link Simple simple optic}. + * + * @param optic the {@link Optic} + * @param

the {@link Profunctor} bound + * @param the {@link Functor} bound + * @param the left side and the right side's functor embedding of the output profunctor + * @param the left side and the right side's functor embedding of the input profunctor + * @return the {@link Simple} optic + */ + static

, + F extends Functor, + S, A> Simple adapt(Optic optic) { + return new Simple() { + @Override + public , CoF extends Functor, + FB extends Functor, FT extends Functor, + PAFB extends Profunctor, + PSFT extends Profunctor> PSFT apply(PAFB pafb) { + return optic.apply(pafb); + } + }; + } } } diff --git a/src/main/java/com/jnape/palatable/lambda/optics/functions/Over.java b/src/main/java/com/jnape/palatable/lambda/optics/functions/Over.java index de8b4a541..cf73de8ad 100644 --- a/src/main/java/com/jnape/palatable/lambda/optics/functions/Over.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/functions/Over.java @@ -9,9 +9,9 @@ import java.util.function.Function; /** - * Given a lens, a function from A to B, and a "larger" value S, produce a - * T by retrieving the A from the S, applying the function, and updating the - * S with the B resulting from the function. + * Given an {@link Optic}, a function from A to B, and a "larger" value S, + * produce a T by retrieving the A from the S, applying the function, and + * updating the S with the B resulting from the function. *

* This function is similar to {@link Set}, except that it allows the setting value B to be derived from * S via function application, rather than provided. @@ -23,7 +23,8 @@ * @see Set * @see View */ -public final class Over implements Fn3, ? super Identity, S, T, A, B>, Function, S, T> { +public final class Over implements + Fn3, ? super Identity, S, T, A, B>, Function, S, T> { private static final Over INSTANCE = new Over<>(); diff --git a/src/main/java/com/jnape/palatable/lambda/optics/functions/Set.java b/src/main/java/com/jnape/palatable/lambda/optics/functions/Set.java index c5c7a7110..d6cc30481 100644 --- a/src/main/java/com/jnape/palatable/lambda/optics/functions/Set.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/functions/Set.java @@ -10,11 +10,11 @@ import static com.jnape.palatable.lambda.optics.functions.Over.over; /** - * Given a lens, a "smaller" value B, and a "larger" value S, produce a T by - * lifting the lens into {@link Identity}. + * Given an {@link Optic}, a "smaller" value B, and a "larger" value S, produce a + * T by lifting the {@link Optic} into the {@link Identity} functor. *

- * More idiomatically, this function can be used to treat a lens as a "setter" of Bs on Ss, - * potentially producing a different "larger" value, T. + * More idiomatically, this function can be used to treat an {@link Optic} as a "setter" of + * < code>Bs on Ss, potentially producing a different "larger" value, T. * * @param the type of the larger value * @param the type of the larger updated value diff --git a/src/main/java/com/jnape/palatable/lambda/optics/functions/View.java b/src/main/java/com/jnape/palatable/lambda/optics/functions/View.java index b94992d29..1a80c025e 100644 --- a/src/main/java/com/jnape/palatable/lambda/optics/functions/View.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/functions/View.java @@ -6,10 +6,11 @@ import com.jnape.palatable.lambda.optics.Optic; /** - * Given a lens and a "larger" value S, retrieve a "smaller" value A by lifting the lens into - * {@link Const}. + * Given an {@link Optic} and a "larger" value S, retrieve a "smaller" value A by lifting the + * {@link Optic} into the {@link Const} functor. *

- * More idiomatically, this function can be used to treat a lens as a "getter" of As from Ss. + * More idiomatically, this function can be used to treat a {@link Optic} as a "getter" of As from + * Ss. * * @param the type of the larger value * @param the type of the larger updated value (unused, but necessary for composition) diff --git a/src/test/java/com/jnape/palatable/lambda/optics/OpticTest.java b/src/test/java/com/jnape/palatable/lambda/optics/OpticTest.java new file mode 100644 index 000000000..00a550185 --- /dev/null +++ b/src/test/java/com/jnape/palatable/lambda/optics/OpticTest.java @@ -0,0 +1,44 @@ +package com.jnape.palatable.lambda.optics; + +import com.jnape.palatable.lambda.functions.Fn1; +import com.jnape.palatable.lambda.functor.Functor; +import com.jnape.palatable.lambda.functor.Profunctor; +import com.jnape.palatable.lambda.functor.builtin.Identity; +import com.jnape.palatable.lambda.functor.builtin.Tagged; +import org.junit.Test; + +import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; +import static com.jnape.palatable.lambda.optics.Optic.optic; +import static org.junit.Assert.assertEquals; + +public class OpticTest { + + @Test + public void monomorphize() { + Optic, Identity, String, String, String, String> optic = optic(pafb -> pafb); + Fn1>, Tagged>> monomorphize = optic.monomorphize(); + assertEquals(new Identity<>("foo"), monomorphize.apply(new Tagged<>(new Identity<>("foo"))).unTagged()); + } + + @Test + public void reframe() { + Optic, Functor, String, String, String, String> optic = optic(pafb -> pafb); + Optic, Identity, String, String, String, String> reframed = Optic.reframe(optic); + assertEquals(new Identity<>("foo"), + reframed., Identity, Identity, Identity, + Fn1>, + Fn1>>apply(constantly(new Identity<>("foo"))).apply("bar")); + } + + @Test + public void adapt() { + Optic, Functor, String, String, String, String> optic = optic(pafb -> pafb); + Optic.Simple, Functor, String, String> simple = Optic.Simple.adapt(optic); + + assertEquals("foo", + simple., Identity, Identity, Identity, + Fn1>, + Fn1>>apply(constantly(new Identity<>("foo"))) + .apply("bar").runIdentity()); + } +} \ No newline at end of file From 739f8d7831387d6b2efda80da8c56378b35dd8ab Mon Sep 17 00:00:00 2001 From: jnape Date: Sat, 4 May 2019 15:17:48 -0500 Subject: [PATCH 26/69] Improving Exchange docs --- .../lambda/functor/builtin/Exchange.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Exchange.java b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Exchange.java index d997eaf5d..8d7cc82ea 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Exchange.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Exchange.java @@ -1,6 +1,7 @@ package com.jnape.palatable.lambda.functor.builtin; import com.jnape.palatable.lambda.functor.Profunctor; +import com.jnape.palatable.lambda.optics.Iso; import java.util.function.Function; @@ -21,30 +22,52 @@ public Exchange(Function sa, FunctionS -> A. + * + * @return a {@link Function}<S, A> + */ public Function sa() { return sa; } + /** + * Extract the mapping B -> T. + * + * @return a {@link Function}<B, T> + */ public Function bt() { return bt; } + /** + * {@inheritDoc} + */ @Override public Exchange diMap(Function lFn, Function rFn) { return new Exchange<>(lFn.andThen(sa), bt.andThen(rFn)); } + /** + * {@inheritDoc} + */ @Override public Exchange diMapL(Function fn) { return (Exchange) Profunctor.super.diMapL(fn); } + /** + * {@inheritDoc} + */ @Override public Exchange diMapR(Function fn) { return (Exchange) Profunctor.super.diMapR(fn); } + /** + * {@inheritDoc} + */ @Override public Exchange contraMap(Function fn) { return (Exchange) Profunctor.super.contraMap(fn); From 3b110037435d0ae276f91633cde35233bdf63c9e Mon Sep 17 00:00:00 2001 From: jnape Date: Sat, 4 May 2019 15:23:10 -0500 Subject: [PATCH 27/69] Adjusting variance on Optic.Simple#adapt to be more permissive --- src/main/java/com/jnape/palatable/lambda/optics/Optic.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/jnape/palatable/lambda/optics/Optic.java b/src/main/java/com/jnape/palatable/lambda/optics/Optic.java index 055abf276..e524d06a9 100644 --- a/src/main/java/com/jnape/palatable/lambda/optics/Optic.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/Optic.java @@ -268,7 +268,7 @@ PSFT apply(PAFB pafb) { */ static

, F extends Functor, - S, A> Simple adapt(Optic optic) { + S, A> Simple adapt(Optic optic) { return new Simple() { @Override public , CoF extends Functor, From 38fe3f702fd53cc64b66dda7324953102db9f0c5 Mon Sep 17 00:00:00 2001 From: jnape Date: Sat, 4 May 2019 15:23:39 -0500 Subject: [PATCH 28/69] Effect#effect allows function input to be contravariant --- .../java/com/jnape/palatable/lambda/functions/Effect.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Effect.java b/src/main/java/com/jnape/palatable/lambda/functions/Effect.java index c08a44b01..0074cdd42 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Effect.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Effect.java @@ -7,8 +7,8 @@ import java.util.function.Consumer; import java.util.function.Function; -import static com.jnape.palatable.lambda.io.IO.io; import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; +import static com.jnape.palatable.lambda.io.IO.io; /** * A function returning "no result", and therefore only useful as a side-effect. @@ -78,7 +78,7 @@ static Effect effect(Runnable runnable) { * @param the effect argument type * @return the effect */ - static Effect effect(Fn1> fn) { + static Effect effect(Fn1> fn) { return a -> fn.apply(a).unsafePerformIO(); } } \ No newline at end of file From 9c969a53db985f143f0fc27fa9409d1cb30e9592 Mon Sep 17 00:00:00 2001 From: jnape Date: Sat, 4 May 2019 15:25:25 -0500 Subject: [PATCH 29/69] Eliminating warning in Iso in older javac --- .../jnape/palatable/lambda/optics/Iso.java | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/jnape/palatable/lambda/optics/Iso.java b/src/main/java/com/jnape/palatable/lambda/optics/Iso.java index 236c46d07..ff04ffb26 100644 --- a/src/main/java/com/jnape/palatable/lambda/optics/Iso.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/Iso.java @@ -44,7 +44,8 @@ * not vary, a {@link Simple} iso can be used (for instance, in the previous example, stringIntIso could * have had the simplified Iso.Simple<String, Integer> type). *

- * For more information, read about isos. + * For more information, read about + * isos. * * @param the larger type for focusing * @param the larger type for mirrored focusing @@ -119,10 +120,12 @@ default Iso discardR(Applicative> appB) { @Override default Iso flatMap(Function>> fn) { - return unIso().fmap(bt -> Fn2.fn2(fn1(bt.andThen(fn.>andThen(Applicative::coerce)) - .andThen(Iso::unIso) - .andThen(Tuple2::_2) - .andThen(Fn1::fn1)))) + //noinspection RedundantTypeArguments + return unIso().fmap(bt -> Fn2.fn2( + fn1(bt.andThen(fn.>andThen(Monad>::coerce)) + .andThen(Iso::unIso) + .andThen(Tuple2::_2) + .andThen(Fn1::fn1)))) .fmap(Fn2::uncurry) .fmap(bbu -> bbu.diMapL(Tuple2::fill)) .into(Iso::iso); @@ -199,8 +202,10 @@ static Iso iso( Optic, ? super Functor, S, T, A, B> optic) { return new Iso() { @Override - public >, CoF extends Functor>, FB extends Functor, FT extends Functor, PAFB extends Profunctor, PSFT extends Profunctor> PSFT apply( - PAFB pafb) { + public >, + CoF extends Functor>, FB extends Functor, + FT extends Functor, PAFB extends Profunctor, + PSFT extends Profunctor> PSFT apply(PAFB pafb) { return optic.apply(pafb); } }; @@ -250,12 +255,12 @@ default Iso.Simple compose(Iso.Simple g) { */ @SuppressWarnings("overloads") default Iso.Simple andThen(Iso.Simple f) { - return adapt(f.compose(this)); + return Iso.Simple.adapt(f.compose(this)); } @Override default Iso.Simple mirror() { - return adapt(Iso.super.mirror()); + return Iso.Simple.adapt(Iso.super.mirror()); } @Override @@ -265,17 +270,17 @@ default Lens.Simple toLens() { @Override default Iso.Simple discardR(Applicative> appB) { - return adapt(Iso.super.discardR(appB)); + return Iso.Simple.adapt(Iso.super.discardR(appB)); } @Override default Iso.Simple andThen(Optic.Simple, ? super Functor, A, B> f) { - return adapt(Iso.super.andThen(f)); + return Iso.Simple.adapt(Iso.super.andThen(f)); } @Override default Iso.Simple compose(Optic.Simple, ? super Functor, R, S> g) { - return adapt(Iso.super.compose(g)); + return Iso.Simple.adapt(Iso.super.compose(g)); } /** @@ -290,8 +295,10 @@ static Iso.Simple adapt( Optic, ? super Functor, S, S, A, A> optic) { return new Iso.Simple() { @Override - public >, CoF extends Functor>, FB extends Functor, FT extends Functor, PAFB extends Profunctor, PSFT extends Profunctor> PSFT apply( - PAFB pafb) { + public >, + CoF extends Functor>, FB extends Functor, + FT extends Functor, PAFB extends Profunctor, + PSFT extends Profunctor> PSFT apply(PAFB pafb) { return optic.apply(pafb); } }; From 39b772c2566eb7ae0b0e8a9f01931e66e9cda616 Mon Sep 17 00:00:00 2001 From: jnape Date: Sat, 4 May 2019 18:11:47 -0500 Subject: [PATCH 30/69] Prisms arrive; fixing javadocs --- .../jnape/palatable/lambda/adt/Either.java | 1 - .../palatable/lambda/adt/choice/Choice2.java | 2 - .../palatable/lambda/adt/choice/Choice3.java | 2 - .../palatable/lambda/adt/choice/Choice4.java | 2 - .../palatable/lambda/adt/choice/Choice5.java | 1 - .../palatable/lambda/adt/choice/Choice6.java | 2 - .../palatable/lambda/adt/choice/Choice7.java | 2 - .../palatable/lambda/adt/choice/Choice8.java | 2 - .../jnape/palatable/lambda/functions/Fn1.java | 2 - .../lambda/functions/builtin/fn2/LazyRec.java | 12 +- .../functions/builtin/fn3/FoldRight.java | 10 +- .../lambda/functions/specialized/Pure.java | 14 ++ .../palatable/lambda/functor/Cocartesian.java | 3 +- .../lambda/functor/builtin/Compose.java | 2 - .../lambda/functor/builtin/Const.java | 2 - .../lambda/functor/builtin/Identity.java | 2 - .../lambda/functor/builtin/Market.java | 90 ++++++++ .../lambda/functor/builtin/Tagged.java | 78 +++++++ .../com/jnape/palatable/lambda/io/IO.java | 2 - .../jnape/palatable/lambda/optics/Iso.java | 73 ++++++ .../jnape/palatable/lambda/optics/Lens.java | 70 +++++- .../jnape/palatable/lambda/optics/Optic.java | 19 +- .../jnape/palatable/lambda/optics/Prism.java | 217 ++++++++++++++++++ .../palatable/lambda/optics/ProtoOptic.java | 28 +++ .../lambda/optics/functions/Matching.java | 46 ++++ .../lambda/optics/functions/Pre.java | 60 +++++ .../palatable/lambda/optics/functions/Re.java | 48 ++++ .../lambda/optics/functions/Set.java | 2 +- .../lambda/traversable/LambdaIterable.java | 2 - .../lambda/functor/builtin/MarketTest.java | 29 +++ .../palatable/lambda/optics/PrismTest.java | 51 ++++ .../lambda/optics/functions/PreTest.java | 30 +++ .../lambda/optics/functions/ReTest.java | 27 +++ 33 files changed, 889 insertions(+), 44 deletions(-) create mode 100644 src/main/java/com/jnape/palatable/lambda/functions/specialized/Pure.java create mode 100644 src/main/java/com/jnape/palatable/lambda/functor/builtin/Market.java create mode 100644 src/main/java/com/jnape/palatable/lambda/functor/builtin/Tagged.java create mode 100644 src/main/java/com/jnape/palatable/lambda/optics/Prism.java create mode 100644 src/main/java/com/jnape/palatable/lambda/optics/ProtoOptic.java create mode 100644 src/main/java/com/jnape/palatable/lambda/optics/functions/Matching.java create mode 100644 src/main/java/com/jnape/palatable/lambda/optics/functions/Pre.java create mode 100644 src/main/java/com/jnape/palatable/lambda/optics/functions/Re.java create mode 100644 src/test/java/com/jnape/palatable/lambda/functor/builtin/MarketTest.java create mode 100644 src/test/java/com/jnape/palatable/lambda/optics/PrismTest.java create mode 100644 src/test/java/com/jnape/palatable/lambda/optics/functions/PreTest.java create mode 100644 src/test/java/com/jnape/palatable/lambda/optics/functions/ReTest.java diff --git a/src/main/java/com/jnape/palatable/lambda/adt/Either.java b/src/main/java/com/jnape/palatable/lambda/adt/Either.java index 85b538c47..242d800e9 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/Either.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/Either.java @@ -256,7 +256,6 @@ public final Either zip(Applicative Lazy> lazyZip( diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice2.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice2.java index e16315de9..d056ae87c 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice2.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice2.java @@ -115,8 +115,6 @@ public Choice2 zip(Applicative, Choic /** * {@inheritDoc} - * - * @param lazyAppFn */ @Override public Lazy>> lazyZip( diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice3.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice3.java index 953a0ca58..0ba9eddc4 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice3.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice3.java @@ -115,8 +115,6 @@ public Choice3 zip(Applicative, Ch /** * {@inheritDoc} - * - * @param lazyAppFn */ @Override public Lazy> lazyZip( diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice4.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice4.java index 8a2efdec7..f24a04042 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice4.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice4.java @@ -116,8 +116,6 @@ public Choice4 zip(Applicative, /** * {@inheritDoc} - * - * @param lazyAppFn */ @Override public Lazy> lazyZip( diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice5.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice5.java index fb4a609f3..4008fde0b 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice5.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice5.java @@ -120,7 +120,6 @@ public Choice5 zip(Applicative Lazy> lazyZip( diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice6.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice6.java index c3696b1a4..0f09db9fa 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice6.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice6.java @@ -123,8 +123,6 @@ public Choice6 zip( /** * {@inheritDoc} - * - * @param lazyAppFn */ @Override public Lazy> lazyZip( diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice7.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice7.java index 4f6c2708c..6965a2d37 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice7.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice7.java @@ -126,8 +126,6 @@ public Choice7 zip( /** * {@inheritDoc} - * - * @param lazyAppFn */ @Override public Lazy> lazyZip( diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice8.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice8.java index 28d47e689..a55590886 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice8.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice8.java @@ -119,8 +119,6 @@ public Choice8 zip( /** * {@inheritDoc} - * - * @param lazyAppFn */ @Override public Lazy> lazyZip( diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java index 680dc55eb..566ac93db 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java @@ -104,8 +104,6 @@ default Fn1 zip(Fn2 appFn) { /** * {@inheritDoc} - * - * @param lazyAppFn */ @Override default Lazy> lazyZip( diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LazyRec.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LazyRec.java index 1e1ffbc8f..7b154b0ae 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LazyRec.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LazyRec.java @@ -17,13 +17,13 @@ *

* Example: *

- * 
- * Lazy lazyFactorial = lazyRec((fact, x) -> x.equals(ONE)
- *                                                               ? lazy(x)
- *                                                               : fact.apply(x.subtract(ONE)).fmap(y -> y.multiply(x)),
+ * {@code
+ * Lazy lazyFactorial = lazyRec((fact, x) -> x.equals(ONE)
+ *                                                       ? lazy(x)
+ *                                                       : fact.apply(x.subtract(ONE)).fmap(y -> y.multiply(x)),
  *                                                  BigInteger.valueOf(50_000));
- * BigInteger value = lazyFactorial.value(); // 3.34732050959714483691547609407148647791277322381045 × 10^213236
- * 
+ * BigInteger value = lazyFactorial.value(); // 3.34732050959714483691547609407148647791277322381045 x 10^213236
+ * }
  * 
* * @param the input type diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/FoldRight.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/FoldRight.java index a31648e68..8741aadba 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/FoldRight.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/FoldRight.java @@ -20,15 +20,15 @@ *

* Example: *

- * 
+ * {@code
  * Lazy> lazyCopy = foldRight(
- *     (head, lazyTail) -> lazy(cons(head, () -> lazyTail.value().iterator())),
+ *     (head, lazyTail) -> lazy(cons(head, () -> lazyTail.value().iterator())),
  *     lazy(emptyList()),
- *     iterate(x -> x + 1, 0));
- * Iterable copy = () -> lazyCopy.value().iterator();
+ *     iterate(x -> x + 1, 0));
+ * Iterable copy = () -> lazyCopy.value().iterator();
  * take(3, copy).forEach(System.out::println); // prints "1, 2, 3"
  * take(3, copy).forEach(System.out::println); // prints "1, 2, 3"
- * 
+ * }
  * 
*

* For more information, read about the {@link Functor} to lift into + */ +public interface Pure> { + + Functor apply(A a); +} diff --git a/src/main/java/com/jnape/palatable/lambda/functor/Cocartesian.java b/src/main/java/com/jnape/palatable/lambda/functor/Cocartesian.java index 8d76e9c45..41bea7f1c 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/Cocartesian.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/Cocartesian.java @@ -26,7 +26,8 @@ public interface Cocartesian> extends Profu /** * Choose between the covariantly-positioned carrier type and the contravariantly-positioned carrier type. This can - * be used to encode partial functions a -> (⊥ v b) as total functions a -> (a v b). + * be used to encode partial functions a -> (_|_ v b) as total functions + * a -> (a v b). * * @return the profunctor with a choice */ diff --git a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Compose.java b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Compose.java index b7dcbe209..912ca8109 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Compose.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Compose.java @@ -56,8 +56,6 @@ public Compose zip(Applicative, Co /** * {@inheritDoc} - * - * @param lazyAppFn */ @Override public Lazy> lazyZip( diff --git a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Const.java b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Const.java index 220c41598..e857013a8 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Const.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Const.java @@ -66,8 +66,6 @@ public Const zip(Applicative, Const Lazy> lazyZip( diff --git a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Identity.java b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Identity.java index 6ade25ffa..e17ae005f 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Identity.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Identity.java @@ -63,8 +63,6 @@ public Identity zip(Applicative, Identit /** * {@inheritDoc} - * - * @param lazyAppFn */ @Override public Lazy> lazyZip( diff --git a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Market.java b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Market.java new file mode 100644 index 000000000..6929ac661 --- /dev/null +++ b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Market.java @@ -0,0 +1,90 @@ +package com.jnape.palatable.lambda.functor.builtin; + +import com.jnape.palatable.lambda.adt.Either; +import com.jnape.palatable.lambda.adt.choice.Choice2; +import com.jnape.palatable.lambda.functions.Fn1; +import com.jnape.palatable.lambda.functor.Applicative; +import com.jnape.palatable.lambda.functor.Cocartesian; +import com.jnape.palatable.lambda.monad.Monad; + +import java.util.function.Function; + +import static com.jnape.palatable.lambda.adt.Either.left; +import static com.jnape.palatable.lambda.adt.choice.Choice2.a; +import static com.jnape.palatable.lambda.adt.choice.Choice2.b; +import static com.jnape.palatable.lambda.functions.Fn1.fn1; +import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; + +public final class Market implements + Monad>, + Cocartesian> { + + private final Fn1 bt; + private final Fn1> sta; + + public Market(Function bt, Function> sta) { + this.bt = fn1(bt); + this.sta = fn1(sta); + } + + @Override + public Market pure(U u) { + return new Market<>(constantly(u), constantly(left(u))); + } + + @Override + public Market flatMap(Function>> f) { + return new Market<>(b -> f.apply(bt().apply(b)).>coerce().bt().apply(b), + s -> sta().apply(s).invert() + .flatMap(t -> f.apply(t).>coerce().sta() + .apply(s).invert()).invert()); + } + + @Override + public Market zip(Applicative, Market> appFn) { + Market> marketF = appFn.coerce(); + return new Market<>(b -> marketF.bt().apply(b).apply(bt().apply(b)), + s -> sta().apply(s).invert().zip(marketF.sta().apply(s).invert()).invert()); + } + + public Fn1 bt() { + return bt; + } + + public Fn1> sta() { + return sta; + } + + @Override + public Market fmap(Function fn) { + return diMapR(fn); + } + + @Override + public Market, Choice2> cocartesian() { + return new Market<>(bt.fmap(Choice2::b), + cs -> cs.fmap(sta).match(c -> left(a(c)), + tOrA -> tOrA.match(t -> left(b(t)), Either::right))); + } + + @Override + public Market diMap(Function lFn, + Function rFn) { + return new Market<>(bt.fmap(rFn), sta.diMapL(lFn).diMapR(c -> c.biMapL(rFn))); + } + + @Override + public Market diMapL(Function fn) { + return (Market) Cocartesian.super.diMapL(fn); + } + + @Override + public Market diMapR(Function fn) { + return (Market) Cocartesian.super.diMapR(fn); + } + + @Override + public Market contraMap(Function fn) { + return (Market) Cocartesian.super.contraMap(fn); + } +} diff --git a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Tagged.java b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Tagged.java new file mode 100644 index 000000000..cebe4973b --- /dev/null +++ b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Tagged.java @@ -0,0 +1,78 @@ +package com.jnape.palatable.lambda.functor.builtin; + +import com.jnape.palatable.lambda.adt.choice.Choice2; +import com.jnape.palatable.lambda.functor.Applicative; +import com.jnape.palatable.lambda.functor.Cocartesian; +import com.jnape.palatable.lambda.monad.Monad; + +import java.util.function.Function; + +import static com.jnape.palatable.lambda.adt.choice.Choice2.b; + +public final class Tagged implements Monad>, Cocartesian> { + private final B b; + + public Tagged(B b) { + this.b = b; + } + + public B unTagged() { + return b; + } + + @Override + public Tagged flatMap(Function>> f) { + return f.apply(b).coerce(); + } + + @Override + public Tagged pure(C c) { + return new Tagged<>(c); + } + + @Override + public Tagged fmap(Function fn) { + return Monad.super.fmap(fn).coerce(); + } + + @Override + public Tagged zip(Applicative, Tagged> appFn) { + return Monad.super.zip(appFn).coerce(); + } + + @Override + public Tagged discardL(Applicative> appB) { + return Monad.super.discardL(appB).coerce(); + } + + @Override + public Tagged discardR(Applicative> appB) { + return Monad.super.discardR(appB).coerce(); + } + + @Override + public Tagged, Choice2> cocartesian() { + return new Tagged<>(b(b)); + } + + @Override + public Tagged diMap(Function lFn, + Function rFn) { + return new Tagged<>(rFn.apply(b)); + } + + @Override + public Tagged diMapL(Function fn) { + return (Tagged) Cocartesian.super.diMapL(fn); + } + + @Override + public Tagged diMapR(Function fn) { + return (Tagged) Cocartesian.super.diMapR(fn); + } + + @Override + public Tagged contraMap(Function fn) { + return (Tagged) Cocartesian.super.contraMap(fn); + } +} diff --git a/src/main/java/com/jnape/palatable/lambda/io/IO.java b/src/main/java/com/jnape/palatable/lambda/io/IO.java index a9d735bc0..29c2e148b 100644 --- a/src/main/java/com/jnape/palatable/lambda/io/IO.java +++ b/src/main/java/com/jnape/palatable/lambda/io/IO.java @@ -122,8 +122,6 @@ public final IO zip(Applicative, IO> /** * {@inheritDoc} - * - * @param lazyAppFn */ @Override public Lazy> lazyZip(Lazy, IO>> lazyAppFn) { diff --git a/src/main/java/com/jnape/palatable/lambda/optics/Iso.java b/src/main/java/com/jnape/palatable/lambda/optics/Iso.java index ff04ffb26..bcb0775d5 100644 --- a/src/main/java/com/jnape/palatable/lambda/optics/Iso.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/Iso.java @@ -93,31 +93,49 @@ default Iso mirror() { .biMap(e -> fn1(e.sa()), e -> fn1(e.bt())); } + /** + * {@inheritDoc} + */ @Override default Iso fmap(Function fn) { return Monad.super.fmap(fn).coerce(); } + /** + * {@inheritDoc} + */ @Override default Iso pure(U u) { return iso(view(this), constantly(u)); } + /** + * {@inheritDoc} + */ @Override default Iso zip(Applicative, Iso> appFn) { return Monad.super.zip(appFn).coerce(); } + /** + * {@inheritDoc} + */ @Override default Iso discardL(Applicative> appB) { return Monad.super.discardL(appB).coerce(); } + /** + * {@inheritDoc} + */ @Override default Iso discardR(Applicative> appB) { return Monad.super.discardR(appB).coerce(); } + /** + * {@inheritDoc} + */ @Override default Iso flatMap(Function>> fn) { //noinspection RedundantTypeArguments @@ -131,52 +149,82 @@ default Iso flatMap(Function Iso diMapL(Function fn) { return (Iso) Profunctor.super.diMapL(fn); } + /** + * {@inheritDoc} + */ @Override default Iso diMapR(Function fn) { return (Iso) Profunctor.super.diMapR(fn); } + /** + * {@inheritDoc} + */ @Override default Iso diMap(Function lFn, Function rFn) { return this.mapS(lFn).mapT(rFn); } + /** + * {@inheritDoc} + */ @Override default Iso contraMap(Function fn) { return (Iso) Profunctor.super.contraMap(fn); } + /** + * {@inheritDoc} + */ @Override default Iso mapS(Function fn) { return iso(Optic.super.mapS(fn)); } + /** + * {@inheritDoc} + */ @Override default Iso mapT(Function fn) { return iso(Optic.super.mapT(fn)); } + /** + * {@inheritDoc} + */ @Override default Iso mapA(Function fn) { return iso(Optic.super.mapA(fn)); } + /** + * {@inheritDoc} + */ @Override default Iso mapB(Function fn) { return iso(Optic.super.mapB(fn)); } + /** + * {@inheritDoc} + */ @Override default Iso andThen(Optic, ? super Functor, A, B, Z, C> f) { return iso(Optic.super.andThen(f)); } + /** + * {@inheritDoc} + */ @Override default Iso compose(Optic, ? super Functor, R, U, S, T> g) { return iso(Optic.super.compose(g)); @@ -198,6 +246,16 @@ static Iso iso(Function f, return iso(optic(pafb -> pafb.diMap(f, fb -> fb.fmap(g)))); } + /** + * Promote an optic with compatible bounds to an {@link Iso}. + * + * @param optic the {@link Optic} + * @param the larger type for focusing + * @param the larger type for mirrored focusing + * @param the smaller type for focusing + * @param the smaller type for mirrored focusing + * @return the {@link Iso} + */ static Iso iso( Optic, ? super Functor, S, T, A, B> optic) { return new Iso() { @@ -258,26 +316,41 @@ default Iso.Simple andThen(Iso.Simple f) { return Iso.Simple.adapt(f.compose(this)); } + /** + * {@inheritDoc} + */ @Override default Iso.Simple mirror() { return Iso.Simple.adapt(Iso.super.mirror()); } + /** + * {@inheritDoc} + */ @Override default Lens.Simple toLens() { return Lens.Simple.adapt(Iso.super.toLens()); } + /** + * {@inheritDoc} + */ @Override default Iso.Simple discardR(Applicative> appB) { return Iso.Simple.adapt(Iso.super.discardR(appB)); } + /** + * {@inheritDoc} + */ @Override default Iso.Simple andThen(Optic.Simple, ? super Functor, A, B> f) { return Iso.Simple.adapt(Iso.super.andThen(f)); } + /** + * {@inheritDoc} + */ @Override default Iso.Simple compose(Optic.Simple, ? super Functor, R, S> g) { return Iso.Simple.adapt(Iso.super.compose(g)); diff --git a/src/main/java/com/jnape/palatable/lambda/optics/Lens.java b/src/main/java/com/jnape/palatable/lambda/optics/Lens.java index 4e2583e03..8b5746c75 100644 --- a/src/main/java/com/jnape/palatable/lambda/optics/Lens.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/Lens.java @@ -144,73 +144,115 @@ public interface Lens extends Monad>, Profunctor> { + /** + * {@inheritDoc} + */ @Override default Lens fmap(Function fn) { return Monad.super.fmap(fn).coerce(); } + /** + * {@inheritDoc} + */ @Override default Lens pure(U u) { return lens(view(this), (s, b) -> u); } + /** + * {@inheritDoc} + */ @Override default Lens zip(Applicative, Lens> appFn) { return Monad.super.zip(appFn).coerce(); } + /** + * {@inheritDoc} + */ @Override default Lens discardL(Applicative> appB) { return Monad.super.discardL(appB).coerce(); } + /** + * {@inheritDoc} + */ @Override default Lens discardR(Applicative> appB) { return Monad.super.discardR(appB).coerce(); } + /** + * {@inheritDoc} + */ @Override default Lens flatMap(Function>> f) { return lens(view(this), (s, b) -> set(f.apply(set(this, b, s)).>coerce(), b, s)); } + /** + * {@inheritDoc} + */ @Override default Lens diMapL(Function fn) { return (Lens) Profunctor.super.diMapL(fn); } + /** + * {@inheritDoc} + */ @Override default Lens diMapR(Function fn) { return (Lens) Profunctor.super.diMapR(fn); } + /** + * {@inheritDoc} + */ @Override default Lens diMap(Function lFn, Function rFn) { return this.mapS(lFn).mapT(rFn); } + /** + * {@inheritDoc} + */ @Override default Lens contraMap(Function fn) { return (Lens) Profunctor.super.contraMap(fn); } + /** + * {@inheritDoc} + */ @Override default Lens mapS(Function fn) { return lens(Optic.super.mapS(fn)); } + /** + * {@inheritDoc} + */ @Override default Lens mapT(Function fn) { return lens(Optic.super.mapT(fn)); } + /** + * {@inheritDoc} + */ @Override default Lens mapA(Function fn) { return lens(Optic.super.mapA(fn)); } + /** + * {@inheritDoc} + */ @Override default Lens mapB(Function fn) { return lens(Optic.super.mapB(fn)); @@ -226,11 +268,17 @@ default Iso toIso(S s) { return iso(view(this), set(this).flip().apply(s)); } + /** + * {@inheritDoc} + */ @Override default Lens andThen(Optic, ? super Functor, A, B, C, D> f) { return lens(Optic.super.andThen(f)); } + /** + * {@inheritDoc} + */ @Override default Lens compose(Optic, ? super Functor, R, U, S, T> g) { return lens(Optic.super.compose(g)); @@ -258,11 +306,23 @@ static Lens lens(Function gette .fmap(b -> setter.apply(s, b)))); } + /** + * Promote an optic with compatible bounds to a {@link Lens}. + * + * @param optic the {@link Optic} + * @param the type of the "larger" value for reading + * @param the type of the "larger" value for putting + * @param the type of the "smaller" value that is read + * @param the type of the "smaller" update value + * @return the {@link Lens} + */ static Lens lens(Optic, ? super Functor, S, T, A, B> optic) { return new Lens() { @Override - public >, CoF extends Functor>, FB extends Functor, FT extends Functor, PAFB extends Profunctor, PSFT extends Profunctor> PSFT apply( - PAFB pafb) { + public >, CoF extends Functor>, + FB extends Functor, FT extends Functor, + PAFB extends Profunctor, + PSFT extends Profunctor> PSFT apply(PAFB pafb) { return optic.apply(pafb); } }; @@ -323,11 +383,17 @@ static Lens.Simple> both(Lens.Simple f, Lens.Sim @FunctionalInterface interface Simple extends Lens, Optic.Simple, Functor, S, A> { + /** + * {@inheritDoc} + */ @Override default Lens.Simple andThen(Optic.Simple, ? super Functor, A, B> f) { return Lens.Simple.adapt(Lens.super.andThen(f)); } + /** + * {@inheritDoc} + */ @Override default Lens.Simple compose(Optic.Simple, ? super Functor, R, S> g) { return Lens.Simple.adapt(Lens.super.compose(g)); diff --git a/src/main/java/com/jnape/palatable/lambda/optics/Optic.java b/src/main/java/com/jnape/palatable/lambda/optics/Optic.java index e524d06a9..4eeac4f75 100644 --- a/src/main/java/com/jnape/palatable/lambda/optics/Optic.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/Optic.java @@ -37,6 +37,8 @@ public interface Optic

, F extends Functo * * @param the covariant bound on P * @param the covariant bound on F + * @param fixed functor over B for inference + * @param fixed functor over T for inference * @param the fixed input profunctor type * @param the fixed output profunctor type * @return the monomorphic {@link Fn1} backed by this {@link Optic} @@ -52,7 +54,7 @@ Fn1 monomorphize() { } /** - * Left-to-right composition of optics. Requires compatibility between S> and T. + * Left-to-right composition of optics. Requires compatibility between S and T. * * @param f the other optic * @param the new left side of the input profunctor @@ -162,6 +164,8 @@ default Optic mapB(Function fn) { * @param the right side's functor embedding of the output profunctor * @param the left side of the input profunctor * @param the right side's functor embedding of the input profunctor + * @param fixed functor over B for inference + * @param fixed functor over T for inference * @param the input * @param the output * @return the {@link Optic} @@ -211,8 +215,17 @@ S, T, A, B> Optic reframe(Optic, ? extends P>>monomorphize()); } - interface Simple

, F extends Functor, S, A> extends - Optic { + /** + * An convenience type with a simplified signature for {@link Optic optics} with unified S/T and + * A/B types. + * + * @param

the {@link Profunctor} bound + * @param the {@link Functor} bound + * @param the left side and right side's functor embedding of the output profunctor + * @param the left side and right side's functor embedding of the input profunctor + */ + interface Simple

, F extends Functor, S, A> + extends Optic { /** * Compose two simple optics from left to right. diff --git a/src/main/java/com/jnape/palatable/lambda/optics/Prism.java b/src/main/java/com/jnape/palatable/lambda/optics/Prism.java new file mode 100644 index 000000000..bf2afb487 --- /dev/null +++ b/src/main/java/com/jnape/palatable/lambda/optics/Prism.java @@ -0,0 +1,217 @@ +package com.jnape.palatable.lambda.optics; + +import com.jnape.palatable.lambda.adt.Either; +import com.jnape.palatable.lambda.adt.Maybe; +import com.jnape.palatable.lambda.adt.choice.Choice2; +import com.jnape.palatable.lambda.adt.coproduct.CoProduct2; +import com.jnape.palatable.lambda.adt.hlist.Tuple2; +import com.jnape.palatable.lambda.functions.specialized.Pure; +import com.jnape.palatable.lambda.functor.Cocartesian; +import com.jnape.palatable.lambda.functor.Functor; +import com.jnape.palatable.lambda.functor.Profunctor; +import com.jnape.palatable.lambda.functor.builtin.Identity; +import com.jnape.palatable.lambda.functor.builtin.Market; +import com.jnape.palatable.lambda.optics.functions.Matching; +import com.jnape.palatable.lambda.optics.functions.Pre; +import com.jnape.palatable.lambda.optics.functions.Re; +import com.jnape.palatable.lambda.optics.functions.View; + +import java.util.function.Function; + +/** + * Prisms are {@link Iso Isos} that can fail in one direction. Example: + *

+ * {@code
+ * Prism parseInt =
+ *     prism(str -> Either.trying(() -> Integer.parseInt(str),
+ *                                constantly(str)),
+ *           Object::toString);
+ *
+ * String         str   = view(re(parseInt), 123); // "123"
+ * Maybe works = view(pre(parseInt), "123"); // Just 123
+ * Maybe fails = view(pre(parseInt), "foo"); // Nothing
+ * }
+ * 
+ *

+ * Note that because a {@link Prism} might fail in one direction, it cannot be immediately used for + * {@link View viewing}; however, the combinators {@link Re re}, {@link Pre pre}, and {@link Matching matching} can all + * be used to provide the additional context to a {@link Prism} so it can be used for viewing. + * + * @param the input that might fail to map to its output + * @param the guaranteed output + * @param the output that might fail to be produced + * @param the input that guarantees its output + */ +@FunctionalInterface +public interface Prism extends + ProtoOptic, S, T, A, B>, + Optic, Identity, S, T, A, B> { + + @Override + default >, + CoF extends Functor>, + FB extends Functor, FT extends Functor, + PAFB extends Profunctor, + PSFT extends Profunctor> PSFT apply(PAFB pafb) { + @SuppressWarnings("RedundantTypeArguments") + Optic, Identity, S, T, A, B> optic = this.>toOptic(Identity::new); + return optic.apply(pafb); + } + + /** + * Recover the two mappings encapsulated by this {@link Prism} by sending it through a {@link Market}. + * + * @return a {@link Tuple2 tuple} of the two mappings encapsulated by this {@link Prism} + */ + default Tuple2, Function>> unPrism() { + return Tuple2.fill(this., Identity, Identity, Identity, + Market>, Market>>apply( + new Market<>(Identity::new, Either::right)).fmap(Identity::runIdentity)) + .biMap(Market::bt, Market::sta); + } + + /** + * Static factory method for creating a {@link Prism} given a mapping from + * S -> {@link Either}<T, A> and a mapping from B -> T. + * + * @param sta the mapping from S -> {@link Either}<T, A> + * @param bt the mapping from B -> T + * @param the input that might fail to map to its output + * @param the guaranteed output + * @param the output that might fail to be produced + * @param the input that guarantees its output + * @return the {@link Prism} + */ + static Prism prism(Function> sta, + Function bt) { + return new Prism() { + @Override + public > Optic, F, S, T, A, B> toOptic( + Pure pure) { + return Optic., + F, + S, T, A, B, + Functor, + Functor, + Cocartesian, ?>, + Cocartesian, ?>>optic(pafb -> pafb.cocartesian() + .diMap(s -> sta.apply(s).match(Choice2::a, Choice2::b), + tOrFb -> tOrFb.match(pure::apply, fb -> fb.fmap(bt)))); + } + }; + } + + /** + * Promote a {@link ProtoOptic} with compatible bounds to an {@link Prism}. + * + * @param protoOptic the {@link ProtoOptic} + * @param the input that might fail to map to its output + * @param the guaranteed output + * @param the output that might fail to be produced + * @param the input that guarantees its output + * @return the {@link Prism} + */ + static Prism prism(ProtoOptic, S, T, A, B> protoOptic) { + return new Prism() { + @Override + public > Optic, F, S, T, A, B> toOptic( + Pure pure) { + Optic, F, S, T, A, B> optic = protoOptic.toOptic(pure); + return Optic.reframe(optic); + } + }; + } + + /** + * Promote an {@link Optic} with compatible bounds to an {@link Prism}. Note that because the {@link Optic} must + * guarantee an unbounded {@link Functor} constraint in order to satisfy any future covariant constraint, the + * resulting {@link Prism prism's} toOptic method will never need to consult its given + * {@link Pure lifting} function. + * + * @param optic the {@link Optic} + * @param the input that might fail to map to its output + * @param the guaranteed output + * @param the output that might fail to be produced + * @param the input that guarantees its output + * @return the {@link Prism} + */ + static Prism prism( + Optic, ? super Functor, S, T, A, B> optic) { + return new Prism() { + @Override + public > Optic, F, S, T, A, B> toOptic( + Pure pure) { + return Optic.reframe(optic); + } + }; + } + + /** + * Static factory method for creating a simple {@link Prism} from a function and its potentially failing inverse. + * + * @param sMaybeA a partial mapping from S -> A + * @param as a total mapping from A -> S + * @param the input that might fail to map to its output and the guaranteed output from the other direction + * @param the output that might fail to be produced and the input that guarantees its output in the other + * direction + * @return the {@link Simple simple prism} + */ + static Prism.Simple simplePrism(Function> sMaybeA, + Function as) { + return Prism.prism(s -> sMaybeA.apply(s).toEither(() -> s), as)::toOptic; + } + + /** + * A convenience type with a simplified type signature for common {@link Prism prism} with unified S/T + * and A/B types. + * + * @param the input that might fail to map to its output and the guaranteed output from the other direction + * @param the output that might fail to be produced and the input that guarantees its output in the other + * direction + */ + interface Simple extends Prism { + + /** + * Adapt a {@link Prism} with compatible bounds to a {@link Prism.Simple simple Prism}. + * + * @param prism the {@link Prism} + * @param the input that might fail to map to its output and the guaranteed output from the other + * direction + * @param the output that might fail to be produced and the input that guarantees its output in the other + * direction + * @return the {@link Prism.Simple simple Prism} + */ + static Prism.Simple adapt(Prism prism) { + return prism::toOptic; + } + + /** + * Adapt a {@link ProtoOptic} with compatible bounds to a {@link Prism.Simple simple Prism}. + * + * @param protoOptic the {@link ProtoOptic} + * @param the input that might fail to map to its output and the guaranteed output from the other + * direction + * @param the output that might fail to be produced and the input that guarantees its output in the + * other direction + * @return the {@link Prism.Simple simple Prism} + */ + static Prism.Simple adapt(ProtoOptic, S, S, A, A> protoOptic) { + return adapt(prism(protoOptic)); + } + + /** + * Adapt an {@link Optic} with compatible bounds to a {@link Prism.Simple simple Prism}. + * + * @param optic the {@link Optic} + * @param the input that might fail to map to its output and the guaranteed output from the other + * direction + * @param the output that might fail to be produced and the input that guarantees its output in the + * other direction + * @return the {@link Prism.Simple simple Prism} + */ + static Prism.Simple adapt( + Optic, ? super Functor, S, S, A, A> optic) { + return adapt(prism(optic)); + } + } +} diff --git a/src/main/java/com/jnape/palatable/lambda/optics/ProtoOptic.java b/src/main/java/com/jnape/palatable/lambda/optics/ProtoOptic.java new file mode 100644 index 000000000..1d38ef807 --- /dev/null +++ b/src/main/java/com/jnape/palatable/lambda/optics/ProtoOptic.java @@ -0,0 +1,28 @@ +package com.jnape.palatable.lambda.optics; + +import com.jnape.palatable.lambda.functions.specialized.Pure; +import com.jnape.palatable.lambda.functor.Functor; +import com.jnape.palatable.lambda.functor.Profunctor; + +/** + * A generic supertype representation for a profunctor {@link Optic} that requires a {@link Pure} implementation to + * derive its {@link Functor} constraint and graduate to a full-fledge {@link Optic}. + * + * @param

the {@link Profunctor} bound + * @param the left side of the output profunctor + * @param the right side's functor embedding of the output profunctor + * @param the left side of the input profunctor + * @param the right side's functor embedding of the input profunctor + */ +public interface ProtoOptic

, S, T, A, B> { + + /** + * Given a {@link Pure} lifting function, fix this {@link ProtoOptic} to the given {@link Functor} and promote it to + * an {@link Optic}. + * + * @param pure the {@link Pure} lifting function + * @param the {@link Functor} bound + * @return the {@link Optic} + */ + > Optic toOptic(Pure pure); +} diff --git a/src/main/java/com/jnape/palatable/lambda/optics/functions/Matching.java b/src/main/java/com/jnape/palatable/lambda/optics/functions/Matching.java new file mode 100644 index 000000000..425f47dcf --- /dev/null +++ b/src/main/java/com/jnape/palatable/lambda/optics/functions/Matching.java @@ -0,0 +1,46 @@ +package com.jnape.palatable.lambda.optics.functions; + +import com.jnape.palatable.lambda.adt.Either; +import com.jnape.palatable.lambda.functions.Fn1; +import com.jnape.palatable.lambda.functions.Fn2; +import com.jnape.palatable.lambda.functor.builtin.Identity; +import com.jnape.palatable.lambda.functor.builtin.Market; +import com.jnape.palatable.lambda.optics.Optic; + +public final class Matching implements + Fn2, ? super Identity, S, T, A, B>, S, Either> { + + private static final Matching INSTANCE = new Matching<>(); + + private Matching() { + } + + @Override + public Either apply(Optic, ? super Identity, S, T, A, B> optic, S s) { + Market> market = new Market<>(Identity::new, Either::right); + return optic., + Identity, + Identity, + Identity, + Market>, + Market>> + apply(market).sta().apply(s) + .biMapL(Identity::runIdentity) + .match(Either::left, Either::right); + } + + @SuppressWarnings("unchecked") + public static Matching matching() { + return (Matching) INSTANCE; + } + + public static Fn1> matching( + Optic, ? super Identity, S, T, A, B> optic) { + return Matching.matching().apply(optic); + } + + public static Either matching( + Optic, ? super Identity, S, T, A, B> optic, S s) { + return matching(optic).apply(s); + } +} diff --git a/src/main/java/com/jnape/palatable/lambda/optics/functions/Pre.java b/src/main/java/com/jnape/palatable/lambda/optics/functions/Pre.java new file mode 100644 index 000000000..edbd9e9c0 --- /dev/null +++ b/src/main/java/com/jnape/palatable/lambda/optics/functions/Pre.java @@ -0,0 +1,60 @@ +package com.jnape.palatable.lambda.optics.functions; + +import com.jnape.palatable.lambda.adt.Maybe; +import com.jnape.palatable.lambda.functions.Fn1; +import com.jnape.palatable.lambda.functions.specialized.Pure; +import com.jnape.palatable.lambda.functor.builtin.Const; +import com.jnape.palatable.lambda.optics.Optic; +import com.jnape.palatable.lambda.optics.ProtoOptic; + +import static com.jnape.palatable.lambda.adt.Maybe.nothing; +import static com.jnape.palatable.lambda.optics.Optic.reframe; + +/** + * Turn an {@link Optic} with a unary mapping that can be used for viewing some number of values into an {@link Optic} + * that views the first value, if it exists. + * + * @param the value to read from + * @param used for unification of the {@link Optic optic's} unused morphism + * @param the result to {@link Maybe maybe} read out + * @param used for unification of the {@link Optic optic's} unused morphism + */ +public final class Pre implements Fn1, ? super Const, ?>, S, T, A, B>, + Optic, Const, ?>, S, T, Maybe, B>> { + + private static final Pre INSTANCE = new Pre<>(); + + private Pre() { + } + + @Override + public Optic, Const, ?>, S, T, Maybe, B> apply( + Optic, ? super Const, ?>, S, T, A, B> optic) { + Optic, ? super Const, ?>, S, T, Maybe, B> mappedOptic = optic.mapA(Maybe::just); + return reframe(mappedOptic); + } + + @SuppressWarnings("unchecked") + public static Pre pre() { + return (Pre) INSTANCE; + } + + @SuppressWarnings("overloads") + public static Optic, Const, ?>, S, T, Maybe, B> pre( + Optic, ? super Const, ?>, S, T, A, B> optic) { + return Pre.pre().apply(optic); + } + + @SuppressWarnings("overloads") + public static Optic, Const, ?>, S, T, Maybe, B> pre( + ProtoOptic, S, T, A, B> protoOptic) { + Optic, Const, ?>, S, T, A, B> optic = protoOptic + .toOptic(new Pure, ?>>() { + @Override + public Const, X> apply(X x) { + return new Const<>(nothing()); + } + }); + return pre(optic); + } +} \ No newline at end of file diff --git a/src/main/java/com/jnape/palatable/lambda/optics/functions/Re.java b/src/main/java/com/jnape/palatable/lambda/optics/functions/Re.java new file mode 100644 index 000000000..a61841058 --- /dev/null +++ b/src/main/java/com/jnape/palatable/lambda/optics/functions/Re.java @@ -0,0 +1,48 @@ +package com.jnape.palatable.lambda.optics.functions; + +import com.jnape.palatable.lambda.functions.Fn1; +import com.jnape.palatable.lambda.functor.builtin.Const; +import com.jnape.palatable.lambda.functor.builtin.Identity; +import com.jnape.palatable.lambda.functor.builtin.Tagged; +import com.jnape.palatable.lambda.optics.Iso; +import com.jnape.palatable.lambda.optics.Optic; +import com.jnape.palatable.lambda.optics.Prism; + +/** + * Turn an {@link Optic} with a unary mapping that can be used for setting (e.g. {@link Prism}, {@link Iso}) around for + * viewing through the other direction. + * + * @param used for unification of the {@link Optic optic's} unused morphism + * @param the result to read out + * @param used for unification of the {@link Optic optic's} unused morphism + * @param the value to read from + */ +public final class Re implements + Fn1, ? super Identity, S, T, A, B>, Optic, Const, B, B, T, T>> { + + private static final Re INSTANCE = new Re<>(); + + private Re() { + } + + @Override + public Optic, Const, B, B, T, T> apply( + Optic, ? super Identity, S, T, A, B> optic) { + return Optic., Const, B, B, T, T, + Const, Const, + Fn1>, + Fn1>>optic(pafb -> b -> new Const<>(optic., Identity, Identity, + Identity, Tagged>, + Tagged>>apply(new Tagged<>(new Identity<>(b))).unTagged().runIdentity())); + } + + @SuppressWarnings("unchecked") + public static Re re() { + return (Re) INSTANCE; + } + + public static Optic, Const, B, B, T, T> re( + Optic, ? super Identity, S, T, A, B> optic) { + return Re.re().apply(optic); + } +} diff --git a/src/main/java/com/jnape/palatable/lambda/optics/functions/Set.java b/src/main/java/com/jnape/palatable/lambda/optics/functions/Set.java index d6cc30481..1921c45c6 100644 --- a/src/main/java/com/jnape/palatable/lambda/optics/functions/Set.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/functions/Set.java @@ -14,7 +14,7 @@ * T by lifting the {@link Optic} into the {@link Identity} functor. *

* More idiomatically, this function can be used to treat an {@link Optic} as a "setter" of - * < code>Bs on Ss, potentially producing a different "larger" value, T. + * Bs on Ss, potentially producing a different "larger" value, T. * * @param the type of the larger value * @param the type of the larger updated value diff --git a/src/main/java/com/jnape/palatable/lambda/traversable/LambdaIterable.java b/src/main/java/com/jnape/palatable/lambda/traversable/LambdaIterable.java index 5ef35da8e..09222e719 100644 --- a/src/main/java/com/jnape/palatable/lambda/traversable/LambdaIterable.java +++ b/src/main/java/com/jnape/palatable/lambda/traversable/LambdaIterable.java @@ -73,8 +73,6 @@ public LambdaIterable zip(Applicative, L /** * {@inheritDoc} - * - * @param lazyAppFn */ @Override public Lazy> lazyZip( diff --git a/src/test/java/com/jnape/palatable/lambda/functor/builtin/MarketTest.java b/src/test/java/com/jnape/palatable/lambda/functor/builtin/MarketTest.java new file mode 100644 index 000000000..d4009918e --- /dev/null +++ b/src/test/java/com/jnape/palatable/lambda/functor/builtin/MarketTest.java @@ -0,0 +1,29 @@ +package com.jnape.palatable.lambda.functor.builtin; + +import com.jnape.palatable.traitor.annotations.TestTraits; +import com.jnape.palatable.traitor.framework.Subjects; +import com.jnape.palatable.traitor.runners.Traits; +import org.junit.runner.RunWith; +import testsupport.EquatableM; +import testsupport.traits.ApplicativeLaws; +import testsupport.traits.FunctorLaws; +import testsupport.traits.MonadLaws; + +import static com.jnape.palatable.lambda.adt.Either.trying; +import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; +import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id; +import static com.jnape.palatable.lambda.functions.builtin.fn2.Both.both; +import static com.jnape.palatable.traitor.framework.Subjects.subjects; +import static java.lang.Integer.parseInt; + +@RunWith(Traits.class) +public class MarketTest { + + @TestTraits({FunctorLaws.class, ApplicativeLaws.class, MonadLaws.class}) + public Subjects, String>> testSubject() { + Market market = new Market<>(id(), str -> trying(() -> parseInt(str), + constantly(str))); + return subjects(new EquatableM<>(market, m -> both(m.bt(), m.sta(), "123")), + new EquatableM<>(market, m -> both(m.bt(), m.sta(), "foo"))); + } +} \ No newline at end of file diff --git a/src/test/java/com/jnape/palatable/lambda/optics/PrismTest.java b/src/test/java/com/jnape/palatable/lambda/optics/PrismTest.java new file mode 100644 index 000000000..47b76efdb --- /dev/null +++ b/src/test/java/com/jnape/palatable/lambda/optics/PrismTest.java @@ -0,0 +1,51 @@ +package com.jnape.palatable.lambda.optics; + +import com.jnape.palatable.lambda.adt.Either; +import com.jnape.palatable.lambda.adt.coproduct.CoProduct2; +import com.jnape.palatable.lambda.functions.Fn1; +import org.junit.Test; + +import java.util.function.Function; + +import static com.jnape.palatable.lambda.adt.Either.left; +import static com.jnape.palatable.lambda.adt.Either.right; +import static com.jnape.palatable.lambda.adt.Maybe.just; +import static com.jnape.palatable.lambda.optics.Prism.prism; +import static com.jnape.palatable.lambda.optics.Prism.simplePrism; +import static com.jnape.palatable.lambda.optics.functions.Matching.matching; +import static com.jnape.palatable.lambda.optics.functions.Pre.pre; +import static com.jnape.palatable.lambda.optics.functions.Re.re; +import static com.jnape.palatable.lambda.optics.functions.View.view; +import static org.junit.Assert.assertEquals; + +public class PrismTest { + + private static final Fn1 PARSE_INT = Fn1.fn1(Integer::parseInt); + + @Test + public void prismLaws() { + Prism prism = prism(PARSE_INT.choose(), Object::toString); + + assertEquals(just(1), view(pre(prism), view(re(prism), 1))); + assertEquals(just(123), view(pre(prism), "123").filter(a -> view(re(prism), a).equals("123"))); + assertEquals(left("foo"), matching(prism, "foo").match(t -> matching(prism, t), Either::right)); + } + + @Test + @SuppressWarnings("unused") + public void simplePrismInference() { + Prism.Simple simplePrism = simplePrism(PARSE_INT.choose().fmap(CoProduct2::projectB), + Object::toString); + } + + @Test + public void unPrismExtractsMappings() { + Prism prism = prism(PARSE_INT.choose(), Object::toString); + Function is = prism.unPrism()._1(); + Function> sis = prism.unPrism()._2(); + + assertEquals("123", is.apply(123)); + assertEquals(right(123), sis.apply("123")); + assertEquals(left("foo"), sis.apply("foo")); + } +} \ No newline at end of file diff --git a/src/test/java/com/jnape/palatable/lambda/optics/functions/PreTest.java b/src/test/java/com/jnape/palatable/lambda/optics/functions/PreTest.java new file mode 100644 index 000000000..d697108ee --- /dev/null +++ b/src/test/java/com/jnape/palatable/lambda/optics/functions/PreTest.java @@ -0,0 +1,30 @@ +package com.jnape.palatable.lambda.optics.functions; + +import com.jnape.palatable.lambda.adt.Either; +import com.jnape.palatable.lambda.optics.Iso; +import com.jnape.palatable.lambda.optics.Prism; +import org.junit.Test; + +import static com.jnape.palatable.lambda.adt.Maybe.just; +import static com.jnape.palatable.lambda.adt.Maybe.nothing; +import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; +import static com.jnape.palatable.lambda.optics.Iso.iso; +import static com.jnape.palatable.lambda.optics.Prism.prism; +import static com.jnape.palatable.lambda.optics.functions.Pre.pre; +import static com.jnape.palatable.lambda.optics.functions.View.view; +import static java.lang.Integer.parseInt; +import static org.junit.Assert.assertEquals; + +public class PreTest { + + @Test + public void focusOnAtMostOneValue() { + Iso iso = iso(Integer::parseInt, Object::toString); + Prism prism = prism(s -> Either.trying(() -> parseInt(s), + constantly(s)), + Object::toString); + assertEquals(just(1), view(pre(prism), "1")); + assertEquals(nothing(), view(pre(prism), "foo")); + assertEquals(just(1), view(pre(iso), "1")); + } +} \ No newline at end of file diff --git a/src/test/java/com/jnape/palatable/lambda/optics/functions/ReTest.java b/src/test/java/com/jnape/palatable/lambda/optics/functions/ReTest.java new file mode 100644 index 000000000..a6d4fb900 --- /dev/null +++ b/src/test/java/com/jnape/palatable/lambda/optics/functions/ReTest.java @@ -0,0 +1,27 @@ +package com.jnape.palatable.lambda.optics.functions; + +import com.jnape.palatable.lambda.adt.Either; +import com.jnape.palatable.lambda.optics.Iso; +import com.jnape.palatable.lambda.optics.Prism; +import org.junit.Test; + +import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; +import static com.jnape.palatable.lambda.optics.Iso.iso; +import static com.jnape.palatable.lambda.optics.Prism.prism; +import static com.jnape.palatable.lambda.optics.functions.Re.re; +import static com.jnape.palatable.lambda.optics.functions.View.view; +import static java.lang.Integer.parseInt; +import static org.junit.Assert.assertEquals; + +public class ReTest { + + @Test + public void flipAroundIsoAndPrism() { + Iso iso = iso(Integer::parseInt, Object::toString); + Prism prism = prism(s -> Either.trying(() -> parseInt(s), + constantly(s)), + Object::toString); + assertEquals("1", view(re(prism), 1)); + assertEquals("1", view(re(iso), 1)); + } +} \ No newline at end of file From a79e760f3796934e683fd9acfcceca6081cd03fc Mon Sep 17 00:00:00 2001 From: jnape Date: Sat, 4 May 2019 18:17:12 -0500 Subject: [PATCH 31/69] Adding missing javadoc --- .../lambda/functor/builtin/Market.java | 62 ++++++++++++++++--- .../lambda/functor/builtin/Tagged.java | 45 ++++++++++++++ 2 files changed, 99 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Market.java b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Market.java index 6929ac661..efb2e0247 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Market.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Market.java @@ -6,6 +6,7 @@ import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Cocartesian; import com.jnape.palatable.lambda.monad.Monad; +import com.jnape.palatable.lambda.optics.Prism; import java.util.function.Function; @@ -15,6 +16,14 @@ import static com.jnape.palatable.lambda.functions.Fn1.fn1; import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; +/** + * A profunctor used to extract the isomorphic functions a {@link Prism} is composed of. + * + * @param the output that might fail to be produced + * @param the input that guarantees its output + * @param the input that might fail to map to its output + * @param the guaranteed output + */ public final class Market implements Monad>, Cocartesian> { @@ -27,11 +36,35 @@ public Market(Function bt, FunctionB -> T. + * + * @return a {@link Function}<B, T> + */ + public Fn1 bt() { + return bt; + } + + /** + * Extract the mapping S -> {@link Either}<T, A>. + * + * @return a {@link Function}<S, {@link Either}<T, A>> + */ + public Fn1> sta() { + return sta; + } + + /** + * {@inheritDoc} + */ @Override public Market pure(U u) { return new Market<>(constantly(u), constantly(left(u))); } + /** + * {@inheritDoc} + */ @Override public Market flatMap(Function>> f) { return new Market<>(b -> f.apply(bt().apply(b)).>coerce().bt().apply(b), @@ -40,6 +73,9 @@ public Market flatMap(Function Market zip(Applicative, Market> appFn) { Market> marketF = appFn.coerce(); @@ -47,19 +83,17 @@ public Market zip(Applicative, s -> sta().apply(s).invert().zip(marketF.sta().apply(s).invert()).invert()); } - public Fn1 bt() { - return bt; - } - - public Fn1> sta() { - return sta; - } - + /** + * {@inheritDoc} + */ @Override public Market fmap(Function fn) { return diMapR(fn); } + /** + * {@inheritDoc} + */ @Override public Market, Choice2> cocartesian() { return new Market<>(bt.fmap(Choice2::b), @@ -67,22 +101,34 @@ public Market, Choice2> cocartesian() { tOrA -> tOrA.match(t -> left(b(t)), Either::right))); } + /** + * {@inheritDoc} + */ @Override public Market diMap(Function lFn, Function rFn) { return new Market<>(bt.fmap(rFn), sta.diMapL(lFn).diMapR(c -> c.biMapL(rFn))); } + /** + * {@inheritDoc} + */ @Override public Market diMapL(Function fn) { return (Market) Cocartesian.super.diMapL(fn); } + /** + * {@inheritDoc} + */ @Override public Market diMapR(Function fn) { return (Market) Cocartesian.super.diMapR(fn); } + /** + * {@inheritDoc} + */ @Override public Market contraMap(Function fn) { return (Market) Cocartesian.super.contraMap(fn); diff --git a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Tagged.java b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Tagged.java index cebe4973b..3b2ea5e79 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Tagged.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Tagged.java @@ -9,6 +9,13 @@ import static com.jnape.palatable.lambda.adt.choice.Choice2.b; +/** + * Like {@link Const}, but the phantom parameter is in the contravariant position, and the value is in covariant + * position. + * + * @param the phantom type + * @param the value type + */ public final class Tagged implements Monad>, Cocartesian> { private final B b; @@ -16,61 +23,99 @@ public Tagged(B b) { this.b = b; } + /** + * Extract the contained value. + * + * @return the value + */ public B unTagged() { return b; } + /** + * {@inheritDoc} + */ @Override public Tagged flatMap(Function>> f) { return f.apply(b).coerce(); } + /** + * {@inheritDoc} + */ @Override public Tagged pure(C c) { return new Tagged<>(c); } + /** + * {@inheritDoc} + */ @Override public Tagged fmap(Function fn) { return Monad.super.fmap(fn).coerce(); } + /** + * {@inheritDoc} + */ @Override public Tagged zip(Applicative, Tagged> appFn) { return Monad.super.zip(appFn).coerce(); } + /** + * {@inheritDoc} + */ @Override public Tagged discardL(Applicative> appB) { return Monad.super.discardL(appB).coerce(); } + /** + * {@inheritDoc} + */ @Override public Tagged discardR(Applicative> appB) { return Monad.super.discardR(appB).coerce(); } + /** + * {@inheritDoc} + */ @Override public Tagged, Choice2> cocartesian() { return new Tagged<>(b(b)); } + /** + * {@inheritDoc} + */ @Override public Tagged diMap(Function lFn, Function rFn) { return new Tagged<>(rFn.apply(b)); } + /** + * {@inheritDoc} + */ @Override public Tagged diMapL(Function fn) { return (Tagged) Cocartesian.super.diMapL(fn); } + /** + * {@inheritDoc} + */ @Override public Tagged diMapR(Function fn) { return (Tagged) Cocartesian.super.diMapR(fn); } + /** + * {@inheritDoc} + */ @Override public Tagged contraMap(Function fn) { return (Tagged) Cocartesian.super.contraMap(fn); From 45724d530298f74aa5c0cc6ea480131d11a71030 Mon Sep 17 00:00:00 2001 From: jnape Date: Sat, 4 May 2019 18:39:55 -0500 Subject: [PATCH 32/69] LazyT, a monad transformer for Lazy --- CHANGELOG.md | 5 + .../lambda/functor/builtin/Lazy.java | 31 ++++- .../monad/transformer/builtin/LazyT.java | 126 ++++++++++++++++++ .../monad/transformer/builtin/LazyTTest.java | 36 +++++ 4 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/LazyT.java create mode 100644 src/test/java/com/jnape/palatable/lambda/monad/transformer/builtin/LazyTTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 1263a8cf1..b79a97dbe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,10 +24,15 @@ might need to be reworked, and subtyping is obviously no longer supported. - `MaybeT`, a monad transformer for `Maybe` - `EitherT`, a monad transformer for `Either` - `IdentityT`, a monad transformer for `Identity` +- `LazyT`, a monad transformer for `Lazy` - `Endo`, a monoid formed by `Fn1` under composition - `State`, the state `Monad` - `Downcast`, a function supporting unchecked down-casting - `Cocartesian`, profunctorial strength in cocartesian coproduct terms +- `Prism`, an `Optic` that is nearly an `Iso` but can fail in one direction +- `Market`, `Tagged`, profunctors supporting optics +- `Re` for viewing an `Optic` in one direction reliably +- `Pre` for viewing at most one value from an `Optic` in one direction ## [3.3.0] - 2019-02-18 ### Added diff --git a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Lazy.java b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Lazy.java index f3f4be0ac..ea1bef9cd 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Lazy.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Lazy.java @@ -4,8 +4,10 @@ import com.jnape.palatable.lambda.functions.Fn0; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.monad.Monad; +import com.jnape.palatable.lambda.traversable.Traversable; import java.util.LinkedList; +import java.util.Objects; import java.util.function.Function; import java.util.function.Supplier; @@ -21,7 +23,7 @@ * * @param the value type */ -public abstract class Lazy implements Monad> { +public abstract class Lazy implements Monad>, Traversable> { private Lazy() { } @@ -44,6 +46,18 @@ public Lazy flatMap(Function>> f) { return new Compose<>(source, flatMap); } + /** + * {@inheritDoc} + */ + @Override + @SuppressWarnings("unchecked") + public , TravB extends Traversable>, + AppB extends Applicative, + AppTrav extends Applicative> AppTrav traverse(Function fn, + Function pure) { + return fn.apply(value()).fmap(b -> (TravB) lazy(b)).coerce(); + } + /** * {@inheritDoc} */ @@ -84,6 +98,21 @@ public final Lazy discardR(Applicative> appB) { return Monad.super.discardR(appB).coerce(); } + @Override + public boolean equals(Object other) { + return other instanceof Lazy && Objects.equals(value(), ((Lazy) other).value()); + } + + @Override + public int hashCode() { + return Objects.hash(value()); + } + + @Override + public String toString() { + return "Lazy{value=" + value() + "}"; + } + /** * Lift a pure value into a lazy computation. * diff --git a/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/LazyT.java b/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/LazyT.java new file mode 100644 index 000000000..fe10e8142 --- /dev/null +++ b/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/LazyT.java @@ -0,0 +1,126 @@ +package com.jnape.palatable.lambda.monad.transformer.builtin; + +import com.jnape.palatable.lambda.functor.Applicative; +import com.jnape.palatable.lambda.functor.Functor; +import com.jnape.palatable.lambda.functor.builtin.Compose; +import com.jnape.palatable.lambda.functor.builtin.Lazy; +import com.jnape.palatable.lambda.monad.Monad; +import com.jnape.palatable.lambda.monad.transformer.MonadT; + +import java.util.Objects; +import java.util.function.Function; + +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; + +/** + * A {@link MonadT monad transformer} for {@link Lazy}. Note that {@link LazyT#flatMap(Function)} must force its value. + * + * @param the outer {@link Monad} + * @param the carrier type + */ +public class LazyT, A> implements MonadT, A> { + + private final Monad, M> mla; + + private LazyT(Monad, M> mla) { + this.mla = mla; + } + + /** + * {@inheritDoc} + */ + @Override + public >, FGA extends Monad> FGA run() { + return mla.fmap(Functor::coerce).coerce(); + } + + /** + * {@inheritDoc} + */ + @Override + public LazyT flatMap(Function, ?>>> f) { + return new LazyT<>(mla.flatMap(lazyA -> f.apply(lazyA.value())., B>>coerce().run())); + } + + /** + * {@inheritDoc} + */ + @Override + public LazyT pure(B b) { + return new LazyT<>(mla.pure(lazy(b))); + } + + /** + * {@inheritDoc} + */ + @Override + public LazyT fmap(Function fn) { + return MonadT.super.fmap(fn).coerce(); + } + + /** + * {@inheritDoc} + */ + @Override + public LazyT zip(Applicative, MonadT, ?>> appFn) { + return MonadT.super.zip(appFn).coerce(); + } + + /** + * {@inheritDoc} + */ + @Override + public Lazy> lazyZip( + Lazy, MonadT, ?>>> lazyAppFn) { + return new Compose<>(mla) + .lazyZip(lazyAppFn.fmap(lazyT -> new Compose<>( + lazyT.>>coerce() + .>, + Monad>, M>>run()))) + .fmap(compose -> lazyT(compose.getCompose())); + } + + /** + * {@inheritDoc} + */ + @Override + public LazyT discardL(Applicative, ?>> appB) { + return MonadT.super.discardL(appB).coerce(); + } + + /** + * {@inheritDoc} + */ + @Override + public LazyT discardR(Applicative, ?>> appB) { + return MonadT.super.discardR(appB).coerce(); + } + + @Override + public boolean equals(Object other) { + return other instanceof LazyT && Objects.equals(mla, ((LazyT) other).mla); + } + + @Override + public int hashCode() { + return Objects.hash(mla); + } + + @Override + public String toString() { + return "LazyT{mla=" + mla + '}'; + } + + /** + * Static factory method for lifting a {@link Monad}<{@link Lazy}<A>, M> into a + * {@link LazyT}. + * + * @param mla the {@link Monad}<{@link Lazy}<A>, M> + * @param the outer {@link Monad} unification parameter + * @param the carrier type + * @return the new {@link LazyT} + */ + public static , A> LazyT lazyT(Monad, M> mla) { + return new LazyT<>(mla); + } +} diff --git a/src/test/java/com/jnape/palatable/lambda/monad/transformer/builtin/LazyTTest.java b/src/test/java/com/jnape/palatable/lambda/monad/transformer/builtin/LazyTTest.java new file mode 100644 index 000000000..87dffb7e6 --- /dev/null +++ b/src/test/java/com/jnape/palatable/lambda/monad/transformer/builtin/LazyTTest.java @@ -0,0 +1,36 @@ +package com.jnape.palatable.lambda.monad.transformer.builtin; + +import com.jnape.palatable.lambda.adt.Maybe; +import com.jnape.palatable.traitor.annotations.TestTraits; +import com.jnape.palatable.traitor.runners.Traits; +import org.junit.Test; +import org.junit.runner.RunWith; +import testsupport.traits.ApplicativeLaws; +import testsupport.traits.FunctorLaws; +import testsupport.traits.MonadLaws; + +import static com.jnape.palatable.lambda.adt.Maybe.just; +import static com.jnape.palatable.lambda.adt.Maybe.nothing; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; +import static com.jnape.palatable.lambda.monad.transformer.builtin.LazyT.lazyT; +import static org.junit.Assert.assertEquals; + +@RunWith(Traits.class) +public class LazyTTest { + + @TestTraits({FunctorLaws.class, ApplicativeLaws.class, MonadLaws.class}) + public LazyT, Integer> testSubject() { + return lazyT(just(lazy(1))); + } + + @Test + public void lazyZip() { + assertEquals(lazyT(just(lazy(2))), + lazyT(just(lazy(1))) + .lazyZip(lazy(lazyT(just(lazy(x -> x + 1))))).value()); + assertEquals(lazyT(nothing()), + lazyT(nothing()).lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + } +} \ No newline at end of file From 47969896958f1ae415eabb8cfca207f66c7948cf Mon Sep 17 00:00:00 2001 From: jnape Date: Sun, 5 May 2019 21:22:16 -0500 Subject: [PATCH 33/69] Try/Either no longer attempt in vain to preserve Throwable type --- CHANGELOG.md | 2 + .../jnape/palatable/lambda/adt/Either.java | 18 +-- .../com/jnape/palatable/lambda/adt/Try.java | 125 +++++++----------- .../specialized/checked/Runtime.java | 5 +- .../iteration/RateLimitingIterator.java | 10 +- .../jnape/palatable/lambda/adt/TryTest.java | 40 +++--- .../functions/builtin/fn4/RateLimitTest.java | 12 +- 7 files changed, 96 insertions(+), 116 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b79a97dbe..cda581167 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ might need to be reworked, and subtyping is obviously no longer supported. - ***Breaking Change***: `Strong` is now called `Cartesian` to better reflect the type of strength - ***Breaking Change***: new Optic type hierarchy more faithfully encodes profunctor constraints on optics, new `Optic` type is now the supertype of `Lens` and `Iso`, and `lens` package has been moved to `optics` +- ***Breaking Change***: Try and Either no longer preserve `Throwable` type since it was inherently not type-safe + anyway; Try is therefore no longer a `Bifunctor` - `IO` is now stack-safe, regardless of whether the composition nests linearly or recursively ### Added diff --git a/src/main/java/com/jnape/palatable/lambda/adt/Either.java b/src/main/java/com/jnape/palatable/lambda/adt/Either.java index 242d800e9..bda1b4fa2 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/Either.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/Either.java @@ -323,14 +323,13 @@ public static Either fromMaybe(Maybe maybe, Supplier leftFn) * * @param supplier the supplier of the right value * @param leftFn a function mapping E to L - * @param the most contravariant exception that the supplier might throw * @param the left parameter type * @param the right parameter type * @return the supplier result as a right value, or leftFn's mapping result as a left value */ - public static Either trying(CheckedSupplier supplier, - Function leftFn) { - return Try.trying(supplier::get).toEither(leftFn); + public static Either trying(CheckedSupplier supplier, + Function leftFn) { + return Try.trying(supplier::get).toEither(leftFn); } /** @@ -338,11 +337,10 @@ public static Either trying(CheckedSupplier the left parameter type (the most contravariant exception that supplier might throw) * @param the right parameter type * @return the supplier result as a right value, or a left value of the thrown exception */ - public static Either trying(CheckedSupplier supplier) { + public static Either trying(CheckedSupplier supplier) { return trying(supplier, id()); } @@ -352,12 +350,11 @@ public static Either trying(CheckedSupplier * * @param runnable the runnable * @param leftFn a function mapping E to L - * @param the most contravariant exception that the runnable might throw * @param the left parameter type * @return {@link Unit} as a right value, or leftFn's mapping result as a left value */ - public static Either trying(CheckedRunnable runnable, - Function leftFn) { + public static Either trying(CheckedRunnable runnable, + Function leftFn) { return Try.trying(runnable).toEither(leftFn); } @@ -366,10 +363,9 @@ public static Either trying(CheckedRunnable * exception, wrap it in a left value and return it. * * @param runnable the runnable - * @param the left parameter type (the most contravariant exception that runnable might throw) * @return {@link Unit} as a right value, or a left value of the thrown exception */ - public static Either trying(CheckedRunnable runnable) { + public static Either trying(CheckedRunnable runnable) { return trying(runnable, id()); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/Try.java b/src/main/java/com/jnape/palatable/lambda/adt/Try.java index 4b0e24b19..fddedbb37 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/Try.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/Try.java @@ -4,8 +4,8 @@ import com.jnape.palatable.lambda.functions.specialized.checked.CheckedFn1; import com.jnape.palatable.lambda.functions.specialized.checked.CheckedRunnable; import com.jnape.palatable.lambda.functions.specialized.checked.CheckedSupplier; +import com.jnape.palatable.lambda.functions.specialized.checked.Runtime; import com.jnape.palatable.lambda.functor.Applicative; -import com.jnape.palatable.lambda.functor.BoundedBifunctor; import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; @@ -18,18 +18,16 @@ import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id; import static com.jnape.palatable.lambda.functions.builtin.fn1.Upcast.upcast; -import static com.jnape.palatable.lambda.functions.builtin.fn2.Peek2.peek2; import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; /** * A {@link Monad} of the evaluation outcome of an expression that might throw. Try/catch/finally semantics map to * trying/catching/ensuring, respectively. * - * @param the {@link Throwable} type that may have been thrown by the expression * @param the possibly successful expression result * @see Either */ -public abstract class Try implements Monad>, Traversable>, BoundedBifunctor>, CoProduct2> { +public abstract class Try implements Monad>, Traversable>, CoProduct2> { private Try() { } @@ -43,7 +41,8 @@ private Try() { * @return a new {@link Try} instance around either the original successful result or the mapped result */ @SuppressWarnings("unchecked") - public final Try catching(Class throwableType, Function recoveryFn) { + public final Try catching(Class throwableType, + Function recoveryFn) { return catching(throwableType::isInstance, t -> recoveryFn.apply((S) t)); } @@ -54,8 +53,8 @@ public final Try catching(Class throwableType, Function catching(Function predicate, - Function recoveryFn) { + public final Try catching(Function predicate, + Function recoveryFn) { return match(t -> predicate.apply(t) ? success(recoveryFn.apply(t)) : failure(t), Try::success); } @@ -72,10 +71,13 @@ public final Try catching(Function predicate * @return the same {@link Try} instance if runnable completes successfully; otherwise, a {@link Try} conforming to * rules above */ - public final Try ensuring(CheckedRunnable runnable) { - return match(t -> peek2(t::addSuppressed, __ -> {}, trying(runnable)) - .biMapL(constantly(t)) - .flatMap(constantly(failure(t))), + public final Try ensuring(CheckedRunnable runnable) { + return match(t -> trying(runnable) + .>fmap(constantly(failure(t))) + .recover(t2 -> { + t.addSuppressed(t2); + return failure(t); + }), a -> trying(runnable).fmap(constantly(a))); } @@ -86,7 +88,7 @@ public final Try ensuring(CheckedRunnable runnable) { * @param fn the function mapping the potential {@link Throwable} T to A * @return a success value */ - public final A recover(Function fn) { + public final A recover(Function fn) { return match(fn, id()); } @@ -97,7 +99,7 @@ public final A recover(Function fn) { * @param fn the function mapping the potential A to T * @return a failure value */ - public final T forfeit(Function fn) { + public final Throwable forfeit(Function fn) { return match(id(), fn); } @@ -105,9 +107,8 @@ public final T forfeit(Function fn) { * If this is a success value, return it. Otherwise, rethrow the captured failure. * * @return possibly the success value - * @throws T the possible failure */ - public abstract A orThrow() throws T; + public abstract A orThrow(); /** * If this is a success, wrap the value in a {@link Maybe#just} and return it. Otherwise, return {@link @@ -125,7 +126,7 @@ public final Maybe toMaybe() { * * @return {@link Either} the success value or the {@link Throwable} */ - public final Either toEither() { + public final Either toEither() { return toEither(id()); } @@ -137,7 +138,7 @@ public final Either toEither() { * @param the {@link Either} left parameter type * @return {@link Either} the success value or the mapped left value */ - public final Either toEither(Function fn) { + public final Either toEither(Function fn) { return match(fn.andThen(Either::left), Either::right); } @@ -145,7 +146,7 @@ public final Either toEither(Function fn) { * {@inheritDoc} */ @Override - public Try fmap(Function fn) { + public Try fmap(Function fn) { return Monad.super.fmap(fn).coerce(); } @@ -153,7 +154,7 @@ public Try fmap(Function fn) { * {@inheritDoc} */ @Override - public Try flatMap(Function>> f) { + public Try flatMap(Function>> f) { return match(Try::failure, a -> f.apply(a).coerce()); } @@ -161,7 +162,7 @@ public Try flatMap(Function>> * {@inheritDoc} */ @Override - public Try pure(B b) { + public Try pure(B b) { return success(b); } @@ -169,13 +170,13 @@ public Try pure(B b) { * {@inheritDoc} */ @Override - public Try zip(Applicative, Try> appFn) { + public Try zip(Applicative, Try> appFn) { return Monad.super.zip(appFn).coerce(); } @Override - public Lazy> lazyZip( - Lazy, Try>> lazyAppFn) { + public Lazy> lazyZip( + Lazy, Try>> lazyAppFn) { return match(f -> lazy(failure(f)), s -> lazyAppFn.fmap(tryF -> tryF.fmap(f -> f.apply(s)).coerce())); } @@ -184,7 +185,7 @@ public Lazy> lazyZip( * {@inheritDoc} */ @Override - public Try discardL(Applicative> appB) { + public Try discardL(Applicative> appB) { return Monad.super.discardL(appB).coerce(); } @@ -192,7 +193,7 @@ public Try discardL(Applicative> appB) { * {@inheritDoc} */ @Override - public Try discardR(Applicative> appB) { + public Try discardR(Applicative> appB) { return Monad.super.discardR(appB).coerce(); } @@ -201,48 +202,22 @@ public Try discardR(Applicative> appB) { */ @Override @SuppressWarnings("unchecked") - public , TravB extends Traversable>, + public , TravB extends Traversable>, AppB extends Applicative, AppTrav extends Applicative> AppTrav traverse(Function fn, Function pure) { return match(t -> pure.apply((TravB) failure(t)), - a -> fn.apply(a).>fmap(Try::success).fmap(Applicative::coerce).coerce()); - } - - /** - * {@inheritDoc} - */ - @Override - public Try biMap(Function lFn, - Function rFn) { - return match(t -> failure(lFn.apply(t)), a -> success(rFn.apply(a))); - } - - /** - * {@inheritDoc} - */ - @Override - public Try biMapL(Function fn) { - return (Try) BoundedBifunctor.super.biMapL(fn); - } - - /** - * {@inheritDoc} - */ - @Override - public Try biMapR(Function fn) { - return (Try) BoundedBifunctor.super.biMapR(fn); + a -> fn.apply(a).fmap(Try::success).fmap(Applicative::coerce).coerce()); } /** * Static factory method for creating a success value. * * @param a the wrapped value - * @param the failure parameter type * @param the success parameter type * @return a success value of a */ - public static Try success(A a) { + public static Try success(A a) { return new Success<>(a); } @@ -254,7 +229,7 @@ public static Try success(A a) { * @param the success parameter type * @return a failure value of t */ - public static Try failure(T t) { + public static Try failure(T t) { return new Failure<>(t); } @@ -266,12 +241,11 @@ public static Try failure(T t) { * @param the possible success type * @return a new {@link Try} around either a successful A result or the thrown {@link Throwable} */ - @SuppressWarnings("unchecked") - public static Try trying(CheckedSupplier supplier) { + public static Try trying(CheckedSupplier supplier) { try { return success(supplier.get()); } catch (Throwable t) { - return failure((T) t); + return failure(t); } } @@ -279,10 +253,9 @@ public static Try trying(CheckedSupplier su * Execute runnable, returning a success {@link Unit} or a failure of the thrown {@link Throwable}. * * @param runnable the runnable - * @param the possible {@link Throwable} type * @return a new {@link Try} around either a successful {@link Unit} result or the thrown {@link Throwable} */ - public static Try trying(CheckedRunnable runnable) { + public static Try trying(CheckedRunnable runnable) { return trying(() -> { runnable.run(); return UNIT; @@ -317,12 +290,12 @@ public static Try trying(CheckedRunnable runna * @return a {@link Try} representing the result of the function's application to the resource */ @SuppressWarnings("try") - public static Try withResources( + public static Try withResources( CheckedSupplier aSupplier, - CheckedFn1> fn) { + CheckedFn1> fn) { return trying(() -> { try (A resource = aSupplier.get()) { - return fn.apply(resource).biMap(upcast(), upcast()); + return fn.apply(resource).fmap(upcast()); } }).flatMap(id()); } @@ -339,10 +312,10 @@ public static Try withResources( * @param the function return type * @return a {@link Try} representing the result of the function's application to the dependent resource */ - public static Try withResources( + public static Try withResources( CheckedSupplier aSupplier, CheckedFn1 bFn, - CheckedFn1> fn) { + CheckedFn1> fn) { return withResources(aSupplier, a -> withResources(() -> bFn.apply(a), fn::apply)); } @@ -361,28 +334,28 @@ public static Try the function return type * @return a {@link Try} representing the result of the function's application to the final dependent resource */ - public static Try withResources( + public static Try withResources( CheckedSupplier aSupplier, CheckedFn1 bFn, CheckedFn1 cFn, - CheckedFn1> fn) { + CheckedFn1> fn) { return withResources(aSupplier, bFn, b -> withResources(() -> cFn.apply(b), fn::apply)); } - private static final class Failure extends Try { - private final T t; + private static final class Failure extends Try { + private final Throwable t; - private Failure(T t) { + private Failure(Throwable t) { this.t = t; } @Override - public A orThrow() throws T { - throw t; + public A orThrow() { + throw Runtime.throwChecked(t); } @Override - public R match(Function aFn, Function bFn) { + public R match(Function aFn, Function bFn) { return aFn.apply(t); } @@ -404,7 +377,7 @@ public String toString() { } } - private static final class Success extends Try { + private static final class Success extends Try { private final A a; private Success(A a) { @@ -412,12 +385,12 @@ private Success(A a) { } @Override - public A orThrow() throws T { + public A orThrow() { return a; } @Override - public R match(Function aFn, Function bFn) { + public R match(Function aFn, Function bFn) { return bFn.apply(a); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/Runtime.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/Runtime.java index 1546e811b..5ba88fd93 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/Runtime.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/Runtime.java @@ -1,6 +1,9 @@ package com.jnape.palatable.lambda.functions.specialized.checked; -class Runtime { +public final class Runtime { + + private Runtime() { + } @SuppressWarnings("unchecked") public static RuntimeException throwChecked(Throwable t) throws T { diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/RateLimitingIterator.java b/src/main/java/com/jnape/palatable/lambda/iteration/RateLimitingIterator.java index f7b622bb8..510c95d91 100644 --- a/src/main/java/com/jnape/palatable/lambda/iteration/RateLimitingIterator.java +++ b/src/main/java/com/jnape/palatable/lambda/iteration/RateLimitingIterator.java @@ -1,5 +1,6 @@ package com.jnape.palatable.lambda.iteration; +import com.jnape.palatable.lambda.adt.Try; import com.jnape.palatable.lambda.adt.hlist.Tuple3; import java.time.Duration; @@ -13,12 +14,14 @@ import java.util.Set; import java.util.function.Supplier; +import static com.jnape.palatable.lambda.adt.Try.failure; import static com.jnape.palatable.lambda.adt.Try.trying; import static com.jnape.palatable.lambda.functions.builtin.fn1.Size.size; import static com.jnape.palatable.lambda.functions.builtin.fn2.Filter.filter; import static com.jnape.palatable.lambda.functions.builtin.fn2.GTE.gte; import static com.jnape.palatable.lambda.functions.builtin.fn2.LT.lt; import static com.jnape.palatable.lambda.functions.builtin.fn2.LTE.lte; +import static com.jnape.palatable.lambda.monad.Monad.join; import static com.jnape.palatable.lambda.semigroup.builtin.Max.max; import static java.lang.Thread.sleep; import static java.util.Collections.emptyList; @@ -58,14 +61,17 @@ private void awaitNextTimeSlice() { private void awaitNextTimeSliceForRateLimit(Tuple3> rateLimit) { while (rateLimitExhaustedInTimeSlice(rateLimit)) { - trying(() -> sleep(0)).biMapL(IterationInterruptedException::new).orThrow(); + join(trying(() -> sleep(0)) + .fmap(Try::success) + .catching(InterruptedException.class, t -> failure(new IterationInterruptedException(t)))) + .orThrow(); } } private boolean rateLimitExhaustedInTimeSlice(Tuple3> rateLimit) { List timeSlicesForRateLimit = timeSlicesByRateLimit.getOrDefault(rateLimit, emptyList()); return rateLimit.into((limit, duration, instantSupplier) -> { - Instant timeSliceEnd = instantSupplier.get(); + Instant timeSliceEnd = instantSupplier.get(); Instant previousTimeSliceEnd = timeSliceEnd.minus(duration); timeSlicesForRateLimit.removeIf(lt(previousTimeSliceEnd)); return max(0L, limit - size(filter(mark -> lte(mark, previousTimeSliceEnd) && gte(mark, timeSliceEnd), timeSlicesForRateLimit))) == 0; diff --git a/src/test/java/com/jnape/palatable/lambda/adt/TryTest.java b/src/test/java/com/jnape/palatable/lambda/adt/TryTest.java index 57b1696f8..aca7d039d 100644 --- a/src/test/java/com/jnape/palatable/lambda/adt/TryTest.java +++ b/src/test/java/com/jnape/palatable/lambda/adt/TryTest.java @@ -44,13 +44,13 @@ public class TryTest { @Rule public ExpectedException thrown = ExpectedException.none(); @TestTraits({FunctorLaws.class, ApplicativeLaws.class, MonadLaws.class, TraversableLaws.class}) - public Subjects> testSubject() { + public Subjects> testSubject() { return subjects(failure(new IllegalStateException()), success(1)); } @Test public void catchingWithGenericPredicate() { - Try caught = Try.failure(new RuntimeException()) + Try caught = Try.failure(new RuntimeException()) .catching(__ -> false, r -> "caught first") .catching(__ -> true, r -> "caught second"); @@ -59,7 +59,7 @@ public void catchingWithGenericPredicate() { @Test public void catchingIsANoOpForSuccess() { - Try caught = Try.success("success") + Try caught = success("success") .catching(__ -> true, __ -> "caught"); assertEquals(success("success"), caught); @@ -67,7 +67,7 @@ public void catchingIsANoOpForSuccess() { @Test public void firstMatchingCatchBlockWins() { - Try caught = Try.failure(new IllegalStateException()) + Try caught = Try.failure(new IllegalStateException()) .catching(__ -> true, __ -> "first") .catching(__ -> true, __ -> "second"); @@ -76,7 +76,7 @@ public void firstMatchingCatchBlockWins() { @Test public void catchBasedOnExceptionType() { - Try caught = Try.failure(new IllegalStateException()) + Try caught = Try.failure(new IllegalStateException()) .catching(IllegalArgumentException.class, __ -> "illegal argument exception") .catching(IllegalStateException.class, __ -> "illegal state exception") .catching(RuntimeException.class, __ -> "runtime exception"); @@ -87,7 +87,7 @@ public void catchBasedOnExceptionType() { @Test public void ensureIfSuccess() { AtomicInteger invocations = new AtomicInteger(0); - Try.success(1).ensuring((invocations::incrementAndGet)); + success(1).ensuring((invocations::incrementAndGet)); assertEquals(1, invocations.get()); } @@ -101,9 +101,9 @@ public void ensureIfFailure() { @Test public void exceptionThrownInEnsuringBlockIsCaught() { IllegalStateException expected = new IllegalStateException(); - assertEquals(Try.failure(expected), Try.success(1).ensuring(() -> {throw expected;})); + assertEquals(Try.failure(expected), success(1).ensuring(() -> {throw expected;})); - Either actual = Try.failure(new IllegalArgumentException()) + Either actual = Try.failure(new IllegalArgumentException()) .ensuring(() -> { throw expected;}) .toEither(); assertThat(actual, isLeftThat(instanceOf(IllegalArgumentException.class))); @@ -114,12 +114,12 @@ public void exceptionThrownInEnsuringBlockIsCaught() { public void forfeitEnsuresFailure() { IllegalStateException expected = new IllegalStateException(); assertEquals(expected, Try.failure(expected).forfeit(__ -> new IllegalArgumentException())); - assertEquals(expected, Try.success(1).forfeit(__ -> expected)); + assertEquals(expected, Try.success(1).forfeit(__ -> expected)); } @Test public void recoverEnsuresSuccess() { - assertEquals((Integer) 1, Try.success(1).recover(constantly(1))); + assertEquals((Integer) 1, Try.success(1).recover(constantly(1))); assertEquals((Integer) 1, Try.failure(new IllegalArgumentException()).recover(constantly(1))); } @@ -134,13 +134,13 @@ public void orThrow() throws Throwable { @Test public void toMaybe() { - assertEquals(just("foo"), Try.success("foo").toMaybe()); + assertEquals(just("foo"), success("foo").toMaybe()); assertEquals(nothing(), Try.failure(new IllegalStateException()).toMaybe()); } @Test public void toEither() { - assertEquals(right("foo"), Try.success("foo").toEither()); + assertEquals(right("foo"), success("foo").toEither()); IllegalStateException exception = new IllegalStateException(); assertEquals(left(exception), Try.failure(exception).toEither()); @@ -148,7 +148,7 @@ public void toEither() { @Test public void toEitherWithLeftMappingFunction() { - assertEquals(right(1), Try.success(1).toEither(__ -> "fail")); + assertEquals(right(1), success(1).toEither(__ -> "fail")); assertEquals(left("fail"), Try.failure(new IllegalStateException("fail")).toEither(Throwable::getMessage)); } @@ -163,13 +163,13 @@ public void tryingCatchesAnyThrowableThrownDuringEvaluation() { @Test public void withResourcesCleansUpAutoCloseableInSuccessCase() { AtomicBoolean closed = new AtomicBoolean(false); - assertEquals(Try.success(1), Try.withResources(() -> () -> closed.set(true), resource -> success(1))); + assertEquals(success(1), Try.withResources(() -> () -> closed.set(true), resource -> success(1))); assertTrue(closed.get()); } @Test public void withResourcesCleansUpAutoCloseableInFailureCase() { - AtomicBoolean closed = new AtomicBoolean(false); + AtomicBoolean closed = new AtomicBoolean(false); RuntimeException exception = new RuntimeException(); assertEquals(Try.failure(exception), Try.withResources(() -> () -> closed.set(true), resource -> { throw exception; })); @@ -191,11 +191,11 @@ public void withResourcesExposesResourceCloseFailure() { @Test public void withResourcesPreservesSuppressedExceptionThrownDuringClose() { - RuntimeException rootException = new RuntimeException(); - IOException nestedIOException = new IOException(); - Try failure = Try.withResources(() -> () -> { throw nestedIOException; }, - resource -> { throw rootException; }); - Exception thrown = failure.recover(id()); + RuntimeException rootException = new RuntimeException(); + IOException nestedIOException = new IOException(); + Try failure = Try.withResources(() -> () -> { throw nestedIOException; }, + resource -> { throw rootException; }); + Throwable thrown = failure.recover(id()); assertEquals(thrown, rootException); assertArrayEquals(new Throwable[]{nestedIOException}, thrown.getSuppressed()); diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn4/RateLimitTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn4/RateLimitTest.java index 0459a8be1..b37527919 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn4/RateLimitTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn4/RateLimitTest.java @@ -1,6 +1,5 @@ package com.jnape.palatable.lambda.functions.builtin.fn4; -import com.jnape.palatable.lambda.adt.Try; import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.iteration.IterationInterruptedException; import com.jnape.palatable.traitor.annotations.TestTraits; @@ -17,8 +16,10 @@ import java.time.Duration; import java.util.concurrent.CountDownLatch; +import static com.jnape.palatable.lambda.adt.Try.trying; import static com.jnape.palatable.lambda.functions.builtin.fn1.Repeat.repeat; import static com.jnape.palatable.lambda.functions.builtin.fn4.RateLimit.rateLimit; +import static com.jnape.palatable.lambda.functions.specialized.checked.CheckedRunnable.checked; import static java.time.Clock.systemUTC; import static java.time.Duration.ZERO; import static java.util.Arrays.asList; @@ -55,18 +56,17 @@ public void zeroDurationJustIteratesElements() { @Test public void limitPerDurationIsHonoredAccordingToClock() { Duration duration = Duration.ofMillis(10); - long limit = 2L; + long limit = 2L; assertThat(rateLimit(clock::instant, limit, duration, asList(1, 2, 3, 4)), iteratesAccordingToRateLimit(limit, duration, asList(1, 2, 3, 4), clock)); } @Test(timeout = 100, expected = IterationInterruptedException.class) public void rateLimitingDelayIsInterruptible() throws InterruptedException { - Thread testThread = Thread.currentThread(); - CountDownLatch latch = new CountDownLatch(1); + Thread testThread = Thread.currentThread(); + CountDownLatch latch = new CountDownLatch(1); new Thread(() -> { - Try.trying(latch::await).biMapL(AssertionError::new) - .orThrow(); + trying(checked(latch::await)).orThrow(); testThread.interrupt(); }) {{ start(); From f240f84ed122852ede134975c7857b92b8917006 Mon Sep 17 00:00:00 2001 From: jnape Date: Sun, 5 May 2019 21:35:59 -0500 Subject: [PATCH 34/69] Try#orThrow can declare checked exceptions for catching purposes --- CHANGELOG.md | 5 +++-- .../java/com/jnape/palatable/lambda/adt/Try.java | 2 +- .../com/jnape/palatable/lambda/adt/TryTest.java | 14 ++++++++++++++ 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cda581167..834bb104f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,8 +14,9 @@ might need to be reworked, and subtyping is obviously no longer supported. - ***Breaking Change***: `Strong` is now called `Cartesian` to better reflect the type of strength - ***Breaking Change***: new Optic type hierarchy more faithfully encodes profunctor constraints on optics, new `Optic` type is now the supertype of `Lens` and `Iso`, and `lens` package has been moved to `optics` -- ***Breaking Change***: Try and Either no longer preserve `Throwable` type since it was inherently not type-safe - anyway; Try is therefore no longer a `Bifunctor` +- ***Breaking Change***: `Try` and `Either` no longer preserve `Throwable` type since it was inherently not type-safe + anyway; Try is therefore no longer a `Bifunctor`, and `orThrow` can be used to declare checked + exceptions that could be caught by corresponding catch blocks - `IO` is now stack-safe, regardless of whether the composition nests linearly or recursively ### Added diff --git a/src/main/java/com/jnape/palatable/lambda/adt/Try.java b/src/main/java/com/jnape/palatable/lambda/adt/Try.java index fddedbb37..165c6333c 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/Try.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/Try.java @@ -108,7 +108,7 @@ public final Throwable forfeit(Function fn) { * * @return possibly the success value */ - public abstract A orThrow(); + public abstract A orThrow() throws T; /** * If this is a success, wrap the value in a {@link Maybe#just} and return it. Otherwise, return {@link diff --git a/src/test/java/com/jnape/palatable/lambda/adt/TryTest.java b/src/test/java/com/jnape/palatable/lambda/adt/TryTest.java index aca7d039d..77425e391 100644 --- a/src/test/java/com/jnape/palatable/lambda/adt/TryTest.java +++ b/src/test/java/com/jnape/palatable/lambda/adt/TryTest.java @@ -36,6 +36,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import static testsupport.matchers.LeftMatcher.isLeftThat; @RunWith(Traits.class) @@ -219,4 +220,17 @@ public void lazyZip() { throw new AssertionError(); })).value()); } + + @Test + public void orThrowCanStillThrowCheckedExceptions() { + try { + Try.trying(() -> { + throw new RuntimeException(); + }).orThrow(); + fail("Expected RuntimeException to be thrown, but nothing was"); + } catch (IOException ioException) { + fail("Expected thrown exception to not be IOException, but merely proving it can still be caught"); + } catch (Exception expected) { + } + } } \ No newline at end of file From 91d414a667c4fabc726d4aaefac2fa12110b859b Mon Sep 17 00:00:00 2001 From: jnape Date: Mon, 6 May 2019 18:50:38 -0500 Subject: [PATCH 35/69] Adding checkedApply to all function variants to support implicit throws --- CHANGELOG.md | 5 +++- .../jnape/palatable/lambda/adt/Either.java | 4 +-- .../com/jnape/palatable/lambda/adt/Try.java | 8 ++++-- .../palatable/lambda/functions/Effect.java | 17 +++++++++++ .../jnape/palatable/lambda/functions/Fn0.java | 18 ++++++++---- .../jnape/palatable/lambda/functions/Fn1.java | 19 +++++++++++-- .../jnape/palatable/lambda/functions/Fn2.java | 19 ++++++++++++- .../jnape/palatable/lambda/functions/Fn3.java | 19 ++++++++++++- .../jnape/palatable/lambda/functions/Fn4.java | 19 ++++++++++++- .../jnape/palatable/lambda/functions/Fn5.java | 20 ++++++++++++- .../jnape/palatable/lambda/functions/Fn6.java | 20 ++++++++++++- .../jnape/palatable/lambda/functions/Fn7.java | 19 ++++++++++++- .../jnape/palatable/lambda/functions/Fn8.java | 19 ++++++++++++- .../functions/builtin/fn1/CatMaybes.java | 2 +- .../functions/builtin/fn1/Coalesce.java | 2 +- .../functions/builtin/fn1/Constantly.java | 2 +- .../lambda/functions/builtin/fn1/Cycle.java | 2 +- .../functions/builtin/fn1/Distinct.java | 2 +- .../functions/builtin/fn1/Downcast.java | 2 +- .../lambda/functions/builtin/fn1/Empty.java | 2 +- .../lambda/functions/builtin/fn1/Flatten.java | 2 +- .../lambda/functions/builtin/fn1/Force.java | 2 +- .../lambda/functions/builtin/fn1/Head.java | 2 +- .../lambda/functions/builtin/fn1/Id.java | 2 +- .../lambda/functions/builtin/fn1/Init.java | 2 +- .../lambda/functions/builtin/fn1/Inits.java | 2 +- .../lambda/functions/builtin/fn1/Last.java | 2 +- .../functions/builtin/fn1/Magnetize.java | 2 +- .../lambda/functions/builtin/fn1/Not.java | 2 +- .../functions/builtin/fn1/Occurrences.java | 2 +- .../lambda/functions/builtin/fn1/Repeat.java | 2 +- .../lambda/functions/builtin/fn1/Reverse.java | 2 +- .../lambda/functions/builtin/fn1/Size.java | 2 +- .../lambda/functions/builtin/fn1/Sort.java | 2 +- .../lambda/functions/builtin/fn1/Tail.java | 2 +- .../lambda/functions/builtin/fn1/Tails.java | 2 +- .../lambda/functions/builtin/fn1/Uncons.java | 2 +- .../lambda/functions/builtin/fn1/Upcast.java | 2 +- .../lambda/functions/builtin/fn2/All.java | 2 +- .../lambda/functions/builtin/fn2/Alter.java | 2 +- .../lambda/functions/builtin/fn2/Any.java | 2 +- .../lambda/functions/builtin/fn2/Both.java | 8 +++--- .../builtin/fn2/CartesianProduct.java | 4 +-- .../lambda/functions/builtin/fn2/CmpEq.java | 2 +- .../lambda/functions/builtin/fn2/Cons.java | 2 +- .../functions/builtin/fn2/Difference.java | 2 +- .../lambda/functions/builtin/fn2/Drop.java | 2 +- .../functions/builtin/fn2/DropWhile.java | 2 +- .../lambda/functions/builtin/fn2/Eq.java | 2 +- .../lambda/functions/builtin/fn2/Filter.java | 2 +- .../lambda/functions/builtin/fn2/Find.java | 2 +- .../lambda/functions/builtin/fn2/GT.java | 2 +- .../lambda/functions/builtin/fn2/GTE.java | 2 +- .../lambda/functions/builtin/fn2/GroupBy.java | 4 +-- .../functions/builtin/fn2/InGroupsOf.java | 2 +- .../functions/builtin/fn2/Intersection.java | 2 +- .../functions/builtin/fn2/Intersperse.java | 2 +- .../lambda/functions/builtin/fn2/Into.java | 4 +-- .../lambda/functions/builtin/fn2/Into1.java | 4 +-- .../lambda/functions/builtin/fn2/Into3.java | 4 +-- .../lambda/functions/builtin/fn2/Into4.java | 5 ++-- .../lambda/functions/builtin/fn2/Into5.java | 6 ++-- .../lambda/functions/builtin/fn2/Into6.java | 6 ++-- .../lambda/functions/builtin/fn2/Into7.java | 7 +++-- .../lambda/functions/builtin/fn2/Into8.java | 2 +- .../lambda/functions/builtin/fn2/Iterate.java | 2 +- .../lambda/functions/builtin/fn2/LT.java | 2 +- .../lambda/functions/builtin/fn2/LTE.java | 2 +- .../lambda/functions/builtin/fn2/LazyRec.java | 2 +- .../functions/builtin/fn2/MagnetizeBy.java | 3 +- .../lambda/functions/builtin/fn2/Map.java | 2 +- .../functions/builtin/fn2/Partial2.java | 4 +-- .../functions/builtin/fn2/Partial3.java | 4 +-- .../functions/builtin/fn2/Partition.java | 6 ++-- .../lambda/functions/builtin/fn2/Peek.java | 4 +-- .../lambda/functions/builtin/fn2/Peek2.java | 2 +- .../functions/builtin/fn2/PrependAll.java | 2 +- .../functions/builtin/fn2/ReduceLeft.java | 2 +- .../functions/builtin/fn2/ReduceRight.java | 2 +- .../functions/builtin/fn2/Replicate.java | 2 +- .../functions/builtin/fn2/Sequence.java | 2 +- .../lambda/functions/builtin/fn2/Slide.java | 2 +- .../lambda/functions/builtin/fn2/Snoc.java | 2 +- .../lambda/functions/builtin/fn2/SortBy.java | 4 +-- .../functions/builtin/fn2/SortWith.java | 2 +- .../lambda/functions/builtin/fn2/Span.java | 3 +- .../lambda/functions/builtin/fn2/Take.java | 2 +- .../functions/builtin/fn2/TakeWhile.java | 2 +- .../lambda/functions/builtin/fn2/ToArray.java | 2 +- .../functions/builtin/fn2/ToCollection.java | 2 +- .../lambda/functions/builtin/fn2/ToMap.java | 2 +- .../lambda/functions/builtin/fn2/Tupler2.java | 2 +- .../lambda/functions/builtin/fn2/Unfoldr.java | 2 +- .../lambda/functions/builtin/fn2/Zip.java | 2 +- .../lambda/functions/builtin/fn3/Between.java | 2 +- .../lambda/functions/builtin/fn3/Clamp.java | 2 +- .../lambda/functions/builtin/fn3/CmpEqBy.java | 2 +- .../functions/builtin/fn3/FoldLeft.java | 2 +- .../functions/builtin/fn3/FoldRight.java | 3 +- .../lambda/functions/builtin/fn3/GTBy.java | 4 +-- .../lambda/functions/builtin/fn3/GTEBy.java | 2 +- .../lambda/functions/builtin/fn3/LTBy.java | 2 +- .../lambda/functions/builtin/fn3/LTEBy.java | 2 +- .../lambda/functions/builtin/fn3/LiftA2.java | 2 +- .../functions/builtin/fn3/ScanLeft.java | 2 +- .../lambda/functions/builtin/fn3/Times.java | 2 +- .../lambda/functions/builtin/fn3/ZipWith.java | 3 +- .../functions/builtin/fn4/IfThenElse.java | 4 +-- .../lambda/functions/builtin/fn4/LiftA3.java | 2 +- .../functions/builtin/fn4/RateLimit.java | 2 +- .../lambda/functions/builtin/fn5/LiftA4.java | 2 +- .../lambda/functions/builtin/fn6/LiftA5.java | 2 +- .../lambda/functions/builtin/fn7/LiftA6.java | 4 +-- .../lambda/functions/builtin/fn8/LiftA7.java | 4 +-- .../functions/recursion/Trampoline.java | 2 +- .../specialized/BiMonoidFactory.java | 23 ++++++++++++--- .../specialized/BiSemigroupFactory.java | 17 +++++++---- .../functions/specialized/MonoidFactory.java | 12 +++++++- .../lambda/functions/specialized/Noop.java | 2 +- .../lambda/functions/specialized/Pure.java | 12 +++++++- .../specialized/SemigroupFactory.java | 11 ++++++-- .../specialized/checked/CheckedEffect.java | 22 +++++---------- .../specialized/checked/CheckedFn1.java | 28 +++++++------------ .../jnape/palatable/lambda/monoid/Monoid.java | 4 +-- .../lambda/monoid/builtin/AddAll.java | 6 ++-- .../palatable/lambda/monoid/builtin/And.java | 2 +- .../lambda/monoid/builtin/Collapse.java | 7 +++-- .../lambda/monoid/builtin/Compose.java | 2 +- .../lambda/monoid/builtin/Concat.java | 2 +- .../palatable/lambda/monoid/builtin/Endo.java | 10 +++---- .../lambda/monoid/builtin/First.java | 2 +- .../palatable/lambda/monoid/builtin/Join.java | 2 +- .../palatable/lambda/monoid/builtin/Last.java | 2 +- .../lambda/monoid/builtin/LeftAll.java | 2 +- .../lambda/monoid/builtin/LeftAny.java | 4 +-- .../lambda/monoid/builtin/Merge.java | 4 +-- .../lambda/monoid/builtin/MergeMaps.java | 2 +- .../palatable/lambda/monoid/builtin/Or.java | 4 +-- .../lambda/monoid/builtin/Present.java | 2 +- .../lambda/monoid/builtin/PutAll.java | 2 +- .../lambda/monoid/builtin/RightAll.java | 2 +- .../lambda/monoid/builtin/RightAny.java | 4 +-- .../lambda/monoid/builtin/RunAll.java | 4 +-- .../lambda/monoid/builtin/Union.java | 2 +- .../palatable/lambda/monoid/builtin/Xor.java | 2 +- .../lambda/optics/functions/Matching.java | 2 +- .../lambda/optics/functions/Over.java | 6 ++-- .../lambda/optics/functions/Pre.java | 4 +-- .../palatable/lambda/optics/functions/Re.java | 2 +- .../lambda/optics/functions/Set.java | 2 +- .../lambda/optics/functions/Under.java | 6 ++-- .../lambda/optics/functions/View.java | 2 +- .../lambda/semigroup/builtin/Absent.java | 2 +- .../lambda/semigroup/builtin/Collapse.java | 4 +-- .../lambda/semigroup/builtin/Compose.java | 2 +- .../lambda/semigroup/builtin/LeftAll.java | 4 +-- .../lambda/semigroup/builtin/LeftAny.java | 2 +- .../lambda/semigroup/builtin/Max.java | 2 +- .../lambda/semigroup/builtin/MaxBy.java | 4 +-- .../lambda/semigroup/builtin/Merge.java | 2 +- .../lambda/semigroup/builtin/Min.java | 2 +- .../lambda/semigroup/builtin/MinBy.java | 4 +-- .../lambda/semigroup/builtin/RightAll.java | 4 +-- .../lambda/semigroup/builtin/RightAny.java | 4 +-- .../lambda/semigroup/builtin/RunAll.java | 4 +-- .../lambda/functions/EffectTest.java | 10 +++---- .../lambda/functor/builtin/LazyTest.java | 2 +- .../com/jnape/palatable/lambda/io/IOTest.java | 4 +-- 168 files changed, 473 insertions(+), 273 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 834bb104f..eb5b0499e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,10 @@ might need to be reworked, and subtyping is obviously no longer supported. type is now the supertype of `Lens` and `Iso`, and `lens` package has been moved to `optics` - ***Breaking Change***: `Try` and `Either` no longer preserve `Throwable` type since it was inherently not type-safe anyway; Try is therefore no longer a `Bifunctor`, and `orThrow` can be used to declare checked - exceptions that could be caught by corresponding catch blocks + exceptions that could be caught by corresponding catch blocks +- ***Breaking Change***: All `Fn*` types target methods now support throwing `Throwable`; `apply` is now defaulted and + will simply bypass javac to throw checked exceptions as if they were unchecked. This allows all + checked variants to be eliminated - `IO` is now stack-safe, regardless of whether the composition nests linearly or recursively ### Added diff --git a/src/main/java/com/jnape/palatable/lambda/adt/Either.java b/src/main/java/com/jnape/palatable/lambda/adt/Either.java index bda1b4fa2..e248eef92 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/Either.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/Either.java @@ -2,9 +2,9 @@ import com.jnape.palatable.lambda.adt.choice.Choice3; import com.jnape.palatable.lambda.adt.coproduct.CoProduct2; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functions.builtin.fn2.Peek; import com.jnape.palatable.lambda.functions.builtin.fn2.Peek2; -import com.jnape.palatable.lambda.functions.specialized.checked.CheckedFn1; import com.jnape.palatable.lambda.functions.specialized.checked.CheckedRunnable; import com.jnape.palatable.lambda.functions.specialized.checked.CheckedSupplier; import com.jnape.palatable.lambda.functor.Applicative; @@ -83,7 +83,7 @@ public final L forfeit(Function forfeitFn) { * @throws T the result of applying the wrapped left value to throwableFn, if this is a left */ public final R orThrow(Function throwableFn) throws T { - return match((CheckedFn1) l -> { + return match((Fn1) l -> { throw throwableFn.apply(l); }, id()); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/Try.java b/src/main/java/com/jnape/palatable/lambda/adt/Try.java index 165c6333c..fe1581307 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/Try.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/Try.java @@ -292,7 +292,7 @@ public static Try trying(CheckedRunnable runnable) { @SuppressWarnings("try") public static Try withResources( CheckedSupplier aSupplier, - CheckedFn1> fn) { + CheckedFn1> fn) { return trying(() -> { try (A resource = aSupplier.get()) { return fn.apply(resource).fmap(upcast()); @@ -316,7 +316,8 @@ public static Try withR CheckedSupplier aSupplier, CheckedFn1 bFn, CheckedFn1> fn) { - return withResources(aSupplier, a -> withResources(() -> bFn.apply(a), fn::apply)); + CheckedFn1> checkedFn = a -> withResources(() -> bFn.apply(a), fn::apply); + return withResources(aSupplier, checkedFn); } /** @@ -339,7 +340,8 @@ public static bFn, CheckedFn1 cFn, CheckedFn1> fn) { - return withResources(aSupplier, bFn, b -> withResources(() -> cFn.apply(b), fn::apply)); + CheckedFn1> checkedFn = b -> withResources(() -> cFn.apply(b), fn::apply); + return withResources(aSupplier, bFn, checkedFn); } private static final class Failure extends Try { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Effect.java b/src/main/java/com/jnape/palatable/lambda/functions/Effect.java index 0074cdd42..3115bef10 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Effect.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Effect.java @@ -1,6 +1,7 @@ package com.jnape.palatable.lambda.functions; import com.jnape.palatable.lambda.adt.Unit; +import com.jnape.palatable.lambda.functions.specialized.checked.Runtime; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.io.IO; @@ -20,11 +21,27 @@ @FunctionalInterface public interface Effect extends Fn1>, Consumer { + void checkedAccept(A a) throws Throwable; + + @Override + default void accept(A a) { + try { + checkedAccept(a); + } catch (Throwable t) { + throw Runtime.throwChecked(t); + } + } + @Override default IO apply(A a) { return io(() -> accept(a)); } + @Override + default IO checkedApply(A a) throws Throwable { + return io(() -> accept(a)); + } + @Override default Effect diMapL(Function fn) { return effect(Fn1.super.diMapL(fn)); diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn0.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn0.java index a1c67f5cc..902bcd940 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Fn0.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn0.java @@ -21,17 +21,23 @@ @FunctionalInterface public interface Fn0 extends Fn1, Supplier, Callable { - A apply(); + A checkedApply() throws Throwable; /** - * Invoke this function with {@link Unit}. + * Convenience method for applying this {@link Fn0} without providing an explicit {@link Unit}. * - * @param unit the only allowed input - * @return the result value + * @return the result + */ + default A apply() { + return apply(UNIT); + } + + /** + * {@inheritDoc} */ @Override - default A apply(Unit unit) { - return apply(); + default A checkedApply(Unit unit) throws Throwable { + return checkedApply(); } @Override diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java index 566ac93db..8704f92f4 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java @@ -3,6 +3,7 @@ import com.jnape.palatable.lambda.adt.Either; import com.jnape.palatable.lambda.adt.choice.Choice2; import com.jnape.palatable.lambda.adt.hlist.Tuple2; +import com.jnape.palatable.lambda.functions.specialized.checked.Runtime; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Cartesian; import com.jnape.palatable.lambda.functor.Cocartesian; @@ -30,12 +31,26 @@ public interface Fn1 extends Function { /** - * Invoke this function with the given argument. + * Invoke this function explosively with the given argument. * * @param a the argument * @return the result of the function application */ - B apply(A a); + default B apply(A a) { + try { + return checkedApply(a); + } catch (Throwable t) { + throw Runtime.throwChecked(t); + } + } + + /** + * Invoke this function with the given argument, potentially throwing any {@link Throwable}. + * + * @param a the argument + * @return the result of the function application + */ + B checkedApply(A a) throws Throwable; /** * Convert this {@link Fn1} to an {@link Fn0} by supplying an argument to this function. Useful for fixing an diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn2.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn2.java index 1386ae11e..cbe3a0929 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Fn2.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn2.java @@ -1,6 +1,7 @@ package com.jnape.palatable.lambda.functions; import com.jnape.palatable.lambda.adt.product.Product2; +import com.jnape.palatable.lambda.functions.specialized.checked.Runtime; import com.jnape.palatable.lambda.functor.Applicative; import java.util.function.BiFunction; @@ -23,6 +24,8 @@ @FunctionalInterface public interface Fn2 extends Fn1> { + C checkedApply(A a, B b) throws Throwable; + /** * Invoke this function with the given arguments. * @@ -30,7 +33,21 @@ public interface Fn2 extends Fn1> { * @param b the second argument * @return the result of the function application */ - C apply(A a, B b); + default C apply(A a, B b) { + try { + return checkedApply(a, b); + } catch (Throwable t) { + throw Runtime.throwChecked(t); + } + } + + /** + * {@inheritDoc} + */ + @Override + default Fn1 checkedApply(A a) throws Throwable { + return b -> checkedApply(a, b); + } /** * {@inheritDoc} diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn3.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn3.java index 9178520dc..84b46a1ae 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Fn3.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn3.java @@ -1,6 +1,7 @@ package com.jnape.palatable.lambda.functions; import com.jnape.palatable.lambda.adt.product.Product2; +import com.jnape.palatable.lambda.functions.specialized.checked.Runtime; import com.jnape.palatable.lambda.functor.Applicative; import java.util.function.BiFunction; @@ -21,6 +22,8 @@ @FunctionalInterface public interface Fn3 extends Fn2> { + D checkedApply(A a, B b, C c) throws Throwable; + /** * Invoke this function with the given arguments. * @@ -29,7 +32,21 @@ public interface Fn3 extends Fn2> { * @param c the third argument * @return the result of the function application */ - D apply(A a, B b, C c); + default D apply(A a, B b, C c) { + try { + return checkedApply(a, b, c); + } catch (Throwable t) { + throw Runtime.throwChecked(t); + } + } + + /** + * {@inheritDoc} + */ + @Override + default Fn1 checkedApply(A a, B b) throws Throwable { + return c -> checkedApply(a, b, c); + } /** * {@inheritDoc} diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn4.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn4.java index 4f9ea02de..e38856550 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Fn4.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn4.java @@ -1,6 +1,7 @@ package com.jnape.palatable.lambda.functions; import com.jnape.palatable.lambda.adt.product.Product2; +import com.jnape.palatable.lambda.functions.specialized.checked.Runtime; import com.jnape.palatable.lambda.functor.Applicative; import java.util.function.BiFunction; @@ -22,6 +23,8 @@ @FunctionalInterface public interface Fn4 extends Fn3> { + E checkedApply(A a, B b, C c, D d) throws Throwable; + /** * Invoke this function with the given arguments. * @@ -31,7 +34,21 @@ public interface Fn4 extends Fn3> { * @param d the fourth argument * @return the result of the function application */ - E apply(A a, B b, C c, D d); + default E apply(A a, B b, C c, D d) { + try { + return checkedApply(a, b, c, d); + } catch (Throwable t) { + throw Runtime.throwChecked(t); + } + } + + /** + * {@inheritDoc} + */ + @Override + default Fn1 checkedApply(A a, B b, C c) throws Throwable { + return d -> checkedApply(a, b, c, d); + } /** * {@inheritDoc} diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn5.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn5.java index f37f664e0..16bc6efa2 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Fn5.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn5.java @@ -1,6 +1,7 @@ package com.jnape.palatable.lambda.functions; import com.jnape.palatable.lambda.adt.product.Product2; +import com.jnape.palatable.lambda.functions.specialized.checked.Runtime; import com.jnape.palatable.lambda.functor.Applicative; import java.util.function.BiFunction; @@ -23,6 +24,8 @@ @FunctionalInterface public interface Fn5 extends Fn4> { + F checkedApply(A a, B b, C c, D d, E e) throws Throwable; + /** * Invoke this function with the given arguments. * @@ -33,7 +36,22 @@ public interface Fn5 extends Fn4> { * @param e the fifth argument * @return the result of the function application */ - F apply(A a, B b, C c, D d, E e); + default F apply(A a, B b, C c, D d, E e) { + try { + return checkedApply(a, b, c, d, e); + } catch (Throwable t) { + throw Runtime.throwChecked(t); + } + + } + + /** + * {@inheritDoc} + */ + @Override + default Fn1 checkedApply(A a, B b, C c, D d) throws Throwable { + return e -> checkedApply(a, b, c, d, e); + } /** * {@inheritDoc} diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn6.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn6.java index 69c6619cb..62917ce3a 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Fn6.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn6.java @@ -1,6 +1,7 @@ package com.jnape.palatable.lambda.functions; import com.jnape.palatable.lambda.adt.product.Product2; +import com.jnape.palatable.lambda.functions.specialized.checked.Runtime; import com.jnape.palatable.lambda.functor.Applicative; import java.util.function.BiFunction; @@ -24,6 +25,8 @@ @FunctionalInterface public interface Fn6 extends Fn5> { + G checkedApply(A a, B b, C c, D d, E e, F f) throws Throwable; + /** * Invoke this function with the given arguments. * @@ -35,7 +38,22 @@ public interface Fn6 extends Fn5> * @param f the sixth argument * @return the result of the function application */ - G apply(A a, B b, C c, D d, E e, F f); + default G apply(A a, B b, C c, D d, E e, F f) { + try { + return checkedApply(a, b, c, d, e, f); + } catch (Throwable t) { + throw Runtime.throwChecked(t); + } + + } + + /** + * {@inheritDoc} + */ + @Override + default Fn1 checkedApply(A a, B b, C c, D d, E e) throws Throwable { + return f -> checkedApply(a, b, c, d, e, f); + } /** * {@inheritDoc} diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn7.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn7.java index 90feae545..2e18bef97 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Fn7.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn7.java @@ -1,6 +1,7 @@ package com.jnape.palatable.lambda.functions; import com.jnape.palatable.lambda.adt.product.Product2; +import com.jnape.palatable.lambda.functions.specialized.checked.Runtime; import com.jnape.palatable.lambda.functor.Applicative; import java.util.function.BiFunction; @@ -25,6 +26,8 @@ @FunctionalInterface public interface Fn7 extends Fn6> { + H checkedApply(A a, B b, C c, D d, E e, F f, G g) throws Throwable; + /** * Invoke this function with the given arguments. * @@ -37,7 +40,21 @@ public interface Fn7 extends Fn6 checkedApply(A a, B b, C c, D d, E e, F f) throws Throwable { + return g -> checkedApply(a, b, c, d, e, f, g); + } /** * {@inheritDoc} diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn8.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn8.java index 9d5020687..07e8fb165 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Fn8.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn8.java @@ -1,6 +1,7 @@ package com.jnape.palatable.lambda.functions; import com.jnape.palatable.lambda.adt.product.Product2; +import com.jnape.palatable.lambda.functions.specialized.checked.Runtime; import com.jnape.palatable.lambda.functor.Applicative; import java.util.function.BiFunction; @@ -23,6 +24,8 @@ @FunctionalInterface public interface Fn8 extends Fn7> { + I checkedApply(A a, B b, C c, D d, E e, F f, G g, H h) throws Throwable; + /** * Invoke this function with the given arguments. * @@ -36,7 +39,21 @@ public interface Fn8 extends Fn7 checkedApply(A a, B b, C c, D d, E e, F f, G g) throws Throwable { + return h -> checkedApply(a, b, c, d, e, f, g, h); + } /** * Partially apply this function by taking its first argument. diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/CatMaybes.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/CatMaybes.java index d74111ba3..9833e2a32 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/CatMaybes.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/CatMaybes.java @@ -21,7 +21,7 @@ private CatMaybes() { } @Override - public Iterable apply(Iterable> maybes) { + public Iterable checkedApply(Iterable> maybes) { return flatten(map(m -> m.>fmap(Collections::singletonList) .orElse(Collections::emptyIterator), maybes)); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Coalesce.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Coalesce.java index ce9147028..3154e07ea 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Coalesce.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Coalesce.java @@ -31,7 +31,7 @@ private Coalesce() { } @Override - public Either, Iterable> apply(Iterable> eithers) { + public Either, Iterable> checkedApply(Iterable> eithers) { return foldLeft((acc, e) -> acc .biMapL(ls -> e.match(Snoc.snoc().flip().apply(ls), constantly(ls))) .flatMap(rs -> e.biMap(Collections::singletonList, diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Constantly.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Constantly.java index ed4d367b0..252eb53df 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Constantly.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Constantly.java @@ -17,7 +17,7 @@ private Constantly() { } @Override - public A apply(A a, B b) { + public A checkedApply(A a, B b) { return a; } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Cycle.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Cycle.java index df61e9fa0..2c39f4391 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Cycle.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Cycle.java @@ -19,7 +19,7 @@ private Cycle() { } @Override - public Iterable apply(Iterable as) { + public Iterable checkedApply(Iterable as) { return new CyclicIterable<>(as); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Distinct.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Distinct.java index 949c2c91e..aab8dfdb3 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Distinct.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Distinct.java @@ -15,7 +15,7 @@ private Distinct() { } @Override - public Iterable apply(Iterable as) { + public Iterable checkedApply(Iterable as) { return new DistinctIterable<>(as); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Downcast.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Downcast.java index c7efde762..d9c0c3985 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Downcast.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Downcast.java @@ -17,7 +17,7 @@ private Downcast() { @Override @SuppressWarnings("unchecked") - public A apply(B b) { + public A checkedApply(B b) { return (A) b; } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Empty.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Empty.java index b8b0f656b..dca2ebe09 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Empty.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Empty.java @@ -15,7 +15,7 @@ private Empty() { } @Override - public Boolean apply(Iterable as) { + public Boolean checkedApply(Iterable as) { return !as.iterator().hasNext(); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Flatten.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Flatten.java index ba05c771d..c1f8c0f6d 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Flatten.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Flatten.java @@ -16,7 +16,7 @@ private Flatten() { } @Override - public Iterable apply(Iterable> iterables) { + public Iterable checkedApply(Iterable> iterables) { return () -> new FlatteningIterator<>(iterables.iterator()); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Force.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Force.java index 84852199a..a198fc9ff 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Force.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Force.java @@ -17,7 +17,7 @@ private Force() { @Override @SuppressWarnings("StatementWithEmptyBody") - public Iterable apply(Iterable as) { + public Iterable checkedApply(Iterable as) { for (A ignored : as) { } return as; diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Head.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Head.java index e6b2457e4..a7c2c16fd 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Head.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Head.java @@ -22,7 +22,7 @@ private Head() { } @Override - public Maybe apply(Iterable as) { + public Maybe checkedApply(Iterable as) { Iterator iterator = as.iterator(); return iterator.hasNext() ? just(iterator.next()) : nothing(); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Id.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Id.java index 62a5871ea..c2f8c06ee 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Id.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Id.java @@ -15,7 +15,7 @@ private Id() { } @Override - public A apply(A a) { + public A checkedApply(A a) { return a; } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Init.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Init.java index 2162e65ee..bb75ad1b1 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Init.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Init.java @@ -17,7 +17,7 @@ private Init() { } @Override - public Iterable apply(Iterable as) { + public Iterable checkedApply(Iterable as) { return () -> new InitIterator<>(as); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Inits.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Inits.java index cb6d7165c..e2b33f928 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Inits.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Inits.java @@ -25,7 +25,7 @@ private Inits() { } @Override - public Iterable> apply(Iterable as) { + public Iterable> checkedApply(Iterable as) { return scanLeft(Snoc.snoc().flip().toBiFunction(), Collections::emptyIterator, as); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Last.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Last.java index 9f49e95da..a71c1dda6 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Last.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Last.java @@ -19,7 +19,7 @@ private Last() { } @Override - public Maybe apply(Iterable as) { + public Maybe checkedApply(Iterable as) { A last = null; for (A a : as) { last = a; diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Magnetize.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Magnetize.java index b25e3e32a..b50429e51 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Magnetize.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Magnetize.java @@ -18,7 +18,7 @@ private Magnetize() { } @Override - public Iterable> apply(Iterable as) { + public Iterable> checkedApply(Iterable as) { return magnetizeBy(eq().toBiFunction(), as); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Not.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Not.java index a7b4956c6..74374b434 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Not.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Not.java @@ -17,7 +17,7 @@ private Not() { } @Override - public Boolean apply(Function pred, A a) { + public Boolean checkedApply(Function pred, A a) { return !pred.apply(a); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Occurrences.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Occurrences.java index af9e21f39..6fea549c8 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Occurrences.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Occurrences.java @@ -20,7 +20,7 @@ private Occurrences() { } @Override - public Map apply(Iterable as) { + public Map checkedApply(Iterable as) { return foldLeft((occurrences, a) -> { occurrences.put(a, occurrences.getOrDefault(a, 0L) + 1); return occurrences; diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Repeat.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Repeat.java index 68209c874..83c80e09a 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Repeat.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Repeat.java @@ -16,7 +16,7 @@ private Repeat() { } @Override - public Iterable apply(A a) { + public Iterable checkedApply(A a) { return () -> new RepetitiousIterator<>(a); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Reverse.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Reverse.java index 3913da8f0..eaeecc014 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Reverse.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Reverse.java @@ -17,7 +17,7 @@ private Reverse() { } @Override - public Iterable apply(Iterable as) { + public Iterable checkedApply(Iterable as) { return new ReversingIterable<>(as); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Size.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Size.java index 95dca3f36..061636248 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Size.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Size.java @@ -12,7 +12,7 @@ private Size() { } @Override - public Long apply(Iterable iterable) { + public Long checkedApply(Iterable iterable) { if (iterable instanceof Collection) return (long) ((Collection) iterable).size(); diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Sort.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Sort.java index 315b6780c..da00cfaaf 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Sort.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Sort.java @@ -25,7 +25,7 @@ private Sort() { } @Override - public List apply(Iterable as) { + public List checkedApply(Iterable as) { return sortBy(id(), as); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Tail.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Tail.java index 930b4be95..9f776ccf0 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Tail.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Tail.java @@ -18,7 +18,7 @@ private Tail() { } @Override - public Iterable apply(Iterable as) { + public Iterable checkedApply(Iterable as) { return drop(1, as); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Tails.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Tails.java index cffe390d3..7179d1f31 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Tails.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Tails.java @@ -28,7 +28,7 @@ private Tails() { } @Override - public Iterable> apply(Iterable as) { + public Iterable> checkedApply(Iterable as) { return snoc(emptyList(), zipWith((a, __) -> a, unfoldr(k -> just(tuple(drop(k, as), k + 1)), 0), as)); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Uncons.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Uncons.java index 27014940b..dc27d9bb3 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Uncons.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Uncons.java @@ -22,7 +22,7 @@ private Uncons() { } @Override - public Maybe>> apply(Iterable as) { + public Maybe>> checkedApply(Iterable as) { return head(as).fmap(a -> tuple(a, tail(as))); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Upcast.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Upcast.java index 89cfaa864..f4f187021 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Upcast.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Upcast.java @@ -28,7 +28,7 @@ private Upcast() { } @Override - public B apply(A a) { + public B checkedApply(A a) { return a; } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/All.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/All.java index 0019932b4..42a97c86f 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/All.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/All.java @@ -21,7 +21,7 @@ private All() { } @Override - public Boolean apply(Function predicate, Iterable as) { + public Boolean checkedApply(Function predicate, Iterable as) { for (A a : as) if (!predicate.apply(a)) return false; diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Alter.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Alter.java index b12160c1f..5eb0b2cc4 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Alter.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Alter.java @@ -21,7 +21,7 @@ private Alter() { } @Override - public IO apply(Effect effect, A a) { + public IO checkedApply(Effect effect, A a) { return effect.fmap(io -> io.fmap(constantly(a))).apply(a); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Any.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Any.java index eacb359b3..048b79cef 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Any.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Any.java @@ -21,7 +21,7 @@ private Any() { } @Override - public Boolean apply(Function predicate, Iterable as) { + public Boolean checkedApply(Function predicate, Iterable as) { for (A a : as) if (predicate.apply(a)) return true; diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Both.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Both.java index 0693437cd..fcd964c7c 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Both.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Both.java @@ -16,15 +16,15 @@ */ public final class Both implements Fn3, Function, A, Tuple2> { - private static final Both INSTANCE = new Both<>(); + private static final Both INSTANCE = new Both<>(); private Both() { } @Override - public Tuple2 apply(Function f, - Function g, - A a) { + public Tuple2 checkedApply(Function f, + Function g, + A a) { return Tuple2.fill(a).biMap(f, g); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/CartesianProduct.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/CartesianProduct.java index e6663cfe3..2ef85c703 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/CartesianProduct.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/CartesianProduct.java @@ -21,13 +21,13 @@ */ public final class CartesianProduct implements Fn2, Iterable, Iterable>> { - private static final CartesianProduct INSTANCE = new CartesianProduct<>(); + private static final CartesianProduct INSTANCE = new CartesianProduct<>(); private CartesianProduct() { } @Override - public Iterable> apply(Iterable as, Iterable bs) { + public Iterable> checkedApply(Iterable as, Iterable bs) { return () -> new CombinatorialIterator<>(as.iterator(), bs.iterator()); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/CmpEq.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/CmpEq.java index de9bd9e4e..3a91ade4c 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/CmpEq.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/CmpEq.java @@ -24,7 +24,7 @@ private CmpEq() { } @Override - public Boolean apply(A x, A y) { + public Boolean checkedApply(A x, A y) { return cmpEqBy(id(), x, y); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Cons.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Cons.java index c69d18ddd..7ad8405a0 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Cons.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Cons.java @@ -17,7 +17,7 @@ private Cons() { } @Override - public Iterable apply(A a, Iterable as) { + public Iterable checkedApply(A a, Iterable as) { return () -> new ConsingIterator<>(a, as); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Difference.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Difference.java index 384b62175..38735673c 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Difference.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Difference.java @@ -29,7 +29,7 @@ private Difference() { } @Override - public Iterable apply(Iterable xs, Iterable ys) { + public Iterable checkedApply(Iterable xs, Iterable ys) { return () -> { if (empty(xs)) return xs.iterator(); diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Drop.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Drop.java index 291324bdf..c975a0efb 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Drop.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Drop.java @@ -21,7 +21,7 @@ private Drop() { } @Override - public Iterable apply(Integer n, Iterable as) { + public Iterable checkedApply(Integer n, Iterable as) { return new DroppingIterable<>(n, as); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/DropWhile.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/DropWhile.java index edd8e45fb..3585ef135 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/DropWhile.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/DropWhile.java @@ -24,7 +24,7 @@ private DropWhile() { } @Override - public Iterable apply(Function predicate, Iterable as) { + public Iterable checkedApply(Function predicate, Iterable as) { return new PredicatedDroppingIterable<>(predicate, as); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Eq.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Eq.java index 126d26072..e4c5aeda1 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Eq.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Eq.java @@ -16,7 +16,7 @@ private Eq() { } @Override - public Boolean apply(A x, A y) { + public Boolean checkedApply(A x, A y) { return x == null ? y == null : x.equals(y); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Filter.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Filter.java index 8e208ac1b..f8954ae8e 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Filter.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Filter.java @@ -22,7 +22,7 @@ private Filter() { } @Override - public Iterable apply(Function predicate, Iterable as) { + public Iterable checkedApply(Function predicate, Iterable as) { return new FilteringIterable<>(predicate, as); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Find.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Find.java index 2ddf0c8be..5539d71fc 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Find.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Find.java @@ -26,7 +26,7 @@ private Find() { } @Override - public Maybe apply(Function predicate, Iterable as) { + public Maybe checkedApply(Function predicate, Iterable as) { return head(dropWhile(not(predicate), as)); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GT.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GT.java index 7d99e7bc1..09d1be4ae 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GT.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GT.java @@ -23,7 +23,7 @@ private GT() { } @Override - public Boolean apply(A y, A x) { + public Boolean checkedApply(A y, A x) { return gtBy(id(), y, x); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GTE.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GTE.java index 5304755de..89413cea6 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GTE.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GTE.java @@ -23,7 +23,7 @@ private GTE() { } @Override - public Boolean apply(A y, A x) { + public Boolean checkedApply(A y, A x) { return gteBy(id(), y, x); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GroupBy.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GroupBy.java index 1e85a30ab..9cbc91ee8 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GroupBy.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GroupBy.java @@ -22,13 +22,13 @@ */ public final class GroupBy implements Fn2, Iterable, Map>> { - private static final GroupBy INSTANCE = new GroupBy<>(); + private static final GroupBy INSTANCE = new GroupBy<>(); private GroupBy() { } @Override - public Map> apply(Function keyFn, Iterable vs) { + public Map> checkedApply(Function keyFn, Iterable vs) { return foldLeft((m, v) -> { m.computeIfAbsent(keyFn.apply(v), __ -> new ArrayList<>()).add(v); return m; diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/InGroupsOf.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/InGroupsOf.java index 410e5745c..5270cf60f 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/InGroupsOf.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/InGroupsOf.java @@ -20,7 +20,7 @@ private InGroupsOf() { } @Override - public Iterable> apply(Integer k, Iterable as) { + public Iterable> checkedApply(Integer k, Iterable as) { return () -> new GroupingIterator<>(k, as.iterator()); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Intersection.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Intersection.java index 1a061a471..e7965d9ae 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Intersection.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Intersection.java @@ -24,7 +24,7 @@ private Intersection() { } @Override - public Iterable apply(Iterable xs, Iterable ys) { + public Iterable checkedApply(Iterable xs, Iterable ys) { return filter(x -> find(eq(x), ys).fmap(constantly(true)).orElse(false), distinct(xs)); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Intersperse.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Intersperse.java index 27c5cf02e..4ff11cdec 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Intersperse.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Intersperse.java @@ -21,7 +21,7 @@ private Intersperse() { } @Override - public Iterable apply(A a, Iterable as) { + public Iterable checkedApply(A a, Iterable as) { return tail(prependAll(a, as)); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into.java index 75e7b4c24..cd5b061de 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into.java @@ -16,13 +16,13 @@ */ public final class Into implements Fn2, Map.Entry, C> { - private static final Into INSTANCE = new Into<>(); + private static final Into INSTANCE = new Into<>(); private Into() { } @Override - public C apply(BiFunction fn, Map.Entry entry) { + public C checkedApply(BiFunction fn, Map.Entry entry) { return fn.apply(entry.getKey(), entry.getValue()); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into1.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into1.java index a230d94b2..526fcb7e5 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into1.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into1.java @@ -15,10 +15,10 @@ */ public final class Into1 implements Fn2, SingletonHList, B> { - private static final Into1 INSTANCE = new Into1<>(); + private static final Into1 INSTANCE = new Into1<>(); @Override - public B apply(Function fn, SingletonHList singletonHList) { + public B checkedApply(Function fn, SingletonHList singletonHList) { return fn.apply(singletonHList.head()); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into3.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into3.java index f9ed9a6cc..05daec1ef 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into3.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into3.java @@ -16,10 +16,10 @@ */ public final class Into3 implements Fn2, Product3, D> { - private static final Into3 INSTANCE = new Into3<>(); + private static final Into3 INSTANCE = new Into3<>(); @Override - public D apply(Fn3 fn, Product3 product) { + public D checkedApply(Fn3 fn, Product3 product) { return product.into(fn); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into4.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into4.java index 3544516eb..14dba6f90 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into4.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into4.java @@ -17,10 +17,11 @@ */ public final class Into4 implements Fn2, Product4, E> { - private static final Into4 INSTANCE = new Into4<>(); + private static final Into4 INSTANCE = new Into4<>(); @Override - public E apply(Fn4 fn, Product4 product) { + public E checkedApply(Fn4 fn, + Product4 product) { return product.into(fn); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into5.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into5.java index e59852f62..8cbdf25f5 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into5.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into5.java @@ -18,11 +18,11 @@ */ public final class Into5 implements Fn2, Product5, F> { - private static final Into5 INSTANCE = new Into5<>(); + private static final Into5 INSTANCE = new Into5<>(); @Override - public F apply(Fn5 fn, - Product5 product) { + public F checkedApply(Fn5 fn, + Product5 product) { return product.into(fn); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into6.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into6.java index 1b4180688..0c59771f2 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into6.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into6.java @@ -20,11 +20,11 @@ */ public final class Into6 implements Fn2, Product6, G> { - private static final Into6 INSTANCE = new Into6<>(); + private static final Into6 INSTANCE = new Into6<>(); @Override - public G apply(Fn6 fn, - Product6 product) { + public G checkedApply(Fn6 fn, + Product6 product) { return product.into(fn); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into7.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into7.java index fe4b0d7e4..612068814 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into7.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into7.java @@ -21,11 +21,12 @@ */ public final class Into7 implements Fn2, Product7, H> { - private static final Into7 INSTANCE = new Into7<>(); + private static final Into7 INSTANCE = new Into7<>(); @Override - public H apply(Fn7 fn, - Product7 product) { + public H checkedApply( + Fn7 fn, + Product7 product) { return product.into(fn); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into8.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into8.java index d41c7ff75..fdad33a72 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into8.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into8.java @@ -25,7 +25,7 @@ public final class Into8 implements Fn2 INSTANCE = new Into8<>(); @Override - public I apply( + public I checkedApply( Fn8 fn, Product8 product) { return product.into(fn); diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Iterate.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Iterate.java index 596bea845..17a96235c 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Iterate.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Iterate.java @@ -24,7 +24,7 @@ private Iterate() { } @Override - public Iterable apply(Function fn, A seed) { + public Iterable checkedApply(Function fn, A seed) { return unfoldr(a -> just(tuple(a, fn.apply(a))), seed); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LT.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LT.java index b5ccf4e23..359d59b66 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LT.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LT.java @@ -23,7 +23,7 @@ private LT() { } @Override - public Boolean apply(A y, A x) { + public Boolean checkedApply(A y, A x) { return ltBy(id(), y, x); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LTE.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LTE.java index 4287229c2..85f07b61e 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LTE.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LTE.java @@ -23,7 +23,7 @@ private LTE() { } @Override - public Boolean apply(A y, A x) { + public Boolean checkedApply(A y, A x) { return lteBy(id(), y, x); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LazyRec.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LazyRec.java index 7b154b0ae..fe14186b7 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LazyRec.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LazyRec.java @@ -38,7 +38,7 @@ private LazyRec() { } @Override - public Lazy apply(BiFunction>, A, Lazy> fn, A a) { + public Lazy checkedApply(BiFunction>, A, Lazy> fn, A a) { return join(lazy(() -> fn.apply(nextA -> apply(fn, nextA), a))); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/MagnetizeBy.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/MagnetizeBy.java index 686c521b0..6456f62fb 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/MagnetizeBy.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/MagnetizeBy.java @@ -33,7 +33,8 @@ private MagnetizeBy() { } @Override - public Iterable> apply(BiFunction predicate, Iterable as) { + public Iterable> checkedApply(BiFunction predicate, + Iterable as) { return () -> uncons(as).fmap(into((A head, Iterable tail) -> { Iterable group = cons(head, unfoldr(into((pivot, ys) -> uncons(ys) .flatMap(into((y, recurse) -> predicate.apply(pivot, y) diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Map.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Map.java index bc0085cf7..35c771ea1 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Map.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Map.java @@ -21,7 +21,7 @@ private Map() { } @Override - public Iterable apply(Function fn, Iterable as) { + public Iterable checkedApply(Function fn, Iterable as) { return new MappingIterable<>(fn, as); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partial2.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partial2.java index 4a02e0ed5..8adb7e847 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partial2.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partial2.java @@ -16,13 +16,13 @@ */ public final class Partial2 implements Fn2, A, Fn1> { - private static final Partial2 INSTANCE = new Partial2<>(); + private static final Partial2 INSTANCE = new Partial2<>(); private Partial2() { } @Override - public Fn1 apply(BiFunction fn, A a) { + public Fn1 checkedApply(BiFunction fn, A a) { return b -> fn.apply(a, b); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partial3.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partial3.java index df9b804a5..151d8f20f 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partial3.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partial3.java @@ -16,13 +16,13 @@ */ public final class Partial3 implements Fn2, A, Fn2> { - private static final Partial3 INSTANCE = new Partial3<>(); + private static final Partial3 INSTANCE = new Partial3<>(); private Partial3() { } @Override - public Fn2 apply(Fn3 fn, A a) { + public Fn2 checkedApply(Fn3 fn, A a) { return fn.apply(a); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partition.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partition.java index 368dfb0bb..41acd66b9 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partition.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partition.java @@ -26,14 +26,14 @@ */ public final class Partition implements Fn2>, Iterable, Tuple2, Iterable>> { - private static final Partition INSTANCE = new Partition<>(); + private static final Partition INSTANCE = new Partition<>(); private Partition() { } @Override - public Tuple2, Iterable> apply(Function> function, - Iterable as) { + public Tuple2, Iterable> checkedApply(Function> function, + Iterable as) { return Tuple2.>>fill(map(function, as)) .biMap(Map., Iterable>map(cp -> cp.match(Collections::singleton, __ -> emptySet())), Map., Iterable>map(cp -> cp.match(__ -> emptySet(), Collections::singleton))) diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek.java index bd86c6856..c12c45d55 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek.java @@ -15,14 +15,14 @@ * @param the functor type */ public final class Peek> implements Fn2, FA, FA> { - private static final Peek INSTANCE = new Peek<>(); + private static final Peek INSTANCE = new Peek<>(); private Peek() { } @Override @SuppressWarnings("unchecked") - public FA apply(Consumer consumer, FA fa) { + public FA checkedApply(Consumer consumer, FA fa) { return (FA) fa.fmap(a -> { consumer.accept(a); return a; diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek2.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek2.java index e228293e5..f9d63e0b6 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek2.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek2.java @@ -26,7 +26,7 @@ private Peek2() { @Override @SuppressWarnings("unchecked") - public FAB apply(Consumer aConsumer, Consumer bConsumer, FAB fab) { + public FAB checkedApply(Consumer aConsumer, Consumer bConsumer, FAB fab) { return (FAB) fab.biMap(a -> { aConsumer.accept(a); return a; diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/PrependAll.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/PrependAll.java index 94ebd2c78..7b2ed2a64 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/PrependAll.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/PrependAll.java @@ -19,7 +19,7 @@ private PrependAll() { } @Override - public Iterable apply(A a, Iterable as) { + public Iterable checkedApply(A a, Iterable as) { return () -> new PrependingIterator<>(a, as.iterator()); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ReduceLeft.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ReduceLeft.java index 150206f61..d77872e71 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ReduceLeft.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ReduceLeft.java @@ -33,7 +33,7 @@ private ReduceLeft() { } @Override - public Maybe apply(BiFunction fn, Iterable as) { + public Maybe checkedApply(BiFunction fn, Iterable as) { Iterator iterator = as.iterator(); return !iterator.hasNext() ? nothing() : just(foldLeft(fn, iterator.next(), () -> iterator)); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ReduceRight.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ReduceRight.java index 14a39b20a..97ed627d5 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ReduceRight.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ReduceRight.java @@ -31,7 +31,7 @@ private ReduceRight() { } @Override - public final Maybe apply(BiFunction fn, Iterable as) { + public final Maybe checkedApply(BiFunction fn, Iterable as) { return reduceLeft((b, a) -> fn.apply(a, b), reverse(as)); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Replicate.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Replicate.java index c310ae8ec..98d436461 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Replicate.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Replicate.java @@ -19,7 +19,7 @@ private Replicate() { } @Override - public Iterable apply(Integer n, A a) { + public Iterable checkedApply(Integer n, A a) { return take(n, repeat(a)); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Sequence.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Sequence.java index fffe9b580..a00eaff48 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Sequence.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Sequence.java @@ -42,7 +42,7 @@ private Sequence() { } @Override - public AppTrav apply(TravApp traversable, Function pure) { + public AppTrav checkedApply(TravApp traversable, Function pure) { return traversable.traverse(id(), pure); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Slide.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Slide.java index caec56faa..1a65422d6 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Slide.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Slide.java @@ -27,7 +27,7 @@ private Slide() { } @Override - public Iterable> apply(Integer k, Iterable as) { + public Iterable> checkedApply(Integer k, Iterable as) { if (k == 0) throw new IllegalArgumentException("k must be greater than 0"); diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Snoc.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Snoc.java index dbf151ab5..67fe1a137 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Snoc.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Snoc.java @@ -21,7 +21,7 @@ private Snoc() { } @Override - public Iterable apply(A a, Iterable as) { + public Iterable checkedApply(A a, Iterable as) { return new SnocIterable<>(a, as); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/SortBy.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/SortBy.java index a5c52ed58..de3d55858 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/SortBy.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/SortBy.java @@ -22,13 +22,13 @@ */ public final class SortBy> implements Fn2, Iterable, List> { - private static final SortBy INSTANCE = new SortBy<>(); + private static final SortBy INSTANCE = new SortBy<>(); private SortBy() { } @Override - public List apply(Function fn, Iterable as) { + public List checkedApply(Function fn, Iterable as) { return sortWith(comparing(fn), as); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/SortWith.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/SortWith.java index 4062d3ebe..2c93239ee 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/SortWith.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/SortWith.java @@ -27,7 +27,7 @@ private SortWith() { } @Override - public List apply(Comparator comparator, Iterable as) { + public List checkedApply(Comparator comparator, Iterable as) { List result = toCollection(ArrayList::new, as); result.sort(comparator); return result; diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Span.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Span.java index 3450a9c49..d74702b35 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Span.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Span.java @@ -23,7 +23,8 @@ private Span() { } @Override - public Tuple2, Iterable> apply(Function predicate, Iterable as) { + public Tuple2, Iterable> checkedApply(Function predicate, + Iterable as) { return Tuple2.fill(as).biMap(takeWhile(predicate), dropWhile(predicate)); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Take.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Take.java index 86c417a6d..dbc55e349 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Take.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Take.java @@ -21,7 +21,7 @@ private Take() { } @Override - public Iterable apply(Integer n, Iterable as) { + public Iterable checkedApply(Integer n, Iterable as) { return new TakingIterable<>(n, as); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/TakeWhile.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/TakeWhile.java index 29863e2bc..098cd6a17 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/TakeWhile.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/TakeWhile.java @@ -23,7 +23,7 @@ private TakeWhile() { } @Override - public Iterable apply(Function predicate, Iterable as) { + public Iterable checkedApply(Function predicate, Iterable as) { return new PredicatedTakingIterable<>(predicate, as); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToArray.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToArray.java index 4b41af1b8..cecaa1543 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToArray.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToArray.java @@ -23,7 +23,7 @@ private ToArray() { @Override @SuppressWarnings("unchecked") - public A[] apply(Class arrayType, Iterable as) { + public A[] checkedApply(Class arrayType, Iterable as) { A[] array = (A[]) Array.newInstance(arrayType.getComponentType(), size(as).intValue()); if (as instanceof Collection) return ((Collection) as).toArray(array); diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToCollection.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToCollection.java index 545682fb6..3e2fb05e1 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToCollection.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToCollection.java @@ -22,7 +22,7 @@ private ToCollection() { } @Override - public C apply(Supplier cSupplier, Iterable as) { + public C checkedApply(Supplier cSupplier, Iterable as) { C c = cSupplier.get(); as.forEach(c::add); return c; diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToMap.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToMap.java index 2b21f5268..e674673fb 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToMap.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToMap.java @@ -25,7 +25,7 @@ private ToMap() { } @Override - public M apply(Supplier mSupplier, Iterable> entries) { + public M checkedApply(Supplier mSupplier, Iterable> entries) { return foldLeft((m, kv) -> { m.put(kv.getKey(), kv.getValue()); return m; diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Tupler2.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Tupler2.java index 6b69f4441..939518d38 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Tupler2.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Tupler2.java @@ -21,7 +21,7 @@ private Tupler2() { } @Override - public Tuple2 apply(A a, B b) { + public Tuple2 checkedApply(A a, B b) { return tuple(a, b); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Unfoldr.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Unfoldr.java index efb79a76c..e0c63eeb2 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Unfoldr.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Unfoldr.java @@ -37,7 +37,7 @@ private Unfoldr() { } @Override - public Iterable apply(Function>> fn, B b) { + public Iterable checkedApply(Function>> fn, B b) { return () -> new UnfoldingIterator<>(fn, b); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Zip.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Zip.java index 3e6ba39eb..8f896e14c 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Zip.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Zip.java @@ -23,7 +23,7 @@ private Zip() { } @Override - public Iterable> apply(Iterable as, Iterable bs) { + public Iterable> checkedApply(Iterable as, Iterable bs) { return zipWith(Tupler2.tupler().toBiFunction(), as, bs); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/Between.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/Between.java index 451addf5c..ccb98929f 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/Between.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/Between.java @@ -20,7 +20,7 @@ private Between() { } @Override - public Boolean apply(A lower, A upper, A a) { + public Boolean checkedApply(A lower, A upper, A a) { return clamp(lower, upper, a).equals(a); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/Clamp.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/Clamp.java index 20de04a77..3343afae4 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/Clamp.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/Clamp.java @@ -23,7 +23,7 @@ private Clamp() { } @Override - public A apply(A lower, A upper, A a) { + public A checkedApply(A lower, A upper, A a) { return max(min(lower, upper)).fmap(min(max(lower, upper))).apply(a); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/CmpEqBy.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/CmpEqBy.java index 5ef1382f7..db202c66a 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/CmpEqBy.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/CmpEqBy.java @@ -26,7 +26,7 @@ private CmpEqBy() { } @Override - public Boolean apply(Function compareFn, A x, A y) { + public Boolean checkedApply(Function compareFn, A x, A y) { return compareFn.apply(x).compareTo(compareFn.apply(y)) == 0; } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/FoldLeft.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/FoldLeft.java index ec0ad331e..d7f9a24e6 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/FoldLeft.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/FoldLeft.java @@ -28,7 +28,7 @@ private FoldLeft() { } @Override - public B apply(BiFunction fn, B acc, Iterable as) { + public B checkedApply(BiFunction fn, B acc, Iterable as) { B accumulation = acc; for (A a : as) accumulation = fn.apply(accumulation, a); diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/FoldRight.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/FoldRight.java index 8741aadba..4086204ed 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/FoldRight.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/FoldRight.java @@ -47,7 +47,8 @@ private FoldRight() { } @Override - public Lazy apply(BiFunction, ? extends Lazy> fn, Lazy acc, Iterable as) { + public Lazy checkedApply(BiFunction, ? extends Lazy> fn, Lazy acc, + Iterable as) { return lazyRec((f, lazyIt) -> lazyIt.flatMap(it -> it.hasNext() ? fn.apply(it.next(), f.apply(lazy(it))) : acc), diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/GTBy.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/GTBy.java index 6dc2ddef1..0a6bf807d 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/GTBy.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/GTBy.java @@ -19,13 +19,13 @@ */ public final class GTBy> implements Fn3, A, A, Boolean> { - private static final GTBy INSTANCE = new GTBy<>(); + private static final GTBy INSTANCE = new GTBy<>(); private GTBy() { } @Override - public Boolean apply(Function compareFn, A y, A x) { + public Boolean checkedApply(Function compareFn, A y, A x) { return compareFn.apply(x).compareTo(compareFn.apply(y)) > 0; } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/GTEBy.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/GTEBy.java index 830eacb69..6c956e366 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/GTEBy.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/GTEBy.java @@ -28,7 +28,7 @@ private GTEBy() { } @Override - public Boolean apply(Function compareFn, A y, A x) { + public Boolean checkedApply(Function compareFn, A y, A x) { return GTBy.gtBy(compareFn).or(cmpEqBy(compareFn)).apply(y, x); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LTBy.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LTBy.java index b09fb69a2..be547f38b 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LTBy.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LTBy.java @@ -25,7 +25,7 @@ private LTBy() { } @Override - public Boolean apply(Function compareFn, A y, A x) { + public Boolean checkedApply(Function compareFn, A y, A x) { return compareFn.apply(x).compareTo(compareFn.apply(y)) < 0; } 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 2eb29c7e1..2dda81ce4 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 @@ -28,7 +28,7 @@ private LTEBy() { } @Override - public Boolean apply(Function compareFn, A y, A x) { + public Boolean checkedApply(Function compareFn, A y, A x) { return LTBy.ltBy(compareFn).or(cmpEqBy(compareFn)).apply(y, x); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LiftA2.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LiftA2.java index 55d58fb6a..fbfc78c06 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LiftA2.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LiftA2.java @@ -32,7 +32,7 @@ private LiftA2() { } @Override - public AppC apply(BiFunction fn, AppA appA, AppB appB) { + public AppC checkedApply(BiFunction fn, AppA appA, AppB appB) { return appB.zip(appA.fmap(Fn2.fn2(fn))).coerce(); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/ScanLeft.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/ScanLeft.java index 400f1d267..f99e6ec8c 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/ScanLeft.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/ScanLeft.java @@ -26,7 +26,7 @@ private ScanLeft() { } @Override - public Iterable apply(BiFunction fn, B b, Iterable as) { + public Iterable checkedApply(BiFunction fn, B b, Iterable as) { return () -> new ScanningIterator<>(fn, b, as.iterator()); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/Times.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/Times.java index a12ab841f..10db14166 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/Times.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/Times.java @@ -28,7 +28,7 @@ private Times() { } @Override - public A apply(Integer n, Function fn, A a) { + public A checkedApply(Integer n, Function fn, A a) { if (n < 0) throw new IllegalStateException("n must not be less than 0"); diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/ZipWith.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/ZipWith.java index 4341ca32f..218b1db48 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/ZipWith.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/ZipWith.java @@ -25,7 +25,8 @@ private ZipWith() { } @Override - public Iterable apply(BiFunction zipper, Iterable as, Iterable bs) { + public Iterable checkedApply(BiFunction zipper, Iterable as, + Iterable bs) { return () -> new ZippingIterator<>(zipper, as.iterator(), bs.iterator()); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/IfThenElse.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/IfThenElse.java index 53d40315d..38f0bbe3e 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/IfThenElse.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/IfThenElse.java @@ -15,8 +15,8 @@ private IfThenElse() { } @Override - public B apply(Function predicate, Function thenCase, - Function elseCase, A a) { + public B checkedApply(Function predicate, Function thenCase, + Function elseCase, A a) { return predicate.apply(a) ? thenCase.apply(a) : elseCase.apply(a); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/LiftA3.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/LiftA3.java index 43c9bc018..b8ccd2527 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/LiftA3.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/LiftA3.java @@ -34,7 +34,7 @@ private LiftA3() { } @Override - public AppD apply(Fn3 fn, AppA appA, AppB appB, AppC appC) { + public AppD checkedApply(Fn3 fn, AppA appA, AppB appB, AppC appC) { return appC.zip(appB.zip(appA.fmap(fn))).coerce(); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/RateLimit.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/RateLimit.java index 970b61dfb..2da5fb3b2 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/RateLimit.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/RateLimit.java @@ -53,7 +53,7 @@ private RateLimit() { } @Override - public Iterable apply(Supplier instantSupplier, Long limit, Duration duration, Iterable as) { + public Iterable checkedApply(Supplier instantSupplier, Long limit, Duration duration, Iterable as) { if (limit < 1) throw new IllegalArgumentException("Limit must be greater than 0: " + limit); diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn5/LiftA4.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn5/LiftA4.java index 1187aa320..408f94652 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn5/LiftA4.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn5/LiftA4.java @@ -38,7 +38,7 @@ private LiftA4() { } @Override - public AppE apply(Fn4 fn, AppA appA, AppB appB, AppC appC, AppD appD) { + public AppE checkedApply(Fn4 fn, AppA appA, AppB appB, AppC appC, AppD appD) { return appD.zip(appC.zip(appB.zip(appA.fmap(fn)))).coerce(); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn6/LiftA5.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn6/LiftA5.java index 24d83bca2..4711de30a 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn6/LiftA5.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn6/LiftA5.java @@ -42,7 +42,7 @@ private LiftA5() { } @Override - public AppF apply(Fn5 fn, AppA appA, AppB appB, AppC appC, AppD appD, AppE appE) { + public AppF checkedApply(Fn5 fn, AppA appA, AppB appB, AppC appC, AppD appD, AppE appE) { return appE.zip(appD.zip(appC.zip(appB.zip(appA.fmap(fn))))).coerce(); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn7/LiftA6.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn7/LiftA6.java index 804fb7b99..90234684d 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn7/LiftA6.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn7/LiftA6.java @@ -47,8 +47,8 @@ private LiftA6() { } @Override - public AppG apply(Fn6 fn, AppA appA, AppB appB, AppC appC, AppD appD, AppE appE, - AppF appF) { + public AppG checkedApply(Fn6 fn, AppA appA, AppB appB, AppC appC, AppD appD, AppE appE, + AppF appF) { return appF.zip(appE.zip(appD.zip(appC.zip(appB.zip(appA.fmap(fn)))))).coerce(); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn8/LiftA7.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn8/LiftA7.java index 359801ba7..90eab07a5 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn8/LiftA7.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn8/LiftA7.java @@ -50,8 +50,8 @@ private LiftA7() { } @Override - public AppH apply(Fn7 fn, AppA appA, AppB appB, AppC appC, AppD appD, AppE appE, - AppF appF, AppG appG) { + public AppH checkedApply(Fn7 fn, AppA appA, AppB appB, AppC appC, AppD appD, AppE appE, + AppF appF, AppG appG) { return appG.zip(appF.zip(appE.zip(appD.zip(appC.zip(appB.zip(appA.fmap(fn))))))).coerce(); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/recursion/Trampoline.java b/src/main/java/com/jnape/palatable/lambda/functions/recursion/Trampoline.java index 2d52b95d1..70e8f4fd7 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/recursion/Trampoline.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/recursion/Trampoline.java @@ -25,7 +25,7 @@ public final class Trampoline implements Fn2 INSTANCE = new Trampoline<>(); @Override - public B apply(Function> fn, A a) { + public B checkedApply(Function> fn, A a) { RecursiveResult next = fn.apply(a); while (next instanceof Recurse) next = fn.apply(((Recurse) next).a); diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/BiMonoidFactory.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/BiMonoidFactory.java index 352de9585..a28e90614 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/BiMonoidFactory.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/specialized/BiMonoidFactory.java @@ -1,22 +1,37 @@ package com.jnape.palatable.lambda.functions.specialized; import com.jnape.palatable.lambda.adt.product.Product2; +import com.jnape.palatable.lambda.functions.specialized.checked.Runtime; import com.jnape.palatable.lambda.monoid.Monoid; @FunctionalInterface public interface BiMonoidFactory extends BiSemigroupFactory { @Override - default MonoidFactory apply(A a) { - return b -> apply(a, b); + Monoid checkedApply(A a, B b) throws Throwable; + + @Override + default MonoidFactory checkedApply(A a) throws Throwable { + return b -> checkedApply(a, b); + } + + @Override + default Monoid apply(A a, B b) { + try { + return checkedApply(a, b); + } catch (Throwable t) { + throw Runtime.throwChecked(t); + } } @Override - Monoid apply(A a, B b); + default MonoidFactory apply(A a) { + return b -> apply(a, b); + } @Override default BiMonoidFactory flip() { - return (b, a) -> apply(a, b); + return (b, a) -> checkedApply(a, b); } @Override diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/BiSemigroupFactory.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/BiSemigroupFactory.java index a2a16d899..5cf0a4a17 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/BiSemigroupFactory.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/specialized/BiSemigroupFactory.java @@ -8,7 +8,17 @@ public interface BiSemigroupFactory extends Fn4 { @Override - Semigroup apply(A a, B b); + Semigroup checkedApply(A a, B b) throws Throwable; + + @Override + default C checkedApply(A a, B b, C c, C d) throws Throwable { + return checkedApply(a, b).checkedApply(c, d); + } + + @Override + default Semigroup apply(A a, B b) { + return Fn4.super.apply(a, b)::apply; + } @Override default SemigroupFactory apply(A a) { @@ -24,9 +34,4 @@ default BiSemigroupFactory flip() { default SemigroupFactory, C> uncurry() { return ab -> apply(ab._1(), ab._2()); } - - @Override - default C apply(A a, B b, C c, C d) { - return apply(a).apply(b).apply(c, d); - } } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/MonoidFactory.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/MonoidFactory.java index 68657a104..e4d993def 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/MonoidFactory.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/specialized/MonoidFactory.java @@ -1,14 +1,24 @@ package com.jnape.palatable.lambda.functions.specialized; +import com.jnape.palatable.lambda.functions.specialized.checked.Runtime; import com.jnape.palatable.lambda.monoid.Monoid; public interface MonoidFactory extends SemigroupFactory { + @Override + Monoid checkedApply(A a) throws Throwable; + @Override default B apply(A a, B b, B c) { return apply(a).apply(b, c); } @Override - Monoid apply(A a); + default Monoid apply(A a) { + try { + return checkedApply(a); + } catch (Throwable t) { + throw Runtime.throwChecked(t); + } + } } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/Noop.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/Noop.java index 509499536..568e6ca2c 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/Noop.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/specialized/Noop.java @@ -14,7 +14,7 @@ private Noop() { } @Override - public void accept(A a) { + public void checkedAccept(A a) { } /** diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/Pure.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/Pure.java index 212488abe..0f63478f6 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/Pure.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/specialized/Pure.java @@ -1,5 +1,6 @@ package com.jnape.palatable.lambda.functions.specialized; +import com.jnape.palatable.lambda.functions.specialized.checked.Runtime; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Functor; @@ -8,7 +9,16 @@ * * @param the {@link Functor} to lift into */ +@FunctionalInterface public interface Pure> { - Functor apply(A a); + Functor checkedApply(A a) throws Throwable; + + default Functor apply(A a) { + try { + return checkedApply(a); + } catch (Throwable t) { + throw Runtime.throwChecked(t); + } + } } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/SemigroupFactory.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/SemigroupFactory.java index 4a47c277c..6d49d6a55 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/SemigroupFactory.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/specialized/SemigroupFactory.java @@ -7,10 +7,15 @@ public interface SemigroupFactory extends Fn3 { @Override - Semigroup apply(A a); + Semigroup checkedApply(A a) throws Throwable; @Override - default B apply(A a, B b, B c) { - return apply(a).apply(b, c); + default Semigroup apply(A a) { + return Fn3.super.apply(a)::apply; + } + + @Override + default B checkedApply(A a, B b, B c) throws Throwable { + return checkedApply(a).checkedApply(b, c); } } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedEffect.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedEffect.java index 0dc24e4bb..65ee00c0e 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedEffect.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedEffect.java @@ -3,14 +3,14 @@ import com.jnape.palatable.lambda.adt.Unit; import com.jnape.palatable.lambda.functions.Effect; import com.jnape.palatable.lambda.functions.Fn1; -import com.jnape.palatable.lambda.io.IO; import com.jnape.palatable.lambda.functor.Applicative; +import com.jnape.palatable.lambda.io.IO; import java.util.function.Consumer; import java.util.function.Function; -import static com.jnape.palatable.lambda.io.IO.io; import static com.jnape.palatable.lambda.functions.specialized.checked.Runtime.throwChecked; +import static com.jnape.palatable.lambda.io.IO.io; /** * Specialized {@link Effect} that can throw any {@link Throwable}. @@ -57,7 +57,7 @@ default IO checkedApply(A a) throws T { */ @Override default CheckedEffect diMapL(Function fn) { - return Effect.super.diMapL(fn)::accept; + return Effect.super.diMapL(fn)::checkedAccept; } /** @@ -65,7 +65,7 @@ default CheckedEffect diMapL(Function fn) { */ @Override default CheckedEffect contraMap(Function fn) { - return Effect.super.contraMap(fn)::accept; + return Effect.super.contraMap(fn)::checkedAccept; } /** @@ -73,7 +73,7 @@ default CheckedEffect contraMap(Function fn) { */ @Override default CheckedEffect compose(Function before) { - return Effect.super.compose(before)::accept; + return Effect.super.compose(before)::checkedAccept; } /** @@ -81,7 +81,7 @@ default CheckedEffect compose(Function before) */ @Override default CheckedEffect discardR(Applicative> appB) { - return Effect.super.discardR(appB)::accept; + return Effect.super.discardR(appB)::checkedAccept; } /** @@ -89,17 +89,9 @@ default CheckedEffect discardR(Applicative> appB) { */ @Override default CheckedEffect andThen(Consumer after) { - return Effect.super.andThen(after)::accept; + return Effect.super.andThen(after)::checkedAccept; } - /** - * A version of {@link Effect#accept} that can throw checked exceptions. - * - * @param a the effect argument - * @throws T any exception that can be thrown by this method - */ - void checkedAccept(A a) throws T; - /** * Convenience static factory method for constructing a {@link CheckedEffect} without an explicit cast or type * attribution at the call site. diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedFn1.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedFn1.java index 4fd589c2a..1c8fb76b6 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedFn1.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedFn1.java @@ -40,13 +40,14 @@ default B apply(A a) { */ @Override default CheckedFn1 fmap(Function f) { - return Fn1.super.fmap(f)::apply; + return Fn1.super.fmap(f)::checkedApply; } /** * {@inheritDoc} */ @Override + @SuppressWarnings("overrides") default CheckedFn1 flatMap(Function>> f) { return Fn1.super.flatMap(f).>coerce()::apply; } @@ -56,7 +57,7 @@ default CheckedFn1 flatMap(Function CheckedFn1 discardL(Applicative> appB) { - return Fn1.super.discardL(appB)::apply; + return Fn1.super.discardL(appB)::checkedApply; } /** @@ -64,7 +65,7 @@ default CheckedFn1 discardL(Applicative> appB) { */ @Override default CheckedFn1 discardR(Applicative> appB) { - return Fn1.super.discardR(appB)::apply; + return Fn1.super.discardR(appB)::checkedApply; } /** @@ -72,7 +73,7 @@ default CheckedFn1 discardR(Applicative> appB) { */ @Override default CheckedFn1 zip(Applicative, Fn1> appFn) { - return Fn1.super.zip(appFn)::apply; + return Fn1.super.zip(appFn)::checkedApply; } /** @@ -105,7 +106,7 @@ default CheckedFn1 diMapR(Function fn) { @Override default CheckedFn1 diMap(Function lFn, Function rFn) { - return Fn1.super.diMap(lFn, rFn)::apply; + return Fn1.super.diMap(lFn, rFn)::checkedApply; } /** @@ -113,7 +114,7 @@ default CheckedFn1 diMap(Function lFn, */ @Override default CheckedFn1, Tuple2> cartesian() { - return Fn1.super.cartesian()::apply; + return Fn1.super.cartesian()::checkedApply; } /** @@ -121,7 +122,7 @@ default CheckedFn1, Tuple2> cartesian() { */ @Override default CheckedFn1> carry() { - return Fn1.super.carry()::apply; + return Fn1.super.carry()::checkedApply; } /** @@ -137,7 +138,7 @@ default CheckedFn1 contraMap(Function fn) { */ @Override default CheckedFn1 compose(Function before) { - return Fn1.super.compose(before)::apply; + return Fn1.super.compose(before)::checkedApply; } /** @@ -145,18 +146,9 @@ default CheckedFn1 compose(Function before) */ @Override default CheckedFn1 andThen(Function after) { - return Fn1.super.andThen(after)::apply; + return Fn1.super.andThen(after)::checkedApply; } - /** - * A version of {@link Fn1#apply} that can throw checked exceptions. - * - * @param a the function argument - * @return the application of the argument to the function - * @throws T any exception that can be thrown by this method - */ - B checkedApply(A a) throws T; - /** * Convenience static factory method for constructing a {@link CheckedFn1} without an explicit cast or type * attribution at the call site. diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/Monoid.java b/src/main/java/com/jnape/palatable/lambda/monoid/Monoid.java index 88d13a1d6..3ff2d3e0b 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/Monoid.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/Monoid.java @@ -110,7 +110,7 @@ public A identity() { } @Override - public A apply(A x, A y) { + public A checkedApply(A x, A y) { return semigroup.apply(x, y); } }; @@ -124,7 +124,7 @@ public A identity() { } @Override - public A apply(A x, A y) { + public A checkedApply(A x, A y) { return semigroup.apply(x, y); } }; diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/AddAll.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/AddAll.java index 5b93eac91..383116e6d 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/AddAll.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/AddAll.java @@ -21,13 +21,13 @@ */ public final class AddAll> implements MonoidFactory, C> { - private static final AddAll INSTANCE = new AddAll<>(); + private static final AddAll INSTANCE = new AddAll<>(); private AddAll() { } @Override - public Monoid apply(Supplier cSupplier) { + public Monoid checkedApply(Supplier cSupplier) { return new Monoid() { @Override public C identity() { @@ -35,7 +35,7 @@ public C identity() { } @Override - public C apply(C xs, C ys) { + public C checkedApply(C xs, C ys) { C c = identity(); c.addAll(xs); c.addAll(ys); diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/And.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/And.java index 3465ca0f8..e47e67df4 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/And.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/And.java @@ -29,7 +29,7 @@ public Boolean identity() { } @Override - public Boolean apply(Boolean x, Boolean y) { + public Boolean checkedApply(Boolean x, Boolean y) { return x && y; } diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Collapse.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Collapse.java index 336e3cf6e..7713431b5 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Collapse.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Collapse.java @@ -29,9 +29,10 @@ private Collapse() { } @Override - public Monoid> apply(Monoid<_1> _1Monoid, Monoid<_2> _2Monoid) { - Semigroup> semigroup = com.jnape.palatable.lambda.semigroup.builtin.Collapse.collapse(_1Monoid, _2Monoid); - return Monoid.>monoid(semigroup, () -> tuple(_1Monoid.identity(), _2Monoid.identity())); + public Monoid> checkedApply(Monoid<_1> _1Monoid, Monoid<_2> _2Monoid) { + return Monoid.>monoid( + com.jnape.palatable.lambda.semigroup.builtin.Collapse.collapse(_1Monoid, _2Monoid), + () -> tuple(_1Monoid.identity(), _2Monoid.identity())); } @SuppressWarnings("unchecked") diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Compose.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Compose.java index 6c9945784..f9c53ed27 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Compose.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Compose.java @@ -30,7 +30,7 @@ private Compose() { } @Override - public Monoid> apply(Monoid aMonoid) { + public Monoid> checkedApply(Monoid aMonoid) { return monoid(com.jnape.palatable.lambda.semigroup.builtin.Compose.compose(aMonoid), (Supplier>) () -> completedFuture(aMonoid.identity())); } diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Concat.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Concat.java index dd1ae290e..c02c09586 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Concat.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Concat.java @@ -28,7 +28,7 @@ public Iterable identity() { } @Override - public Iterable apply(Iterable xs, Iterable ys) { + public Iterable checkedApply(Iterable xs, Iterable ys) { return new ConcatenatingIterable<>(xs, ys); } diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Endo.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Endo.java index a5f1fcc0d..75a4090ba 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Endo.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Endo.java @@ -19,17 +19,17 @@ public final class Endo implements Monoid> { private Endo() { } + public A apply(Fn1 f, Fn1 g, A a) { + return apply(f, g).apply(a); + } + @Override public Fn1 identity() { return id(); } - public A apply(Fn1 f, Fn1 g, A a) { - return apply(f, g).apply(a); - } - @Override - public Fn1 apply(Fn1 f, Fn1 g) { + public Fn1 checkedApply(Fn1 f, Fn1 g) { return f.fmap(g); } diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/First.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/First.java index 9d074aaea..69b1e356c 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/First.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/First.java @@ -34,7 +34,7 @@ public Maybe identity() { } @Override - public Maybe apply(Maybe x, Maybe y) { + public Maybe checkedApply(Maybe x, Maybe y) { return x.fmap(Maybe::just).orElse(y); } diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Join.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Join.java index 9f3713283..571bcbe73 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Join.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Join.java @@ -21,7 +21,7 @@ public String identity() { } @Override - public String apply(String x, String y) { + public String checkedApply(String x, String y) { return x + y; } diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Last.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Last.java index 775e6448f..8b0c91073 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Last.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Last.java @@ -30,7 +30,7 @@ public Maybe identity() { } @Override - public Maybe apply(Maybe x, Maybe y) { + public Maybe checkedApply(Maybe x, Maybe y) { return first(y, x); } diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/LeftAll.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/LeftAll.java index 906a34658..ca2f4634b 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/LeftAll.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/LeftAll.java @@ -35,7 +35,7 @@ private LeftAll() { } @Override - public Monoid> apply(Monoid lMonoid) { + public Monoid> checkedApply(Monoid lMonoid) { Semigroup> semigroup = com.jnape.palatable.lambda.semigroup.builtin.LeftAll.leftAll(lMonoid); return Monoid.>monoid(semigroup, () -> left(lMonoid.identity())); } diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/LeftAny.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/LeftAny.java index 9ba5a8cc7..461738188 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/LeftAny.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/LeftAny.java @@ -29,13 +29,13 @@ */ public final class LeftAny implements MonoidFactory, Either> { - private static final LeftAny INSTANCE = new LeftAny<>(); + private static final LeftAny INSTANCE = new LeftAny<>(); private LeftAny() { } @Override - public Monoid> apply(Monoid lMonoid) { + public Monoid> checkedApply(Monoid lMonoid) { Semigroup> semigroup = com.jnape.palatable.lambda.semigroup.builtin.LeftAny.leftAny(lMonoid); return Monoid.>monoid(semigroup, () -> left(lMonoid.identity())); } diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Merge.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Merge.java index 5b6f7f8df..83b3afa41 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Merge.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Merge.java @@ -22,13 +22,13 @@ */ public final class Merge implements BiMonoidFactory, Monoid, Either> { - private static final Merge INSTANCE = new Merge<>(); + private static final Merge INSTANCE = new Merge<>(); private Merge() { } @Override - public Monoid> apply(Semigroup lSemigroup, Monoid rMonoid) { + public Monoid> checkedApply(Semigroup lSemigroup, Monoid rMonoid) { Semigroup> semigroup = com.jnape.palatable.lambda.semigroup.builtin.Merge.merge(lSemigroup, rMonoid); return Monoid.>monoid(semigroup, () -> right(rMonoid.identity())); } diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/MergeMaps.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/MergeMaps.java index 4e5b54ea2..9f594df75 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/MergeMaps.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/MergeMaps.java @@ -27,7 +27,7 @@ private MergeMaps() { } @Override - public Monoid> apply(Supplier> mSupplier, Semigroup semigroup) { + public Monoid> checkedApply(Supplier> mSupplier, Semigroup semigroup) { return Monoid.>monoid((x, y) -> { Map copy = mSupplier.get(); copy.putAll(x); diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Or.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Or.java index a8157d0fb..90e57807d 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Or.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Or.java @@ -28,7 +28,7 @@ public Boolean identity() { } @Override - public Boolean apply(Boolean x, Boolean y) { + public Boolean checkedApply(Boolean x, Boolean y) { return x || y; } @@ -39,7 +39,7 @@ public boolean test(Boolean x, Boolean y) { @Override public Boolean foldMap(Function fn, Iterable bs) { - return find(fn::apply, bs).fmap(constantly(true)).orElse(false); + return find(fn, bs).fmap(constantly(true)).orElse(false); } @Override diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Present.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Present.java index 2fc0731d5..71dc4e95f 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Present.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Present.java @@ -35,7 +35,7 @@ private Present() { } @Override - public Monoid> apply(Semigroup aSemigroup) { + public Monoid> checkedApply(Semigroup aSemigroup) { return monoid((maybeX, maybeY) -> first(maybeX.fmap(x -> maybeY.fmap(aSemigroup.apply(x)).orElse(x)), maybeY), nothing()); } diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/PutAll.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/PutAll.java index b5c4e7ef8..b3462f175 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/PutAll.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/PutAll.java @@ -25,7 +25,7 @@ public HMap identity() { } @Override - public HMap apply(HMap x, HMap y) { + public HMap checkedApply(HMap x, HMap y) { return x.putAll(y); } diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/RightAll.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/RightAll.java index f68fb82e2..6968ea72c 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/RightAll.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/RightAll.java @@ -33,7 +33,7 @@ private RightAll() { } @Override - public Monoid> apply(Monoid rMonoid) { + public Monoid> checkedApply(Monoid rMonoid) { Semigroup> semigroup = com.jnape.palatable.lambda.semigroup.builtin.RightAll.rightAll(rMonoid); return Monoid.>monoid(semigroup, () -> right(rMonoid.identity())); } diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/RightAny.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/RightAny.java index ff25246c7..277ec5163 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/RightAny.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/RightAny.java @@ -29,13 +29,13 @@ */ public final class RightAny implements MonoidFactory, Either> { - private static final RightAny INSTANCE = new RightAny<>(); + private static final RightAny INSTANCE = new RightAny<>(); private RightAny() { } @Override - public Monoid> apply(Monoid rMonoid) { + public Monoid> checkedApply(Monoid rMonoid) { Semigroup> semigroup = com.jnape.palatable.lambda.semigroup.builtin.RightAny.rightAny(rMonoid); return Monoid.>monoid(semigroup, () -> right(rMonoid.identity())); } diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/RunAll.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/RunAll.java index b3ab1c93e..7533f9c41 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/RunAll.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/RunAll.java @@ -1,8 +1,8 @@ package com.jnape.palatable.lambda.monoid.builtin; import com.jnape.palatable.lambda.functions.Fn1; -import com.jnape.palatable.lambda.io.IO; import com.jnape.palatable.lambda.functions.specialized.MonoidFactory; +import com.jnape.palatable.lambda.io.IO; import com.jnape.palatable.lambda.monoid.Monoid; import com.jnape.palatable.lambda.semigroup.Semigroup; @@ -23,7 +23,7 @@ private RunAll() { } @Override - public Monoid> apply(Monoid monoid) { + public Monoid> checkedApply(Monoid monoid) { Semigroup> semigroup = com.jnape.palatable.lambda.semigroup.builtin.RunAll.runAll(monoid); return monoid(semigroup, io(monoid.identity())); } diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Union.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Union.java index 4594f328e..8da150dc5 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Union.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Union.java @@ -26,7 +26,7 @@ public Iterable identity() { } @Override - public Iterable apply(Iterable xs, Iterable ys) { + public Iterable checkedApply(Iterable xs, Iterable ys) { return new UnioningIterable<>(xs, ys); } diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Xor.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Xor.java index 860df1e6f..4e17c6e97 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Xor.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Xor.java @@ -26,7 +26,7 @@ public Boolean identity() { } @Override - public Boolean apply(Boolean x, Boolean y) { + public Boolean checkedApply(Boolean x, Boolean y) { return x ^ y; } diff --git a/src/main/java/com/jnape/palatable/lambda/optics/functions/Matching.java b/src/main/java/com/jnape/palatable/lambda/optics/functions/Matching.java index 425f47dcf..04b03442f 100644 --- a/src/main/java/com/jnape/palatable/lambda/optics/functions/Matching.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/functions/Matching.java @@ -16,7 +16,7 @@ private Matching() { } @Override - public Either apply(Optic, ? super Identity, S, T, A, B> optic, S s) { + public Either checkedApply(Optic, ? super Identity, S, T, A, B> optic, S s) { Market> market = new Market<>(Identity::new, Either::right); return optic., Identity, diff --git a/src/main/java/com/jnape/palatable/lambda/optics/functions/Over.java b/src/main/java/com/jnape/palatable/lambda/optics/functions/Over.java index cf73de8ad..d15c8bfae 100644 --- a/src/main/java/com/jnape/palatable/lambda/optics/functions/Over.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/functions/Over.java @@ -32,9 +32,9 @@ private Over() { } @Override - public T apply(Optic, ? super Identity, S, T, A, B> optic, - Function fn, - S s) { + public T checkedApply(Optic, ? super Identity, S, T, A, B> optic, + Function fn, + S s) { return optic., Identity, Identity, Identity, Fn1>, Fn1>>apply( a -> new Identity<>(fn.apply(a))).apply(s).runIdentity(); } diff --git a/src/main/java/com/jnape/palatable/lambda/optics/functions/Pre.java b/src/main/java/com/jnape/palatable/lambda/optics/functions/Pre.java index edbd9e9c0..977788eac 100644 --- a/src/main/java/com/jnape/palatable/lambda/optics/functions/Pre.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/functions/Pre.java @@ -28,7 +28,7 @@ private Pre() { } @Override - public Optic, Const, ?>, S, T, Maybe, B> apply( + public Optic, Const, ?>, S, T, Maybe, B> checkedApply( Optic, ? super Const, ?>, S, T, A, B> optic) { Optic, ? super Const, ?>, S, T, Maybe, B> mappedOptic = optic.mapA(Maybe::just); return reframe(mappedOptic); @@ -51,7 +51,7 @@ public static Pre pre() { Optic, Const, ?>, S, T, A, B> optic = protoOptic .toOptic(new Pure, ?>>() { @Override - public Const, X> apply(X x) { + public Const, X> checkedApply(X x) { return new Const<>(nothing()); } }); diff --git a/src/main/java/com/jnape/palatable/lambda/optics/functions/Re.java b/src/main/java/com/jnape/palatable/lambda/optics/functions/Re.java index a61841058..eeb36f5b8 100644 --- a/src/main/java/com/jnape/palatable/lambda/optics/functions/Re.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/functions/Re.java @@ -26,7 +26,7 @@ private Re() { } @Override - public Optic, Const, B, B, T, T> apply( + public Optic, Const, B, B, T, T> checkedApply( Optic, ? super Identity, S, T, A, B> optic) { return Optic., Const, B, B, T, T, Const, Const, diff --git a/src/main/java/com/jnape/palatable/lambda/optics/functions/Set.java b/src/main/java/com/jnape/palatable/lambda/optics/functions/Set.java index 1921c45c6..7fdd16e56 100644 --- a/src/main/java/com/jnape/palatable/lambda/optics/functions/Set.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/functions/Set.java @@ -31,7 +31,7 @@ private Set() { } @Override - public T apply(Optic, ? super Identity, S, T, A, B> optic, B b, S s) { + public T checkedApply(Optic, ? super Identity, S, T, A, B> optic, B b, S s) { return over(optic, constantly(b), s); } diff --git a/src/main/java/com/jnape/palatable/lambda/optics/functions/Under.java b/src/main/java/com/jnape/palatable/lambda/optics/functions/Under.java index 7356d3ec1..ce63ea01a 100644 --- a/src/main/java/com/jnape/palatable/lambda/optics/functions/Under.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/functions/Under.java @@ -30,9 +30,9 @@ private Under() { } @Override - public A apply(Optic, ? super Identity, S, T, A, B> optic, - Function fn, - B b) { + public A checkedApply(Optic, ? super Identity, S, T, A, B> optic, + Function fn, + B b) { Exchange> exchange = optic.apply(new Exchange<>(id(), Identity::new)); return exchange.sa().apply(fn.apply(exchange.bt().apply(b).runIdentity())); } diff --git a/src/main/java/com/jnape/palatable/lambda/optics/functions/View.java b/src/main/java/com/jnape/palatable/lambda/optics/functions/View.java index 1a80c025e..c63074ac2 100644 --- a/src/main/java/com/jnape/palatable/lambda/optics/functions/View.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/functions/View.java @@ -27,7 +27,7 @@ private View() { } @Override - public A apply(Optic, ? super Const, S, T, A, B> optic, S s) { + public A checkedApply(Optic, ? super Const, S, T, A, B> optic, S s) { return optic., Const, Const, Const, Fn1>, Fn1>>apply( Const::new).apply(s).runConst(); } diff --git a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Absent.java b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Absent.java index 1e8c6ef1c..97ccfa54a 100644 --- a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Absent.java +++ b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Absent.java @@ -31,7 +31,7 @@ private Absent() { } @Override - public Semigroup> apply(Semigroup aSemigroup) { + public Semigroup> checkedApply(Semigroup aSemigroup) { return LiftA2., Maybe, Maybe, Maybe>liftA2(aSemigroup.toBiFunction())::apply; } diff --git a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Collapse.java b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Collapse.java index d1a3b6eca..7b163898d 100644 --- a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Collapse.java +++ b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Collapse.java @@ -21,13 +21,13 @@ */ public final class Collapse<_1, _2> implements BiSemigroupFactory, Semigroup<_2>, Tuple2<_1, _2>> { - private static final Collapse INSTANCE = new Collapse<>(); + private static final Collapse INSTANCE = new Collapse<>(); private Collapse() { } @Override - public Semigroup> apply(Semigroup<_1> _1Semigroup, Semigroup<_2> _2Semigroup) { + public Semigroup> checkedApply(Semigroup<_1> _1Semigroup, Semigroup<_2> _2Semigroup) { return (x, y) -> x.biMap(_1Semigroup.flip().apply(y._1()), _2Semigroup.flip().apply(y._2())); } diff --git a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Compose.java b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Compose.java index 0bb9a2a41..cba9a218f 100644 --- a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Compose.java +++ b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Compose.java @@ -26,7 +26,7 @@ private Compose() { } @Override - public Semigroup> apply(Semigroup aSemigroup) { + public Semigroup> checkedApply(Semigroup aSemigroup) { return (futureX, futureY) -> futureX.thenCompose(x -> futureY.thenApply(y -> aSemigroup.apply(x, y))); } diff --git a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/LeftAll.java b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/LeftAll.java index 780c61f89..e5ac2caf1 100644 --- a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/LeftAll.java +++ b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/LeftAll.java @@ -30,13 +30,13 @@ */ public final class LeftAll implements SemigroupFactory, Either> { - private static final LeftAll INSTANCE = new LeftAll<>(); + private static final LeftAll INSTANCE = new LeftAll<>(); private LeftAll() { } @Override - public Semigroup> apply(Semigroup lSemigroup) { + public Semigroup> checkedApply(Semigroup lSemigroup) { return (x, y) -> x.match(xL -> y.match(yL -> left(lSemigroup.apply(xL, yL)), Either::right), Either::right); } diff --git a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/LeftAny.java b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/LeftAny.java index 233246b89..91a892dfb 100644 --- a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/LeftAny.java +++ b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/LeftAny.java @@ -35,7 +35,7 @@ private LeftAny() { } @Override - public Semigroup> apply(Semigroup lSemigroup) { + public Semigroup> checkedApply(Semigroup lSemigroup) { return (x, y) -> x.match(xL -> y.match(yL -> left(lSemigroup.apply(xL, yL)), yR -> left(xL)), xR -> y); diff --git a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Max.java b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Max.java index 001a39a3e..a9cc3db66 100644 --- a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Max.java +++ b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Max.java @@ -26,7 +26,7 @@ private Max() { } @Override - public A apply(A x, A y) { + public A checkedApply(A x, A y) { return maxBy(id(), x, y); } diff --git a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/MaxBy.java b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/MaxBy.java index d00bcbb4b..bc97f7d9c 100644 --- a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/MaxBy.java +++ b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/MaxBy.java @@ -24,13 +24,13 @@ */ public final class MaxBy> implements SemigroupFactory, A> { - private static final MaxBy INSTANCE = new MaxBy<>(); + private static final MaxBy INSTANCE = new MaxBy<>(); private MaxBy() { } @Override - public Semigroup apply(Function compareFn) { + public Semigroup checkedApply(Function compareFn) { return (x, y) -> ltBy(compareFn, y, x) ? y : x; } diff --git a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Merge.java b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Merge.java index eaf5e355b..833e1aa57 100644 --- a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Merge.java +++ b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Merge.java @@ -26,7 +26,7 @@ private Merge() { } @Override - public Semigroup> apply(Semigroup lSemigroup, Semigroup rSemigroup) { + public Semigroup> checkedApply(Semigroup lSemigroup, Semigroup rSemigroup) { return (x, y) -> x.merge(lSemigroup::apply, rSemigroup::apply, y); } diff --git a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Min.java b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Min.java index f700e4612..747bd5d25 100644 --- a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Min.java +++ b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Min.java @@ -26,7 +26,7 @@ private Min() { } @Override - public A apply(A x, A y) { + public A checkedApply(A x, A y) { return minBy(id(), x, y); } diff --git a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/MinBy.java b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/MinBy.java index 4458a55bc..c425c5121 100644 --- a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/MinBy.java +++ b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/MinBy.java @@ -24,13 +24,13 @@ */ public final class MinBy> implements SemigroupFactory, A> { - private static final MinBy INSTANCE = new MinBy<>(); + private static final MinBy INSTANCE = new MinBy<>(); private MinBy() { } @Override - public Semigroup apply(Function compareFn) { + public Semigroup checkedApply(Function compareFn) { return (x, y) -> gtBy(compareFn, y, x) ? y : x; } diff --git a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/RightAll.java b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/RightAll.java index 8c69fbd94..5bb6fa018 100644 --- a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/RightAll.java +++ b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/RightAll.java @@ -29,13 +29,13 @@ */ public final class RightAll implements SemigroupFactory, Either> { - private static final RightAll INSTANCE = new RightAll<>(); + private static final RightAll INSTANCE = new RightAll<>(); private RightAll() { } @Override - public Semigroup> apply(Semigroup rSemigroup) { + public Semigroup> checkedApply(Semigroup rSemigroup) { return (eitherX, eitherY) -> eitherX.flatMap(xR -> eitherY.flatMap(yR -> right(rSemigroup.apply(xR, yR)))); } diff --git a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/RightAny.java b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/RightAny.java index 7d2f1d864..264fad155 100644 --- a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/RightAny.java +++ b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/RightAny.java @@ -30,13 +30,13 @@ */ public final class RightAny implements SemigroupFactory, Either> { - private static final RightAny INSTANCE = new RightAny<>(); + private static final RightAny INSTANCE = new RightAny<>(); private RightAny() { } @Override - public Semigroup> apply(Semigroup rSemigroup) { + public Semigroup> checkedApply(Semigroup rSemigroup) { return (x, y) -> x.match(constantly(y), xR -> y.match(constantly(right(xR)), rSemigroup.apply(xR).andThen(Either::right))); diff --git a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/RunAll.java b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/RunAll.java index 34a2eeb2b..f84d0243a 100644 --- a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/RunAll.java +++ b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/RunAll.java @@ -1,8 +1,8 @@ package com.jnape.palatable.lambda.semigroup.builtin; import com.jnape.palatable.lambda.functions.Fn1; -import com.jnape.palatable.lambda.io.IO; import com.jnape.palatable.lambda.functions.specialized.SemigroupFactory; +import com.jnape.palatable.lambda.io.IO; import com.jnape.palatable.lambda.semigroup.Semigroup; /** @@ -19,7 +19,7 @@ private RunAll() { } @Override - public Semigroup> apply(Semigroup semigroup) { + public Semigroup> checkedApply(Semigroup semigroup) { return (ioX, ioY) -> ioY.zip(ioX.fmap(semigroup)); } diff --git a/src/test/java/com/jnape/palatable/lambda/functions/EffectTest.java b/src/test/java/com/jnape/palatable/lambda/functions/EffectTest.java index 9f5dabd60..ca3505a0e 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/EffectTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functions/EffectTest.java @@ -19,12 +19,12 @@ public class EffectTest { public void covariantReturns() { List results = new ArrayList<>(); - Effect effect = results::add; - Effect diMapL = effect.diMapL(Object::toString); - Effect contraMap = effect.contraMap(Object::toString); - Effect compose = effect.compose(Object::toString); + Effect effect = results::add; + Effect diMapL = effect.diMapL(Object::toString); + Effect contraMap = effect.contraMap(Object::toString); + Effect compose = effect.compose(Object::toString); Effect stringEffect = effect.discardR(constantly("1")); - Effect andThen = effect.andThen(effect); + Effect andThen = effect.andThen(effect); effect.accept("1"); diMapL.accept("2"); diff --git a/src/test/java/com/jnape/palatable/lambda/functor/builtin/LazyTest.java b/src/test/java/com/jnape/palatable/lambda/functor/builtin/LazyTest.java index c506f357c..b169b7870 100644 --- a/src/test/java/com/jnape/palatable/lambda/functor/builtin/LazyTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functor/builtin/LazyTest.java @@ -56,7 +56,7 @@ public void recursiveStackSafety() { assertEquals(STACK_EXPLODING_NUMBER, new Fn1, Lazy>() { @Override - public Lazy apply(Lazy lazyX) { + public Lazy checkedApply(Lazy lazyX) { return lazyX.flatMap(x -> x < STACK_EXPLODING_NUMBER ? apply(lazy(x + 1)) : lazy(x)); diff --git a/src/test/java/com/jnape/palatable/lambda/io/IOTest.java b/src/test/java/com/jnape/palatable/lambda/io/IOTest.java index 0c9ba0535..674bb8e8d 100644 --- a/src/test/java/com/jnape/palatable/lambda/io/IOTest.java +++ b/src/test/java/com/jnape/palatable/lambda/io/IOTest.java @@ -142,7 +142,7 @@ public void recursiveSyncFlatMapStackSafety() { assertEquals(STACK_EXPLODING_NUMBER, new Fn1, IO>() { @Override - public IO apply(IO a) { + public IO checkedApply(IO a) { return a.flatMap(x -> x < STACK_EXPLODING_NUMBER ? apply(io(x + 1)) : io(x)); } }.apply(io(0)).unsafePerformIO()); @@ -172,7 +172,7 @@ public void recursiveAsyncFlatMapStackSafety() { assertEquals(STACK_EXPLODING_NUMBER, new Fn1, IO>() { @Override - public IO apply(IO a) { + public IO checkedApply(IO a) { return a.flatMap(x -> x < STACK_EXPLODING_NUMBER ? apply(io(x + 1)) : io(x)); } }.apply(io(0)).unsafePerformAsyncIO().join()); From 74f70bd962dda001f423976f1b86e302881c735c Mon Sep 17 00:00:00 2001 From: jnape Date: Mon, 6 May 2019 20:06:30 -0500 Subject: [PATCH 36/69] Eliminating all checked variants of Fn1 and friends --- CHANGELOG.md | 8 +- .../jnape/palatable/lambda/adt/Either.java | 13 +- .../com/jnape/palatable/lambda/adt/Maybe.java | 9 +- .../com/jnape/palatable/lambda/adt/Try.java | 77 ++++---- .../specialized/checked/CheckedEffect.java | 107 ------------ .../specialized/checked/CheckedFn1.java | 165 ------------------ .../specialized/checked/CheckedRunnable.java | 17 -- .../specialized/checked/CheckedSupplier.java | 145 --------------- .../com/jnape/palatable/lambda/io/IO.java | 17 +- .../checked/CheckedEffectTest.java | 34 ---- .../specialized/checked/CheckedFn1Test.java | 47 ----- .../checked/CheckedSupplierTest.java | 42 ----- .../com/jnape/palatable/lambda/io/IOTest.java | 19 +- 13 files changed, 71 insertions(+), 629 deletions(-) delete mode 100644 src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedFn1.java delete mode 100644 src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedSupplier.java delete mode 100644 src/test/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedEffectTest.java delete mode 100644 src/test/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedFn1Test.java delete mode 100644 src/test/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedSupplierTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index eb5b0499e..bad86b559 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,8 +6,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/). ## [Unreleased] ### Changed - ***Breaking Change***: `IO` is now sealed and moved to its own package. Most previous constructions using the static -factory methods should continue to work (by simply targeting `Supplier` now instead of an anonymous `IO`), but some -might need to be reworked, and subtyping is obviously no longer supported. + factory methods should continue to work (by simply targeting `Supplier` now instead of an + anonymous `IO`), but some might need to be reworked, and subtyping is obviously no longer + supported. - ***Breaking Change***: `FoldRight` now requires `Lazy` as part of its interface to support short-circuiting operations - ***Breaking Change***: Eliminated all raw types and java11 warnings. This required using capture in unification parameters for Functor and friends, so nearly every functor's type-signature changed. @@ -19,7 +20,8 @@ might need to be reworked, and subtyping is obviously no longer supported. exceptions that could be caught by corresponding catch blocks - ***Breaking Change***: All `Fn*` types target methods now support throwing `Throwable`; `apply` is now defaulted and will simply bypass javac to throw checked exceptions as if they were unchecked. This allows all - checked variants to be eliminated + checked variants to be eliminated +- ***Breaking Change***: All `Checked` variants have been eliminated - `IO` is now stack-safe, regardless of whether the composition nests linearly or recursively ### Added diff --git a/src/main/java/com/jnape/palatable/lambda/adt/Either.java b/src/main/java/com/jnape/palatable/lambda/adt/Either.java index e248eef92..e6c0aeebb 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/Either.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/Either.java @@ -3,10 +3,11 @@ import com.jnape.palatable.lambda.adt.choice.Choice3; import com.jnape.palatable.lambda.adt.coproduct.CoProduct2; import com.jnape.palatable.lambda.functions.Fn1; +import com.jnape.palatable.lambda.functions.Fn0; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functions.builtin.fn2.Peek; import com.jnape.palatable.lambda.functions.builtin.fn2.Peek2; import com.jnape.palatable.lambda.functions.specialized.checked.CheckedRunnable; -import com.jnape.palatable.lambda.functions.specialized.checked.CheckedSupplier; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; import com.jnape.palatable.lambda.functor.builtin.Lazy; @@ -318,7 +319,7 @@ public static Either fromMaybe(Maybe maybe, Supplier leftFn) } /** - * Attempt to execute the {@link CheckedSupplier}, returning its result in a right value. If the supplier throws an + * Attempt to execute the {@link Fn0}, returning its result in a right value. If the supplier throws an * exception, apply leftFn to it, wrap it in a left value and return it. * * @param supplier the supplier of the right value @@ -327,20 +328,20 @@ public static Either fromMaybe(Maybe maybe, Supplier leftFn) * @param the right parameter type * @return the supplier result as a right value, or leftFn's mapping result as a left value */ - public static Either trying(CheckedSupplier supplier, + public static Either trying(Fn0 supplier, Function leftFn) { - return Try.trying(supplier::get).toEither(leftFn); + return Try.trying(supplier::get).toEither(leftFn); } /** - * Attempt to execute the {@link CheckedSupplier}, returning its result in a right value. If the supplier throws an + * Attempt to execute the {@link Fn0}, returning its result in a right value. If the supplier throws an * exception, wrap it in a left value and return it. * * @param supplier the supplier of the right value * @param the right parameter type * @return the supplier result as a right value, or a left value of the thrown exception */ - public static Either trying(CheckedSupplier supplier) { + public static Either trying(Fn0 supplier) { return trying(supplier, id()); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/Maybe.java b/src/main/java/com/jnape/palatable/lambda/adt/Maybe.java index 67c1fd886..892edc8ab 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/Maybe.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/Maybe.java @@ -5,8 +5,8 @@ import com.jnape.palatable.lambda.adt.coproduct.CoProduct2; import com.jnape.palatable.lambda.adt.hlist.HList; import com.jnape.palatable.lambda.adt.hlist.Tuple2; +import com.jnape.palatable.lambda.functions.Fn0; import com.jnape.palatable.lambda.functions.builtin.fn2.Peek; -import com.jnape.palatable.lambda.functions.specialized.checked.CheckedSupplier; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Functor; import com.jnape.palatable.lambda.functor.builtin.Lazy; @@ -21,6 +21,7 @@ import static com.jnape.palatable.lambda.adt.Either.left; import static com.jnape.palatable.lambda.adt.Unit.UNIT; +import static com.jnape.palatable.lambda.functions.Fn0.fn0; import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id; import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; @@ -69,10 +70,10 @@ public final A orElse(A other) { * @return the value, if present * @throws E the throwable, if the value is absent */ - public final A orElseThrow(Supplier throwableSupplier) throws E { - return orElseGet((CheckedSupplier) () -> { + public final A orElseThrow(Fn0 throwableSupplier) throws E { + return orElseGet(fn0(() -> { throw throwableSupplier.get(); - }); + })); } /** diff --git a/src/main/java/com/jnape/palatable/lambda/adt/Try.java b/src/main/java/com/jnape/palatable/lambda/adt/Try.java index fe1581307..bec29194a 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/Try.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/Try.java @@ -1,9 +1,9 @@ package com.jnape.palatable.lambda.adt; import com.jnape.palatable.lambda.adt.coproduct.CoProduct2; -import com.jnape.palatable.lambda.functions.specialized.checked.CheckedFn1; +import com.jnape.palatable.lambda.functions.Fn0; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functions.specialized.checked.CheckedRunnable; -import com.jnape.palatable.lambda.functions.specialized.checked.CheckedSupplier; import com.jnape.palatable.lambda.functions.specialized.checked.Runtime; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.builtin.Lazy; @@ -237,11 +237,10 @@ public static Try failure(T t) { * Execute supplier, returning a success A or a failure of the thrown {@link Throwable}. * * @param supplier the supplier - * @param the possible {@link Throwable} type * @param the possible success type * @return a new {@link Try} around either a successful A result or the thrown {@link Throwable} */ - public static Try trying(CheckedSupplier supplier) { + public static Try trying(Fn0 supplier) { try { return success(supplier.get()); } catch (Throwable t) { @@ -263,7 +262,7 @@ public static Try trying(CheckedRunnable runnable) { } /** - * Given a {@link CheckedSupplier}<{@link AutoCloseable}> aSupplier and a + * Given a {@link Fn0}<{@link AutoCloseable}> aSupplier and a * {@link Function} fn, apply fn to the result of aSupplier, ensuring * that the result has its {@link AutoCloseable#close() close} method invoked, regardless of the outcome. *

@@ -283,65 +282,63 @@ public static Try trying(CheckedRunnable runnable) { * * try-with-resources, introduced in Java 7. * - * @param aSupplier the resource supplier - * @param fn the function body - * @param the resource type - * @param the function return type + * @param fn0 the resource supplier + * @param fn the function body + * @param the resource type + * @param the function return type * @return a {@link Try} representing the result of the function's application to the resource */ @SuppressWarnings("try") public static Try withResources( - CheckedSupplier aSupplier, - CheckedFn1> fn) { + Fn0 fn0, + Fn1> fn) { return trying(() -> { - try (A resource = aSupplier.get()) { + try (A resource = fn0.apply()) { return fn.apply(resource).fmap(upcast()); } }).flatMap(id()); } /** - * Convenience overload of {@link Try#withResources(CheckedSupplier, CheckedFn1) withResources} that cascades - * dependent resource creation via nested calls. + * Convenience overload of {@link Try#withResources(Fn0, Fn1) withResources} that cascades dependent resource + * creation via nested calls. * - * @param aSupplier the first resource supplier - * @param bFn the dependent resource function - * @param fn the function body - * @param the first resource type - * @param the second resource type - * @param the function return type + * @param fn0 the first resource supplier + * @param bFn the dependent resource function + * @param fn the function body + * @param the first resource type + * @param the second resource type + * @param the function return type * @return a {@link Try} representing the result of the function's application to the dependent resource */ public static Try withResources( - CheckedSupplier aSupplier, - CheckedFn1 bFn, - CheckedFn1> fn) { - CheckedFn1> checkedFn = a -> withResources(() -> bFn.apply(a), fn::apply); - return withResources(aSupplier, checkedFn); + Fn0 fn0, + Fn1 bFn, + Fn1> fn) { + return withResources(fn0, a -> withResources(() -> bFn.apply(a), fn::apply)); } /** - * Convenience overload of {@link Try#withResources(CheckedSupplier, CheckedFn1, CheckedFn1) withResources} that + * Convenience overload of {@link Try#withResources(Fn0, Fn1, Fn1) withResources} that * cascades * two dependent resource creations via nested calls. * - * @param aSupplier the first resource supplier - * @param bFn the second resource function - * @param cFn the final resource function - * @param fn the function body - * @param the first resource type - * @param the second resource type - * @param the final resource type - * @param the function return type + * @param fn0 the first resource supplier + * @param bFn the second resource function + * @param cFn the final resource function + * @param fn the function body + * @param the first resource type + * @param the second resource type + * @param the final resource type + * @param the function return type * @return a {@link Try} representing the result of the function's application to the final dependent resource */ public static Try withResources( - CheckedSupplier aSupplier, - CheckedFn1 bFn, - CheckedFn1 cFn, - CheckedFn1> fn) { - CheckedFn1> checkedFn = b -> withResources(() -> cFn.apply(b), fn::apply); - return withResources(aSupplier, bFn, checkedFn); + Fn0 fn0, + Fn1 bFn, + Fn1 cFn, + Fn1> fn) { + return withResources(fn0, bFn, b -> withResources(() -> cFn.apply(b), fn::apply)); } private static final class Failure extends Try { diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedEffect.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedEffect.java index 65ee00c0e..e69de29bb 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedEffect.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedEffect.java @@ -1,107 +0,0 @@ -package com.jnape.palatable.lambda.functions.specialized.checked; - -import com.jnape.palatable.lambda.adt.Unit; -import com.jnape.palatable.lambda.functions.Effect; -import com.jnape.palatable.lambda.functions.Fn1; -import com.jnape.palatable.lambda.functor.Applicative; -import com.jnape.palatable.lambda.io.IO; - -import java.util.function.Consumer; -import java.util.function.Function; - -import static com.jnape.palatable.lambda.functions.specialized.checked.Runtime.throwChecked; -import static com.jnape.palatable.lambda.io.IO.io; - -/** - * Specialized {@link Effect} that can throw any {@link Throwable}. - * - * @param The {@link Throwable} type - * @param The input type - * @see CheckedRunnable - * @see CheckedFn1 - * @see Effect - */ -@FunctionalInterface -public interface CheckedEffect extends Effect, CheckedFn1> { - - /** - * {@inheritDoc} - */ - @Override - default void accept(A a) { - try { - checkedAccept(a); - } catch (Throwable t) { - throw throwChecked(t); - } - } - - /** - * {@inheritDoc} - */ - @Override - default IO apply(A a) { - return io(() -> accept(a)); - } - - /** - * {@inheritDoc} - */ - @Override - default IO checkedApply(A a) throws T { - return apply(a); - } - - /** - * {@inheritDoc} - */ - @Override - default CheckedEffect diMapL(Function fn) { - return Effect.super.diMapL(fn)::checkedAccept; - } - - /** - * {@inheritDoc} - */ - @Override - default CheckedEffect contraMap(Function fn) { - return Effect.super.contraMap(fn)::checkedAccept; - } - - /** - * {@inheritDoc} - */ - @Override - default CheckedEffect compose(Function before) { - return Effect.super.compose(before)::checkedAccept; - } - - /** - * {@inheritDoc} - */ - @Override - default CheckedEffect discardR(Applicative> appB) { - return Effect.super.discardR(appB)::checkedAccept; - } - - /** - * {@inheritDoc} - */ - @Override - default CheckedEffect andThen(Consumer after) { - return Effect.super.andThen(after)::checkedAccept; - } - - /** - * Convenience static factory method for constructing a {@link CheckedEffect} without an explicit cast or type - * attribution at the call site. - * - * @param checkedEffect the checked effect - * @param the inferred Throwable type - * @param the input type - * @return the checked effect - */ - static CheckedEffect checked(CheckedEffect checkedEffect) { - return checkedEffect; - } -} diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedFn1.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedFn1.java deleted file mode 100644 index 1c8fb76b6..000000000 --- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedFn1.java +++ /dev/null @@ -1,165 +0,0 @@ -package com.jnape.palatable.lambda.functions.specialized.checked; - -import com.jnape.palatable.lambda.adt.hlist.Tuple2; -import com.jnape.palatable.lambda.functions.Fn1; -import com.jnape.palatable.lambda.functions.Fn2; -import com.jnape.palatable.lambda.functor.Applicative; -import com.jnape.palatable.lambda.monad.Monad; - -import java.util.function.Function; - -import static com.jnape.palatable.lambda.functions.specialized.checked.Runtime.throwChecked; - -/** - * Specialized {@link Fn1} that can throw any {@link Throwable}. - * - * @param The {@link Throwable} type - * @param The input type - * @param The output type - * @see CheckedSupplier - * @see CheckedRunnable - * @see Fn1 - */ -@FunctionalInterface -public interface CheckedFn1 extends Fn1 { - - /** - * {@inheritDoc} - */ - @Override - default B apply(A a) { - try { - return checkedApply(a); - } catch (Throwable t) { - throw throwChecked(t); - } - } - - /** - * {@inheritDoc} - */ - @Override - default CheckedFn1 fmap(Function f) { - return Fn1.super.fmap(f)::checkedApply; - } - - /** - * {@inheritDoc} - */ - @Override - @SuppressWarnings("overrides") - default CheckedFn1 flatMap(Function>> f) { - return Fn1.super.flatMap(f).>coerce()::apply; - } - - /** - * {@inheritDoc} - */ - @Override - default CheckedFn1 discardL(Applicative> appB) { - return Fn1.super.discardL(appB)::checkedApply; - } - - /** - * {@inheritDoc} - */ - @Override - default CheckedFn1 discardR(Applicative> appB) { - return Fn1.super.discardR(appB)::checkedApply; - } - - /** - * {@inheritDoc} - */ - @Override - default CheckedFn1 zip(Applicative, Fn1> appFn) { - return Fn1.super.zip(appFn)::checkedApply; - } - - /** - * {@inheritDoc} - */ - @Override - default CheckedFn1 zip(Fn2 appFn) { - return Fn1.super.zip(appFn).coerce(); - } - - /** - * {@inheritDoc} - */ - @Override - default CheckedFn1 diMapL(Function fn) { - return Fn1.super.diMapL(fn).coerce(); - } - - /** - * {@inheritDoc} - */ - @Override - default CheckedFn1 diMapR(Function fn) { - return Fn1.super.diMapR(fn).coerce(); - } - - /** - * {@inheritDoc} - */ - @Override - default CheckedFn1 diMap(Function lFn, - Function rFn) { - return Fn1.super.diMap(lFn, rFn)::checkedApply; - } - - /** - * {@inheritDoc} - */ - @Override - default CheckedFn1, Tuple2> cartesian() { - return Fn1.super.cartesian()::checkedApply; - } - - /** - * {@inheritDoc} - */ - @Override - default CheckedFn1> carry() { - return Fn1.super.carry()::checkedApply; - } - - /** - * {@inheritDoc} - */ - @Override - default CheckedFn1 contraMap(Function fn) { - return Fn1.super.contraMap(fn).coerce(); - } - - /** - * {@inheritDoc} - */ - @Override - default CheckedFn1 compose(Function before) { - return Fn1.super.compose(before)::checkedApply; - } - - /** - * {@inheritDoc} - */ - @Override - default CheckedFn1 andThen(Function after) { - return Fn1.super.andThen(after)::checkedApply; - } - - /** - * Convenience static factory method for constructing a {@link CheckedFn1} without an explicit cast or type - * attribution at the call site. - * - * @param checkedFn1 the checked fn1 - * @param the inferred Throwable type - * @param the input type - * @param the output type - * @return the checked fn1 - */ - static CheckedFn1 checked(CheckedFn1 checkedFn1) { - return checkedFn1; - } -} diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedRunnable.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedRunnable.java index 954f4b952..c3f1bbd51 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedRunnable.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedRunnable.java @@ -1,16 +1,11 @@ package com.jnape.palatable.lambda.functions.specialized.checked; -import com.jnape.palatable.lambda.adt.Unit; - -import static com.jnape.palatable.lambda.adt.Unit.UNIT; import static com.jnape.palatable.lambda.functions.specialized.checked.Runtime.throwChecked; /** * Specialized {@link Runnable} that can throw any {@link Throwable}. * * @param The {@link Throwable} type - * @see CheckedSupplier - * @see CheckedFn1 */ @FunctionalInterface public interface CheckedRunnable extends Runnable { @@ -31,18 +26,6 @@ default void run() { } } - /** - * Convert this {@link CheckedRunnable} to a {@link CheckedSupplier} that returns {@link Unit}. - * - * @return the checked supplier - */ - default CheckedSupplier toSupplier() { - return () -> { - run(); - return UNIT; - }; - } - /** * Convenience static factory method for constructing a {@link CheckedRunnable} without an explicit cast or type * attribution at the call site. diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedSupplier.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedSupplier.java deleted file mode 100644 index 627da8c91..000000000 --- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedSupplier.java +++ /dev/null @@ -1,145 +0,0 @@ -package com.jnape.palatable.lambda.functions.specialized.checked; - -import com.jnape.palatable.lambda.adt.Unit; -import com.jnape.palatable.lambda.adt.hlist.Tuple2; -import com.jnape.palatable.lambda.functions.Fn1; -import com.jnape.palatable.lambda.functions.Fn2; -import com.jnape.palatable.lambda.functor.Applicative; -import com.jnape.palatable.lambda.monad.Monad; - -import java.util.function.Function; -import java.util.function.Supplier; - -import static com.jnape.palatable.lambda.adt.Unit.UNIT; -import static com.jnape.palatable.lambda.functions.specialized.checked.Runtime.throwChecked; - -/** - * Specialized {@link Supplier} that can throw any {@link Throwable}. - * - * @param The {@link Throwable} type - * @param The return type - * @see CheckedFn1 - * @see CheckedRunnable - */ -@FunctionalInterface -public interface CheckedSupplier extends Supplier, CheckedFn1 { - - /** - * A version of {@link Supplier#get()} that can throw checked exceptions. - * - * @return the supplied result - * @throws T any exception that can be thrown by this method - */ - A checkedGet() throws T; - - /** - * Convert this {@link CheckedSupplier} to a {@link CheckedRunnable}. - * - * @return the checked runnable - */ - default CheckedRunnable toRunnable() { - return this::get; - } - - @Override - default A checkedApply(Unit unit) throws T { - return checkedGet(); - } - - /** - * {@inheritDoc} - */ - @Override - default A get() { - try { - return checkedGet(); - } catch (Throwable t) { - throw throwChecked(t); - } - } - - /** - * {@inheritDoc} - */ - @Override - default CheckedSupplier fmap(Function f) { - return CheckedFn1.super.fmap(f).thunk(UNIT)::apply; - } - - /** - * {@inheritDoc} - */ - @Override - default CheckedSupplier flatMap(Function>> f) { - return CheckedFn1.super.flatMap(f).thunk(UNIT)::apply; - } - - /** - * {@inheritDoc} - */ - @Override - default CheckedSupplier discardL(Applicative> appB) { - return CheckedFn1.super.discardL(appB).thunk(UNIT)::apply; - } - - /** - * {@inheritDoc} - */ - @Override - default CheckedSupplier discardR(Applicative> appB) { - return CheckedFn1.super.discardR(appB).thunk(UNIT)::apply; - } - - /** - * {@inheritDoc} - */ - @Override - default CheckedSupplier zip(Applicative, Fn1> appFn) { - return CheckedFn1.super.zip(appFn).thunk(UNIT)::apply; - } - - /** - * {@inheritDoc} - */ - @Override - default CheckedSupplier zip(Fn2 appFn) { - return CheckedFn1.super.zip(appFn).thunk(UNIT)::apply; - } - - /** - * {@inheritDoc} - */ - @Override - default CheckedSupplier diMapR(Function fn) { - return CheckedFn1.super.diMapR(fn).thunk(UNIT)::apply; - } - - /** - * {@inheritDoc} - */ - @Override - default CheckedSupplier> carry() { - return CheckedFn1.super.carry().thunk(UNIT)::apply; - } - - /** - * {@inheritDoc} - */ - @Override - default CheckedSupplier andThen(Function after) { - return CheckedFn1.super.andThen(after).thunk(UNIT)::apply; - } - - /** - * Convenience static factory method for constructing a {@link CheckedSupplier} without an explicit cast or type - * attribution at the call site. - * - * @param supplier the checked supplier - * @param the inferred Throwable type - * @param the supplier return type - * @return the checked supplier - */ - static CheckedSupplier checked(CheckedSupplier supplier) { - return supplier::get; - } -} diff --git a/src/main/java/com/jnape/palatable/lambda/io/IO.java b/src/main/java/com/jnape/palatable/lambda/io/IO.java index 29c2e148b..d2e630e20 100644 --- a/src/main/java/com/jnape/palatable/lambda/io/IO.java +++ b/src/main/java/com/jnape/palatable/lambda/io/IO.java @@ -4,6 +4,7 @@ import com.jnape.palatable.lambda.adt.Unit; import com.jnape.palatable.lambda.adt.choice.Choice2; import com.jnape.palatable.lambda.adt.hlist.Tuple2; +import com.jnape.palatable.lambda.functions.Fn0; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; @@ -12,7 +13,6 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; import java.util.function.Function; -import java.util.function.Supplier; import static com.jnape.palatable.lambda.adt.choice.Choice2.a; import static com.jnape.palatable.lambda.adt.hlist.HList.tuple; @@ -22,7 +22,6 @@ import static com.jnape.palatable.lambda.functions.recursion.RecursiveResult.recurse; import static com.jnape.palatable.lambda.functions.recursion.RecursiveResult.terminate; import static com.jnape.palatable.lambda.functions.recursion.Trampoline.trampoline; -import static com.jnape.palatable.lambda.functions.specialized.checked.CheckedSupplier.checked; import static java.util.concurrent.CompletableFuture.completedFuture; import static java.util.concurrent.CompletableFuture.supplyAsync; import static java.util.concurrent.ForkJoinPool.commonPool; @@ -180,20 +179,20 @@ public CompletableFuture unsafePerformAsyncIO(Executor executor) { /** * Static factory method for coercing a lambda to an {@link IO}. * - * @param supplier the lambda to coerce - * @param the result type + * @param fn0 the lambda to coerce + * @param the result type * @return the {@link IO} */ - public static IO io(Supplier supplier) { + public static IO io(Fn0 fn0) { return new IO() { @Override public A unsafePerformIO() { - return supplier.get(); + return fn0.get(); } @Override public CompletableFuture unsafePerformAsyncIO(Executor executor) { - return supplyAsync(supplier, executor); + return supplyAsync(fn0::apply, executor); } }; } @@ -220,11 +219,11 @@ public static IO io(Runnable runnable) { * @param the result type * @return the {@link IO} */ - public static IO externallyManaged(Supplier> supplier) { + public static IO externallyManaged(Fn0> supplier) { return new IO() { @Override public A unsafePerformIO() { - return checked(() -> unsafePerformAsyncIO().get()).get(); + return fn0(() -> unsafePerformAsyncIO().get()).apply(); } @Override diff --git a/src/test/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedEffectTest.java b/src/test/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedEffectTest.java deleted file mode 100644 index 8472dc067..000000000 --- a/src/test/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedEffectTest.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.jnape.palatable.lambda.functions.specialized.checked; - -import org.junit.Test; - -import java.util.ArrayList; -import java.util.List; - -import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; -import static java.util.Arrays.asList; -import static org.junit.Assert.assertEquals; - -public class CheckedEffectTest { - - @Test - public void assignment() { - List results = new ArrayList<>(); - - CheckedEffect effect = results::add; - CheckedEffect diMapL = effect.diMapL(Object::toString); - CheckedEffect contraMap = effect.contraMap(Object::toString); - CheckedEffect compose = effect.compose(Object::toString); - CheckedEffect stringEffect = effect.discardR(constantly("1")); - CheckedEffect andThen = effect.andThen(effect); - - effect.accept("1"); - diMapL.accept("2"); - contraMap.accept("3"); - compose.accept("4"); - stringEffect.accept("5"); - andThen.accept("6"); - - assertEquals(asList("1", "2", "3", "4", "5", "6", "6"), results); - } -} \ No newline at end of file diff --git a/src/test/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedFn1Test.java b/src/test/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedFn1Test.java deleted file mode 100644 index c5b614755..000000000 --- a/src/test/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedFn1Test.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.jnape.palatable.lambda.functions.specialized.checked; - -import com.jnape.palatable.lambda.adt.hlist.Tuple2; -import org.junit.Test; - -import static com.jnape.palatable.lambda.adt.hlist.HList.tuple; -import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; -import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id; -import static org.junit.Assert.assertEquals; - -public class CheckedFn1Test { - - @Test - public void assignment() { - CheckedFn1 parseInt = Integer::parseInt; - CheckedFn1 fmap = parseInt.fmap(Object::toString); - CheckedFn1 flatMap = parseInt.flatMap(i -> constantly(i + "")); - CheckedFn1 discardL = parseInt.discardL(constantly("0")); - CheckedFn1 discardR = parseInt.discardR(constantly("0")); - CheckedFn1 zipApp = parseInt.zip(constantly(id())); - CheckedFn1 zipF = parseInt.zip(constantly()); - CheckedFn1 diMapL = parseInt.diMapL(id()); - CheckedFn1 diMapR = parseInt.diMapR(id()); - CheckedFn1 diMap = parseInt.diMap(id(), id()); - CheckedFn1, Tuple2> strengthen = parseInt.cartesian(); - CheckedFn1> carry = parseInt.carry(); - CheckedFn1 contraMap = parseInt.contraMap(id()); - CheckedFn1 compose = parseInt.compose(id()); - CheckedFn1 andThen = parseInt.andThen(id()); - - assertEquals((Integer) 1, parseInt.apply("1")); - assertEquals("1", fmap.apply("1")); - assertEquals("1", flatMap.apply("1")); - assertEquals("0", discardL.apply("1")); - assertEquals((Integer) 1, discardR.apply("1")); - assertEquals((Integer) 1, zipApp.apply("1")); - assertEquals("1", zipF.apply("1")); - assertEquals((Integer) 1, diMapL.apply("1")); - assertEquals((Integer) 1, diMapR.apply("1")); - assertEquals((Integer) 1, diMap.apply("1")); - assertEquals(tuple("foo", 1), strengthen.apply(tuple("foo", "1"))); - assertEquals(tuple("1", 1), carry.apply("1")); - assertEquals((Integer) 1, contraMap.apply("1")); - assertEquals((Integer) 1, compose.apply("1")); - assertEquals((Integer) 1, andThen.apply("1")); - } -} \ No newline at end of file diff --git a/src/test/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedSupplierTest.java b/src/test/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedSupplierTest.java deleted file mode 100644 index 804b77ca0..000000000 --- a/src/test/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedSupplierTest.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.jnape.palatable.lambda.functions.specialized.checked; - -import com.jnape.palatable.lambda.adt.Unit; -import com.jnape.palatable.lambda.adt.hlist.Tuple2; -import com.jnape.palatable.lambda.functions.builtin.fn1.Constantly; -import org.junit.Test; - -import static com.jnape.palatable.lambda.adt.Unit.UNIT; -import static com.jnape.palatable.lambda.adt.hlist.HList.tuple; -import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; -import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id; -import static com.jnape.palatable.lambda.functions.specialized.checked.CheckedSupplier.checked; -import static org.junit.Assert.assertEquals; - -public class CheckedSupplierTest { - - @Test - public void assignment() { - CheckedSupplier intSupplier = checked(() -> 1); - CheckedSupplier fmap = intSupplier.fmap(Object::toString); - @SuppressWarnings("RedundantTypeArguments") - CheckedSupplier flatMap = intSupplier.flatMap(Constantly::constantly); - CheckedSupplier discardL = intSupplier.discardL(constantly(1)); - CheckedSupplier discardR = intSupplier.discardR(constantly(2)); - CheckedSupplier zipA = intSupplier.zip(constantly(id())); - CheckedSupplier zipF = intSupplier.zip(constantly()); - CheckedSupplier diMapR = intSupplier.diMapR(id()); - CheckedSupplier> carry = intSupplier.carry(); - CheckedSupplier andThen = intSupplier.andThen(id()); - - assertEquals((Integer) 1, intSupplier.get()); - assertEquals("1", fmap.get()); - assertEquals((Integer) 1, flatMap.get()); - assertEquals((Integer) 1, discardL.get()); - assertEquals((Integer) 1, discardR.get()); - assertEquals((Integer) 1, zipA.get()); - assertEquals(UNIT, zipF.get()); - assertEquals((Integer) 1, diMapR.get()); - assertEquals(tuple(UNIT, 1), carry.get()); - assertEquals((Integer) 1, andThen.get()); - } -} \ No newline at end of file diff --git a/src/test/java/com/jnape/palatable/lambda/io/IOTest.java b/src/test/java/com/jnape/palatable/lambda/io/IOTest.java index 674bb8e8d..c6bd42b16 100644 --- a/src/test/java/com/jnape/palatable/lambda/io/IOTest.java +++ b/src/test/java/com/jnape/palatable/lambda/io/IOTest.java @@ -19,7 +19,6 @@ import static com.jnape.palatable.lambda.adt.Unit.UNIT; import static com.jnape.palatable.lambda.functions.builtin.fn2.Tupler2.tupler; import static com.jnape.palatable.lambda.functions.builtin.fn3.Times.times; -import static com.jnape.palatable.lambda.functions.specialized.checked.CheckedSupplier.checked; import static com.jnape.palatable.lambda.io.IO.externallyManaged; import static com.jnape.palatable.lambda.io.IO.io; import static java.util.concurrent.CompletableFuture.completedFuture; @@ -55,23 +54,23 @@ public void unsafePerformAsyncIOWithExecutor() { @Test public void zipAndDerivativesComposesInParallel() { - String a = "foo"; + String a = "foo"; Fn1> f = tupler(1); - ExecutorService executor = newFixedThreadPool(2); - CountDownLatch advanceFirst = new CountDownLatch(1); - CountDownLatch advanceSecond = new CountDownLatch(1); + ExecutorService executor = newFixedThreadPool(2); + CountDownLatch advanceFirst = new CountDownLatch(1); + CountDownLatch advanceSecond = new CountDownLatch(1); - IO ioA = io(checked(() -> { + IO ioA = io(() -> { advanceFirst.countDown(); advanceSecond.await(); return a; - })); - IO>> ioF = io(checked(() -> { + }); + IO>> ioF = io(() -> { advanceFirst.await(); advanceSecond.countDown(); return f; - })); + }); IO> zip = ioA.zip(ioF); assertEquals(f.apply(a), zip.unsafePerformAsyncIO().join()); @@ -90,7 +89,7 @@ public void zipAndDerivativesComposesInParallel() { @Test public void delegatesToExternallyManagedFuture() { CompletableFuture future = completedFuture(1); - IO io = externallyManaged(() -> future); + IO io = externallyManaged(() -> future); assertEquals((Integer) 1, io.unsafePerformIO()); assertEquals((Integer) 1, io.unsafePerformAsyncIO().join()); assertEquals((Integer) 1, io.unsafePerformAsyncIO(commonPool()).join()); From 20e00f5de95fe234d4b11679d3e5497ebfe86895 Mon Sep 17 00:00:00 2001 From: jnape Date: Mon, 6 May 2019 20:08:49 -0500 Subject: [PATCH 37/69] Deleting empty file --- .../lambda/functions/specialized/checked/CheckedEffect.java | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedEffect.java diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedEffect.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedEffect.java deleted file mode 100644 index e69de29bb..000000000 From eb596f80c34d473d7ab1dd0f2a96bff202b1860e Mon Sep 17 00:00:00 2001 From: jnape Date: Mon, 6 May 2019 20:22:47 -0500 Subject: [PATCH 38/69] Cutting all java.util.function/Runnable/Callable ties - Function replaced with Fn1 - BiFunction replaced with Fn2 - Supplier replaced with Fn0 - Consumer replaced with Effect - Runnable replaced with SideEffect in IO - j.u.f.Predicate replaced with Predicate - j.u.f.BiPredicate replaced with BiPredicate --- CHANGELOG.md | 12 +- .../jnape/palatable/lambda/adt/Either.java | 141 +++++++++--------- .../com/jnape/palatable/lambda/adt/Maybe.java | 48 +++--- .../com/jnape/palatable/lambda/adt/These.java | 41 ++--- .../com/jnape/palatable/lambda/adt/Try.java | 66 ++++---- .../palatable/lambda/adt/choice/Choice2.java | 32 ++-- .../palatable/lambda/adt/choice/Choice3.java | 44 +++--- .../palatable/lambda/adt/choice/Choice4.java | 52 +++---- .../palatable/lambda/adt/choice/Choice5.java | 67 ++++----- .../palatable/lambda/adt/choice/Choice6.java | 69 ++++----- .../palatable/lambda/adt/choice/Choice7.java | 97 ++++++------ .../palatable/lambda/adt/choice/Choice8.java | 105 ++++++------- .../lambda/adt/coproduct/CoProduct2.java | 17 +-- .../lambda/adt/coproduct/CoProduct3.java | 35 ++--- .../lambda/adt/coproduct/CoProduct4.java | 51 +++---- .../lambda/adt/coproduct/CoProduct5.java | 63 +++----- .../lambda/adt/coproduct/CoProduct6.java | 40 ++--- .../lambda/adt/coproduct/CoProduct7.java | 46 +++--- .../lambda/adt/coproduct/CoProduct8.java | 45 +++--- .../lambda/adt/hlist/SingletonHList.java | 19 +-- .../palatable/lambda/adt/hlist/Tuple2.java | 23 ++- .../palatable/lambda/adt/hlist/Tuple3.java | 24 +-- .../palatable/lambda/adt/hlist/Tuple4.java | 26 ++-- .../palatable/lambda/adt/hlist/Tuple5.java | 24 ++- .../palatable/lambda/adt/hlist/Tuple6.java | 24 ++- .../palatable/lambda/adt/hlist/Tuple7.java | 24 ++- .../palatable/lambda/adt/hlist/Tuple8.java | 24 ++- .../lambda/adt/product/Product2.java | 6 +- .../lambda/adt/product/Product3.java | 2 +- .../lambda/adt/product/Product4.java | 3 +- .../palatable/lambda/functions/Effect.java | 82 +++++----- .../jnape/palatable/lambda/functions/Fn0.java | 81 +++++----- .../jnape/palatable/lambda/functions/Fn1.java | 97 +++++------- .../jnape/palatable/lambda/functions/Fn2.java | 29 +--- .../jnape/palatable/lambda/functions/Fn3.java | 12 +- .../jnape/palatable/lambda/functions/Fn4.java | 12 +- .../jnape/palatable/lambda/functions/Fn5.java | 12 +- .../jnape/palatable/lambda/functions/Fn6.java | 12 +- .../jnape/palatable/lambda/functions/Fn7.java | 12 +- .../jnape/palatable/lambda/functions/Fn8.java | 13 +- .../lambda/functions/builtin/fn1/Empty.java | 2 +- .../lambda/functions/builtin/fn1/Inits.java | 2 +- .../functions/builtin/fn1/Magnetize.java | 2 +- .../lambda/functions/builtin/fn1/Not.java | 11 +- .../lambda/functions/builtin/fn2/All.java | 10 +- .../lambda/functions/builtin/fn2/Any.java | 11 +- .../lambda/functions/builtin/fn2/Both.java | 21 +-- .../functions/builtin/fn2/DropWhile.java | 10 +- .../lambda/functions/builtin/fn2/Filter.java | 10 +- .../lambda/functions/builtin/fn2/Find.java | 10 +- .../lambda/functions/builtin/fn2/GroupBy.java | 9 +- .../lambda/functions/builtin/fn2/Into.java | 13 +- .../lambda/functions/builtin/fn2/Into1.java | 14 +- .../lambda/functions/builtin/fn2/Into3.java | 2 +- .../lambda/functions/builtin/fn2/Iterate.java | 16 +- .../lambda/functions/builtin/fn2/LazyRec.java | 18 +-- .../functions/builtin/fn2/MagnetizeBy.java | 9 +- .../lambda/functions/builtin/fn2/Map.java | 10 +- .../functions/builtin/fn2/Partial2.java | 41 ----- .../functions/builtin/fn2/Partial3.java | 41 ----- .../functions/builtin/fn2/Partition.java | 9 +- .../lambda/functions/builtin/fn2/Peek.java | 18 +-- .../lambda/functions/builtin/fn2/Peek2.java | 30 ++-- .../functions/builtin/fn2/ReduceLeft.java | 11 +- .../functions/builtin/fn2/ReduceRight.java | 12 +- .../functions/builtin/fn2/Sequence.java | 30 ++-- .../lambda/functions/builtin/fn2/SortBy.java | 12 +- .../lambda/functions/builtin/fn2/Span.java | 12 +- .../functions/builtin/fn2/TakeWhile.java | 10 +- .../functions/builtin/fn2/ToCollection.java | 22 +-- .../lambda/functions/builtin/fn2/ToMap.java | 22 +-- .../lambda/functions/builtin/fn2/Unfoldr.java | 10 +- .../lambda/functions/builtin/fn2/Zip.java | 3 +- .../lambda/functions/builtin/fn3/CmpEqBy.java | 19 +-- .../functions/builtin/fn3/FoldLeft.java | 20 ++- .../functions/builtin/fn3/FoldRight.java | 22 ++- .../lambda/functions/builtin/fn3/GTBy.java | 19 +-- .../lambda/functions/builtin/fn3/GTEBy.java | 20 +-- .../lambda/functions/builtin/fn3/LTBy.java | 21 +-- .../lambda/functions/builtin/fn3/LTEBy.java | 19 ++- .../lambda/functions/builtin/fn3/LiftA2.java | 16 +- .../functions/builtin/fn3/ScanLeft.java | 25 ++-- .../lambda/functions/builtin/fn3/Times.java | 12 +- .../lambda/functions/builtin/fn3/ZipWith.java | 10 +- .../functions/builtin/fn4/IfThenElse.java | 29 ++-- .../functions/builtin/fn4/RateLimit.java | 43 +++--- .../functions/recursion/RecursiveResult.java | 27 ++-- .../functions/recursion/Trampoline.java | 18 +-- .../functions/specialized/BiPredicate.java | 66 ++++---- .../lambda/functions/specialized/Kleisli.java | 18 +-- .../lambda/functions/specialized/Noop.java | 8 +- .../functions/specialized/Predicate.java | 84 +++++++---- .../functions/specialized/SideEffect.java | 54 +++++++ .../specialized/checked/CheckedRunnable.java | 41 ----- .../palatable/lambda/functor/Applicative.java | 9 +- .../palatable/lambda/functor/Bifunctor.java | 8 +- .../lambda/functor/BoundedBifunctor.java | 16 +- .../palatable/lambda/functor/Cartesian.java | 11 +- .../palatable/lambda/functor/Cocartesian.java | 11 +- .../lambda/functor/Contravariant.java | 7 +- .../palatable/lambda/functor/Functor.java | 4 +- .../palatable/lambda/functor/Profunctor.java | 10 +- .../lambda/functor/builtin/Compose.java | 18 +-- .../lambda/functor/builtin/Const.java | 25 ++-- .../lambda/functor/builtin/Exchange.java | 29 ++-- .../lambda/functor/builtin/Identity.java | 16 +- .../lambda/functor/builtin/Lazy.java | 32 ++-- .../lambda/functor/builtin/Market.java | 28 ++-- .../lambda/functor/builtin/State.java | 10 +- .../lambda/functor/builtin/Tagged.java | 18 +-- .../com/jnape/palatable/lambda/io/IO.java | 49 +++--- .../lambda/iteration/ConsingIterator.java | 13 +- .../lambda/iteration/FilteringIterable.java | 13 +- .../lambda/iteration/FilteringIterator.java | 9 +- .../lambda/iteration/MappingIterable.java | 17 ++- .../lambda/iteration/MappingIterator.java | 9 +- .../iteration/PredicatedDroppingIterable.java | 14 +- .../iteration/PredicatedDroppingIterator.java | 11 +- .../iteration/PredicatedTakingIterable.java | 13 +- .../iteration/PredicatedTakingIterator.java | 12 +- .../iteration/RateLimitingIterable.java | 9 +- .../iteration/RateLimitingIterator.java | 20 +-- .../lambda/iteration/ScanningIterator.java | 11 +- .../lambda/iteration/UnfoldingIterator.java | 14 +- .../lambda/iteration/ZippingIterator.java | 11 +- .../jnape/palatable/lambda/monad/Monad.java | 19 ++- .../lambda/monad/transformer/MonadT.java | 13 +- .../monad/transformer/builtin/EitherT.java | 16 +- .../monad/transformer/builtin/IdentityT.java | 15 +- .../monad/transformer/builtin/LazyT.java | 18 +-- .../monad/transformer/builtin/MaybeT.java | 13 +- .../jnape/palatable/lambda/monoid/Monoid.java | 15 +- .../lambda/monoid/builtin/AddAll.java | 23 ++- .../palatable/lambda/monoid/builtin/And.java | 9 +- .../lambda/monoid/builtin/Compose.java | 4 +- .../lambda/monoid/builtin/Concat.java | 3 +- .../lambda/monoid/builtin/First.java | 4 +- .../lambda/monoid/builtin/MergeMaps.java | 26 ++-- .../palatable/lambda/monoid/builtin/Or.java | 9 +- .../palatable/lambda/monoid/builtin/Xor.java | 5 - .../jnape/palatable/lambda/optics/Iso.java | 39 +++-- .../jnape/palatable/lambda/optics/Lens.java | 37 +++-- .../jnape/palatable/lambda/optics/Optic.java | 15 +- .../jnape/palatable/lambda/optics/Prism.java | 13 +- .../lambda/optics/functions/Over.java | 12 +- .../lambda/optics/functions/Under.java | 14 +- .../lambda/optics/lenses/CollectionLens.java | 9 +- .../lambda/optics/lenses/IterableLens.java | 2 +- .../lambda/optics/lenses/MapLens.java | 26 ++-- .../lambda/optics/lenses/SetLens.java | 51 ++++++- .../palatable/lambda/semigroup/Semigroup.java | 2 +- .../lambda/semigroup/builtin/Absent.java | 2 +- .../lambda/semigroup/builtin/MaxBy.java | 13 +- .../lambda/semigroup/builtin/MinBy.java | 13 +- .../lambda/semigroup/builtin/RightAny.java | 2 +- .../lambda/traversable/LambdaIterable.java | 16 +- .../lambda/traversable/LambdaMap.java | 19 ++- .../lambda/traversable/Traversable.java | 11 +- .../palatable/lambda/adt/EitherTest.java | 47 +++--- .../jnape/palatable/lambda/adt/MaybeTest.java | 5 +- .../lambda/adt/choice/Choice6Test.java | 5 +- .../lambda/adt/choice/Choice7Test.java | 5 +- .../lambda/adt/choice/Choice8Test.java | 6 +- .../lambda/adt/coproduct/CoProduct2Test.java | 7 +- .../lambda/adt/coproduct/CoProduct3Test.java | 17 +-- .../lambda/adt/coproduct/CoProduct4Test.java | 30 ++-- .../lambda/adt/coproduct/CoProduct5Test.java | 47 +++--- .../lambda/adt/coproduct/CoProduct6Test.java | 41 +++-- .../lambda/adt/coproduct/CoProduct7Test.java | 61 ++++---- .../lambda/adt/coproduct/CoProduct8Test.java | 69 +++++---- .../lambda/adt/hlist/Tuple2Test.java | 11 +- .../lambda/adt/hlist/Tuple3Test.java | 9 +- .../lambda/adt/hlist/Tuple4Test.java | 13 +- .../lambda/adt/hlist/Tuple5Test.java | 15 +- .../lambda/adt/hlist/Tuple6Test.java | 15 +- .../lambda/adt/hlist/Tuple7Test.java | 15 +- .../lambda/adt/hlist/Tuple8Test.java | 19 ++- .../lambda/functions/EffectTest.java | 31 ++-- .../palatable/lambda/functions/Fn0Test.java | 39 +++++ .../palatable/lambda/functions/Fn1Test.java | 18 ++- .../palatable/lambda/functions/Fn2Test.java | 15 +- .../functions/builtin/fn1/FlattenTest.java | 2 +- .../lambda/functions/builtin/fn2/AllTest.java | 4 +- .../functions/builtin/fn2/AlterTest.java | 3 +- .../lambda/functions/builtin/fn2/AnyTest.java | 4 +- .../builtin/fn2/MagnetizeByTest.java | 12 +- .../functions/builtin/fn2/Partial2Test.java | 18 --- .../functions/builtin/fn2/Partial3Test.java | 18 --- .../functions/builtin/fn2/PartitionTest.java | 4 +- .../functions/builtin/fn2/Peek2Test.java | 14 +- .../functions/builtin/fn2/PeekTest.java | 5 +- .../functions/builtin/fn2/SequenceTest.java | 7 +- .../builtin/fn2/ToCollectionTest.java | 5 +- .../functions/builtin/fn3/LiftA2Test.java | 7 +- .../functions/builtin/fn3/ZipWithTest.java | 10 +- .../functions/builtin/fn4/RateLimitTest.java | 5 +- .../functions/recursion/TrampolineTest.java | 5 +- .../specialized/BiPredicateTest.java | 46 ++++-- .../functions/specialized/PredicateTest.java | 56 ++++--- .../functions/specialized/SideEffectTest.java | 28 ++++ .../lambda/functor/BifunctorTest.java | 6 +- .../lambda/functor/ProfunctorTest.java | 6 +- .../com/jnape/palatable/lambda/io/IOTest.java | 5 +- .../iteration/ScanningIteratorTest.java | 4 +- .../lambda/iteration/ZippingIteratorTest.java | 8 +- .../palatable/lambda/optics/PrismTest.java | 6 +- .../traversable/LambdaIterableTest.java | 7 +- src/test/java/testsupport/EquatableM.java | 18 +-- .../InvocationRecordingBifunctor.java | 13 +- .../InvocationRecordingProfunctor.java | 14 +- .../testsupport/functions/ExplainFold.java | 4 +- .../testsupport/matchers/LeftMatcher.java | 7 +- .../testsupport/matchers/RightMatcher.java | 7 +- .../testsupport/traits/ApplicativeLaws.java | 41 ++--- .../testsupport/traits/BifunctorLaws.java | 5 +- .../java/testsupport/traits/FunctorLaws.java | 17 ++- .../java/testsupport/traits/MonadLaws.java | 12 +- .../testsupport/traits/TraversableLaws.java | 28 ++-- 218 files changed, 2218 insertions(+), 2434 deletions(-) delete mode 100644 src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partial2.java delete mode 100644 src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partial3.java create mode 100644 src/main/java/com/jnape/palatable/lambda/functions/specialized/SideEffect.java delete mode 100644 src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedRunnable.java create mode 100644 src/test/java/com/jnape/palatable/lambda/functions/Fn0Test.java delete mode 100644 src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partial2Test.java delete mode 100644 src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partial3Test.java create mode 100644 src/test/java/com/jnape/palatable/lambda/functions/specialized/SideEffectTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index bad86b559..76b7ca7cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,12 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/). factory methods should continue to work (by simply targeting `Supplier` now instead of an anonymous `IO`), but some might need to be reworked, and subtyping is obviously no longer supported. +- ***Breaking Change***: Breaking all dependency on `java.util.function` types across the board. All `Fn*` types target + methods now support throwing `Throwable`; `apply` is now defaulted and will simply bypass javac + to throw checked exceptions as if they were unchecked. All `Checked` variants have been + eliminated as a consequence, as they are no longer necessary. Also, straggler functions like + `Partial2/3` that only existed to aid in partial application of non-curried functions are now + superfluous, and have also been eliminated. - ***Breaking Change***: `FoldRight` now requires `Lazy` as part of its interface to support short-circuiting operations - ***Breaking Change***: Eliminated all raw types and java11 warnings. This required using capture in unification parameters for Functor and friends, so nearly every functor's type-signature changed. @@ -17,11 +23,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/). type is now the supertype of `Lens` and `Iso`, and `lens` package has been moved to `optics` - ***Breaking Change***: `Try` and `Either` no longer preserve `Throwable` type since it was inherently not type-safe anyway; Try is therefore no longer a `Bifunctor`, and `orThrow` can be used to declare checked - exceptions that could be caught by corresponding catch blocks -- ***Breaking Change***: All `Fn*` types target methods now support throwing `Throwable`; `apply` is now defaulted and - will simply bypass javac to throw checked exceptions as if they were unchecked. This allows all - checked variants to be eliminated -- ***Breaking Change***: All `Checked` variants have been eliminated + exceptions that could be caught by corresponding catch blocks - `IO` is now stack-safe, regardless of whether the composition nests linearly or recursively ### Added diff --git a/src/main/java/com/jnape/palatable/lambda/adt/Either.java b/src/main/java/com/jnape/palatable/lambda/adt/Either.java index e6c0aeebb..1148c0523 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/Either.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/Either.java @@ -2,12 +2,13 @@ import com.jnape.palatable.lambda.adt.choice.Choice3; import com.jnape.palatable.lambda.adt.coproduct.CoProduct2; -import com.jnape.palatable.lambda.functions.Fn1; +import com.jnape.palatable.lambda.functions.Effect; import com.jnape.palatable.lambda.functions.Fn0; import com.jnape.palatable.lambda.functions.Fn1; +import com.jnape.palatable.lambda.functions.Fn2; import com.jnape.palatable.lambda.functions.builtin.fn2.Peek; import com.jnape.palatable.lambda.functions.builtin.fn2.Peek2; -import com.jnape.palatable.lambda.functions.specialized.checked.CheckedRunnable; +import com.jnape.palatable.lambda.functions.specialized.SideEffect; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; import com.jnape.palatable.lambda.functor.builtin.Lazy; @@ -15,10 +16,6 @@ import com.jnape.palatable.lambda.traversable.Traversable; import java.util.Objects; -import java.util.function.BiFunction; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Supplier; import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id; import static com.jnape.palatable.lambda.functions.builtin.fn3.FoldLeft.foldLeft; @@ -59,7 +56,7 @@ public final R or(R defaultValue) { * @param recoveryFn a function from L to R * @return either the wrapped value (if right) or the result of the left value applied to recoveryFn */ - public final R recover(Function recoveryFn) { + public final R recover(Fn1 recoveryFn) { return match(recoveryFn, id()); } @@ -70,7 +67,7 @@ public final R recover(Function recoveryFn) { * @param forfeitFn a function from R to L * @return either the wrapped value (if left) or the result of the right value applied to forfeitFn */ - public final L forfeit(Function forfeitFn) { + public final L forfeit(Fn1 forfeitFn) { return match(id(), forfeitFn); } @@ -78,13 +75,13 @@ public final L forfeit(Function forfeitFn) { * Return the wrapped value if this is a right; otherwise, map the wrapped left value to a T and throw * it. * - * @param throwableFn a function from L to T * @param the left parameter type (the throwable type) + * @param throwableFn a function from L to T * @return the wrapped value if this is a right * @throws T the result of applying the wrapped left value to throwableFn, if this is a left */ - public final R orThrow(Function throwableFn) throws T { - return match((Fn1) l -> { + public final R orThrow(Fn1 throwableFn) throws T { + return match(l -> { throw throwableFn.apply(l); }, id()); } @@ -95,13 +92,13 @@ public final R orThrow(Function th *

* If this is a left value, return it. * - * @param pred the predicate to apply to a right value - * @param leftSupplier the supplier of a left value if pred fails + * @param pred the predicate to apply to a right value + * @param leftFn0 the supplier of a left value if pred fails * @return this if a left value or a right value that pred matches; otherwise, the result of leftSupplier wrapped in * a left */ - public final Either filter(Function pred, Supplier leftSupplier) { - return filter(pred, __ -> leftSupplier.get()); + public final Either filter(Fn1 pred, Fn0 leftFn0) { + return filter(pred, __ -> leftFn0.apply()); } /** @@ -113,8 +110,8 @@ public final Either filter(Function pred, Su * @return this is a left value or a right value that pred matches; otherwise, the result of leftFn applied to the * right value, wrapped in a left */ - public final Either filter(Function pred, - Function leftFn) { + public final Either filter(Fn1 pred, + Fn1 leftFn) { return flatMap(r -> pred.apply(r) ? right(r) : left(leftFn.apply(r))); } @@ -131,8 +128,8 @@ public final Either filter(Function pred, */ @Override @SuppressWarnings("RedundantTypeArguments") - public Either flatMap(Function>> rightFn) { - return match(Either::left, rightFn.andThen(Monad>::coerce)); + public Either flatMap(Fn1>> rightFn) { + return match(Either::left, rightFn.fmap(Monad>::coerce)); } @Override @@ -153,8 +150,8 @@ public final Either invert() { */ @SafeVarargs @SuppressWarnings("varargs") - public final Either merge(BiFunction leftFn, - BiFunction rightFn, + public final Either merge(Fn2 leftFn, + Fn2 rightFn, Either... others) { return foldLeft((x, y) -> x.match(l1 -> y.match(l2 -> left(leftFn.apply(l1, l2)), r -> left(l1)), r1 -> y.match(Either::left, r2 -> right(rightFn.apply(r1, r2)))), @@ -165,22 +162,22 @@ public final Either merge(BiFunction le /** * Perform side-effects against a wrapped right value, returning back the Either unaltered. * - * @param rightConsumer the effecting consumer + * @param effect the effecting consumer * @return the Either, unaltered */ - public Either peek(Consumer rightConsumer) { - return Peek.peek(rightConsumer, this); + public Either peek(Effect effect) { + return Peek.peek(effect, this); } /** * Perform side-effects against a wrapped right or left value, returning back the Either unaltered. * - * @param leftConsumer the effecting consumer for left values - * @param rightConsumer the effecting consumer for right values + * @param leftEffect the effecting consumer for left values + * @param rightEffect the effecting consumer for right values * @return the Either, unaltered */ - public Either peek(Consumer leftConsumer, Consumer rightConsumer) { - return Peek2.peek2(leftConsumer, rightConsumer, this); + public Either peek(Effect leftEffect, Effect rightEffect) { + return Peek2.peek2(leftEffect, rightEffect, this); } /** @@ -188,13 +185,13 @@ public Either peek(Consumer leftConsumer, Consumer rightConsumer) { * V), unwrap the value stored in this Either, apply the appropriate mapping function, * and return the result. * + * @param the result type * @param leftFn the left value mapping function * @param rightFn the right value mapping function - * @param the result type * @return the result of applying the appropriate mapping function to the wrapped value */ @Override - public abstract V match(Function leftFn, Function rightFn); + public abstract V match(Fn1 leftFn, Fn1 rightFn); /** * {@inheritDoc} @@ -208,7 +205,7 @@ public Choice3 diverge() { * {@inheritDoc} */ @Override - public final Either fmap(Function fn) { + public final Either fmap(Fn1 fn) { return Monad.super.fmap(fn).coerce(); } @@ -216,26 +213,24 @@ public final Either fmap(Function fn) { * {@inheritDoc} */ @Override - @SuppressWarnings("unchecked") - public final Either biMapL(Function fn) { - return (Either) Bifunctor.super.biMapL(fn); + public final Either biMapL(Fn1 fn) { + return (Either) Bifunctor.super.biMapL(fn); } /** * {@inheritDoc} */ @Override - @SuppressWarnings("unchecked") - public final Either biMapR(Function fn) { - return (Either) Bifunctor.super.biMapR(fn); + public final Either biMapR(Fn1 fn) { + return (Either) Bifunctor.super.biMapR(fn); } /** * {@inheritDoc} */ @Override - public final Either biMap(Function leftFn, - Function rightFn) { + public final Either biMap(Fn1 leftFn, + Fn1 rightFn) { return match(l -> left(leftFn.apply(l)), r -> right(rightFn.apply(r))); } @@ -251,8 +246,8 @@ public final Either pure(R2 r2) { * {@inheritDoc} */ @Override - public final Either zip(Applicative, Either> appFn) { - return appFn.>>coerce().flatMap(this::biMapR); + public final Either zip(Applicative, Either> appFn) { + return Monad.super.zip(appFn).coerce(); } /** @@ -260,7 +255,7 @@ public final Either zip(Applicative Lazy> lazyZip( - Lazy, Either>> lazyAppFn) { + Lazy, Either>> lazyAppFn) { return match(l -> lazy(left(l)), r -> lazyAppFn.fmap(eitherLF -> eitherLF.fmap(f -> f.apply(r)).coerce())); } @@ -288,8 +283,8 @@ public final Either discardR(Applicative> appB) { @SuppressWarnings("unchecked") public final , TravB extends Traversable>, AppB extends Applicative, - AppTrav extends Applicative> AppTrav traverse(Function fn, - Function pure) { + AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + Fn1 pure) { return (AppTrav) match(l -> pure.apply((TravB) left(l)), r -> fn.apply(r).fmap(Either::right)); } @@ -307,67 +302,65 @@ public final Maybe toMaybe() { * Convert a {@link Maybe}<R> into an Either<L, R>, supplying the left value from * leftFn in the case of {@link Maybe#nothing()}. * - * @param maybe the maybe - * @param leftFn the supplier to use for left values - * @param the left parameter type - * @param the right parameter type + * @param the left parameter type + * @param the right parameter type + * @param maybe the maybe + * @param leftFn0 the supplier to use for left values * @return a right value of the contained maybe value, or a left value of leftFn's result */ - public static Either fromMaybe(Maybe maybe, Supplier leftFn) { + public static Either fromMaybe(Maybe maybe, Fn0 leftFn0) { return maybe.>fmap(Either::right) - .orElseGet(() -> left(leftFn.get())); + .orElseGet(() -> left(leftFn0.apply())); } /** * Attempt to execute the {@link Fn0}, returning its result in a right value. If the supplier throws an * exception, apply leftFn to it, wrap it in a left value and return it. * - * @param supplier the supplier of the right value - * @param leftFn a function mapping E to L - * @param the left parameter type - * @param the right parameter type + * @param the left parameter type + * @param the right parameter type + * @param fn0 the supplier of the right value + * @param leftFn a function mapping E to L * @return the supplier result as a right value, or leftFn's mapping result as a left value */ - public static Either trying(Fn0 supplier, - Function leftFn) { - return Try.trying(supplier::get).toEither(leftFn); + public static Either trying(Fn0 fn0, Fn1 leftFn) { + return Try.trying(fn0).toEither(leftFn); } /** * Attempt to execute the {@link Fn0}, returning its result in a right value. If the supplier throws an * exception, wrap it in a left value and return it. * - * @param supplier the supplier of the right value - * @param the right parameter type + * @param fn0 the supplier of the right value + * @param the right parameter type * @return the supplier result as a right value, or a left value of the thrown exception */ - public static Either trying(Fn0 supplier) { - return trying(supplier, id()); + public static Either trying(Fn0 fn0) { + return trying(fn0, id()); } /** - * Attempt to execute the {@link CheckedRunnable}, returning {@link Unit} in a right value. If the runnable throws + * Attempt to execute the {@link SideEffect}, returning {@link Unit} in a right value. If the runnable throws * an exception, apply leftFn to it, wrap it in a left value, and return it. * - * @param runnable the runnable - * @param leftFn a function mapping E to L - * @param the left parameter type + * @param the left parameter type + * @param sideEffect the runnable + * @param leftFn a function mapping E to L * @return {@link Unit} as a right value, or leftFn's mapping result as a left value */ - public static Either trying(CheckedRunnable runnable, - Function leftFn) { - return Try.trying(runnable).toEither(leftFn); + public static Either trying(SideEffect sideEffect, Fn1 leftFn) { + return Try.trying(sideEffect).toEither(leftFn); } /** - * Attempt to execute the {@link CheckedRunnable}, returning {@link Unit} in a right value. If the runnable throws + * Attempt to execute the {@link SideEffect}, returning {@link Unit} in a right value. If the runnable throws * exception, wrap it in a left value and return it. * - * @param runnable the runnable + * @param sideEffect the runnable * @return {@link Unit} as a right value, or a left value of the thrown exception */ - public static Either trying(CheckedRunnable runnable) { - return trying(runnable, id()); + public static Either trying(SideEffect sideEffect) { + return trying(sideEffect, id()); } /** @@ -402,7 +395,7 @@ private Left(L l) { } @Override - public V match(Function leftFn, Function rightFn) { + public V match(Fn1 leftFn, Fn1 rightFn) { return leftFn.apply(l); } @@ -432,7 +425,7 @@ private Right(R r) { } @Override - public V match(Function leftFn, Function rightFn) { + public V match(Fn1 leftFn, Fn1 rightFn) { return rightFn.apply(r); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/Maybe.java b/src/main/java/com/jnape/palatable/lambda/adt/Maybe.java index 892edc8ab..94f4e6bda 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/Maybe.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/Maybe.java @@ -5,7 +5,9 @@ import com.jnape.palatable.lambda.adt.coproduct.CoProduct2; import com.jnape.palatable.lambda.adt.hlist.HList; import com.jnape.palatable.lambda.adt.hlist.Tuple2; +import com.jnape.palatable.lambda.functions.Effect; import com.jnape.palatable.lambda.functions.Fn0; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functions.builtin.fn2.Peek; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Functor; @@ -15,9 +17,6 @@ import java.util.Objects; import java.util.Optional; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Supplier; import static com.jnape.palatable.lambda.adt.Either.left; import static com.jnape.palatable.lambda.adt.Unit.UNIT; @@ -44,11 +43,11 @@ private Maybe() { /** * If the value is present, return it; otherwise, return the value supplied by otherSupplier. * - * @param otherSupplier the supplier for the other value + * @param otherFn0 the supplier for the other value * @return this value, or the supplied other value */ - public final A orElseGet(Supplier otherSupplier) { - return match(__ -> otherSupplier.get(), id()); + public final A orElseGet(Fn0 otherFn0) { + return match(__ -> otherFn0.apply(), id()); } /** @@ -72,7 +71,7 @@ public final A orElse(A other) { */ public final A orElseThrow(Fn0 throwableSupplier) throws E { return orElseGet(fn0(() -> { - throw throwableSupplier.get(); + throw throwableSupplier.apply(); })); } @@ -83,7 +82,7 @@ public final A orElseThrow(Fn0 throwableSuppl * @param predicate the predicate to apply to the possibly absent value * @return maybe the present value that satisfied the predicate */ - public final Maybe filter(Function predicate) { + public final Maybe filter(Fn1 predicate) { return flatMap(a -> predicate.apply(a) ? just(a) : nothing()); } @@ -91,12 +90,12 @@ public final Maybe filter(Function predicate) { * If this value is absent, return the value supplied by lSupplier wrapped in Either.left. * Otherwise, wrap the value in Either.right and return it. * - * @param lSupplier the supplier for the left value - * @param the left parameter type + * @param the left parameter type + * @param lFn0 the supplier for the left value * @return this value wrapped in an Either.right, or an Either.left around the result of lSupplier */ - public final Either toEither(Supplier lSupplier) { - return fmap(Either::right).orElseGet(() -> left(lSupplier.get())); + public final Either toEither(Fn0 lFn0) { + return fmap(Either::right).orElseGet(() -> left(lFn0.apply())); } /** @@ -127,7 +126,7 @@ public final Maybe pure(B b) { * {@link Maybe#nothing}. */ @Override - public final Maybe fmap(Function fn) { + public final Maybe fmap(Fn1 fn) { return Monad.super.fmap(fn).coerce(); } @@ -135,7 +134,7 @@ public final Maybe fmap(Function fn) { * {@inheritDoc} */ @Override - public final Maybe zip(Applicative, Maybe> appFn) { + public final Maybe zip(Applicative, Maybe> appFn) { return Monad.super.zip(appFn).coerce(); } @@ -147,8 +146,7 @@ public final Maybe zip(Applicative, Mayb * @return the zipped {@link Maybe} */ @Override - public Lazy> lazyZip( - Lazy, Maybe>> lazyAppFn) { + public Lazy> lazyZip(Lazy, Maybe>> lazyAppFn) { return match(constantly(lazy(nothing())), a -> lazyAppFn.fmap(maybeF -> maybeF.fmap(f -> f.apply(a)).coerce())); } @@ -174,8 +172,8 @@ public final Maybe discardR(Applicative> appB) { */ @SuppressWarnings("RedundantTypeArguments") @Override - public final Maybe flatMap(Function>> f) { - return match(constantly(nothing()), f.andThen(Monad>::coerce)); + public final Maybe flatMap(Fn1>> f) { + return match(constantly(nothing()), f.fmap(Monad>::coerce)); } /** @@ -205,19 +203,19 @@ public Choice2 invert() { /** * If this value is present, accept it by consumer; otherwise, do nothing. * - * @param consumer the consumer + * @param effect the consumer * @return the same Maybe instance */ - public final Maybe peek(Consumer consumer) { - return Peek.peek(consumer, this); + public final Maybe peek(Effect effect) { + return Peek.peek(effect, this); } @Override @SuppressWarnings("unchecked") public final , TravB extends Traversable>, AppB extends Applicative, - AppTrav extends Applicative> AppTrav traverse(Function fn, - Function pure) { + AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + Fn1 pure) { return match(__ -> pure.apply((TravB) Maybe.nothing()), a -> (AppTrav) fn.apply(a).fmap(Maybe::just)); } @@ -289,7 +287,7 @@ private Nothing() { } @Override - public R match(Function aFn, Function bFn) { + public R match(Fn1 aFn, Fn1 bFn) { return aFn.apply(UNIT); } @@ -308,7 +306,7 @@ private Just(A a) { } @Override - public R match(Function aFn, Function bFn) { + public R match(Fn1 aFn, Fn1 bFn) { return bFn.apply(a); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/These.java b/src/main/java/com/jnape/palatable/lambda/adt/These.java index 4416135de..039b149fd 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/These.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/These.java @@ -3,6 +3,7 @@ import com.jnape.palatable.lambda.adt.coproduct.CoProduct2; import com.jnape.palatable.lambda.adt.coproduct.CoProduct3; import com.jnape.palatable.lambda.adt.hlist.Tuple2; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; import com.jnape.palatable.lambda.functor.builtin.Lazy; @@ -10,7 +11,6 @@ import com.jnape.palatable.lambda.traversable.Traversable; import java.util.Objects; -import java.util.function.Function; import static com.jnape.palatable.lambda.adt.hlist.HList.tuple; import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; @@ -25,7 +25,11 @@ * @param the first possible type * @param the second possible type */ -public abstract class These implements CoProduct3, These>, Monad>, Bifunctor>, Traversable> { +public abstract class These implements + CoProduct3, These>, + Monad>, + Bifunctor>, + Traversable> { private These() { } @@ -34,8 +38,8 @@ private These() { * {@inheritDoc} */ @Override - public final These biMap(Function lFn, - Function rFn) { + public final These biMap(Fn1 lFn, + Fn1 rFn) { return match(a -> a(lFn.apply(a)), b -> b(rFn.apply(b)), into((a, b) -> both(lFn.apply(a), rFn.apply(b)))); } @@ -43,7 +47,7 @@ public final These biMap(Function lFn, * {@inheritDoc} */ @Override - public final These flatMap(Function>> f) { + public final These flatMap(Fn1>> f) { return match(These::a, b -> f.apply(b).coerce(), into((a, b) -> f.apply(b).>coerce().biMapL(constantly(a)))); } @@ -58,9 +62,8 @@ public final These pure(C c) { @Override @SuppressWarnings("unchecked") public , TravB extends Traversable>, - AppB extends Applicative, - AppTrav extends Applicative> AppTrav traverse(Function fn, - Function pure) { + AppB extends Applicative, AppTrav extends Applicative> + AppTrav traverse(Fn1 fn, Fn1 pure) { return match(a -> pure.apply((TravB) a(a)), b -> fn.apply(b).fmap(this::pure).fmap(Applicative::coerce).coerce(), into((a, b) -> fn.apply(b).fmap(c -> both(a, c)).fmap(Applicative::coerce).coerce())); @@ -71,7 +74,7 @@ AppTrav extends Applicative> AppTrav traverse(Function These biMapL(Function fn) { + public final These biMapL(Fn1 fn) { return (These) Bifunctor.super.biMapL(fn); } @@ -80,7 +83,7 @@ public final These biMapL(Function fn) { */ @Override @SuppressWarnings("unchecked") - public final These biMapR(Function fn) { + public final These biMapR(Fn1 fn) { return (These) Bifunctor.super.biMapR(fn); } @@ -88,7 +91,7 @@ public final These biMapR(Function fn) { * {@inheritDoc} */ @Override - public final These fmap(Function fn) { + public final These fmap(Fn1 fn) { return Monad.super.fmap(fn).coerce(); } @@ -96,13 +99,13 @@ public final These fmap(Function fn) { * {@inheritDoc} */ @Override - public final These zip(Applicative, These> appFn) { + public final These zip(Applicative, These> appFn) { return Monad.super.zip(appFn).coerce(); } @Override public Lazy> lazyZip( - Lazy, These>> lazyAppFn) { + Lazy, These>> lazyAppFn) { return projectA().>>fmap(a -> lazy(a(a))) .orElseGet(() -> Monad.super.lazyZip(lazyAppFn).fmap(Monad>::coerce)); } @@ -170,8 +173,8 @@ private _A(A a) { } @Override - public R match(Function aFn, Function bFn, - Function, ? extends R> cFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1, ? extends R> cFn) { return aFn.apply(a); } @@ -199,8 +202,8 @@ private _B(B b) { } @Override - public R match(Function aFn, Function bFn, - Function, ? extends R> cFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1, ? extends R> cFn) { return bFn.apply(b); } @@ -228,8 +231,8 @@ private Both(Tuple2 tuple) { } @Override - public R match(Function aFn, Function bFn, - Function, ? extends R> cFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1, ? extends R> cFn) { return cFn.apply(both); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/Try.java b/src/main/java/com/jnape/palatable/lambda/adt/Try.java index bec29194a..3aeacead1 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/Try.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/Try.java @@ -3,15 +3,15 @@ import com.jnape.palatable.lambda.adt.coproduct.CoProduct2; import com.jnape.palatable.lambda.functions.Fn0; import com.jnape.palatable.lambda.functions.Fn1; -import com.jnape.palatable.lambda.functions.specialized.checked.CheckedRunnable; +import com.jnape.palatable.lambda.functions.specialized.SideEffect; import com.jnape.palatable.lambda.functions.specialized.checked.Runtime; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.builtin.Lazy; +import com.jnape.palatable.lambda.io.IO; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; import java.util.Objects; -import java.util.function.Function; import static com.jnape.palatable.lambda.adt.Maybe.nothing; import static com.jnape.palatable.lambda.adt.Unit.UNIT; @@ -35,14 +35,14 @@ private Try() { /** * Catch any instance of throwableType and map it to a success value. * + * @param the {@link Throwable} (sub)type * @param throwableType the {@link Throwable} (sub)type to be caught * @param recoveryFn the function mapping the {@link Throwable} to the result - * @param the {@link Throwable} (sub)type * @return a new {@link Try} instance around either the original successful result or the mapped result */ @SuppressWarnings("unchecked") public final Try catching(Class throwableType, - Function recoveryFn) { + Fn1 recoveryFn) { return catching(throwableType::isInstance, t -> recoveryFn.apply((S) t)); } @@ -53,8 +53,8 @@ public final Try catching(Class throwableType, * @param recoveryFn the function mapping the {@link Throwable} to the result * @return a new {@link Try} instance around either the original successful result or the mapped result */ - public final Try catching(Function predicate, - Function recoveryFn) { + public final Try catching(Fn1 predicate, + Fn1 recoveryFn) { return match(t -> predicate.apply(t) ? success(recoveryFn.apply(t)) : failure(t), Try::success); } @@ -67,18 +67,18 @@ public final Try catching(Function pred * over some {@link Throwable} t1, and the runnable throws a new {@link Throwable} t2, the * result is a failure over t1 with t2 added to t1 as a suppressed exception. * - * @param runnable the runnable block of code to execute + * @param sideEffect the runnable block of code to execute * @return the same {@link Try} instance if runnable completes successfully; otherwise, a {@link Try} conforming to * rules above */ - public final Try ensuring(CheckedRunnable runnable) { - return match(t -> trying(runnable) + public final Try ensuring(SideEffect sideEffect) { + return match(t -> trying(sideEffect) .>fmap(constantly(failure(t))) .recover(t2 -> { t.addSuppressed(t2); return failure(t); }), - a -> trying(runnable).fmap(constantly(a))); + a -> trying(sideEffect).fmap(constantly(a))); } /** @@ -88,7 +88,7 @@ public final Try ensuring(CheckedRunnable runnable) { * @param fn the function mapping the potential {@link Throwable} T to A * @return a success value */ - public final A recover(Function fn) { + public final A recover(Fn1 fn) { return match(fn, id()); } @@ -99,14 +99,16 @@ public final A recover(Function fn) { * @param fn the function mapping the potential A to T * @return a failure value */ - public final Throwable forfeit(Function fn) { + public final Throwable forfeit(Fn1 fn) { return match(id(), fn); } /** * If this is a success value, return it. Otherwise, rethrow the captured failure. * + * @param a declarable exception type used for catching checked exceptions * @return possibly the success value + * @throws T anything that the call site may want to explicitly catch or indicate could be thrown */ public abstract A orThrow() throws T; @@ -134,19 +136,19 @@ public final Either toEither() { * If this is a success, wrap the value in a {@link Either#right} and return it. Otherwise, apply the mapping * function to the failure {@link Throwable}, re-wrap it in an {@link Either#left}, and return it. * - * @param fn the mapping function * @param the {@link Either} left parameter type + * @param fn the mapping function * @return {@link Either} the success value or the mapped left value */ - public final Either toEither(Function fn) { - return match(fn.andThen(Either::left), Either::right); + public final Either toEither(Fn1 fn) { + return match(fn.fmap(Either::left), Either::right); } /** * {@inheritDoc} */ @Override - public Try fmap(Function fn) { + public Try fmap(Fn1 fn) { return Monad.super.fmap(fn).coerce(); } @@ -154,7 +156,7 @@ public Try fmap(Function fn) { * {@inheritDoc} */ @Override - public Try flatMap(Function>> f) { + public Try flatMap(Fn1>> f) { return match(Try::failure, a -> f.apply(a).coerce()); } @@ -170,13 +172,15 @@ public Try pure(B b) { * {@inheritDoc} */ @Override - public Try zip(Applicative, Try> appFn) { + public Try zip(Applicative, Try> appFn) { return Monad.super.zip(appFn).coerce(); } + /** + * {@inheritDoc} + */ @Override - public Lazy> lazyZip( - Lazy, Try>> lazyAppFn) { + public Lazy> lazyZip(Lazy, Try>> lazyAppFn) { return match(f -> lazy(failure(f)), s -> lazyAppFn.fmap(tryF -> tryF.fmap(f -> f.apply(s)).coerce())); } @@ -204,8 +208,8 @@ public Try discardR(Applicative> appB) { @SuppressWarnings("unchecked") public , TravB extends Traversable>, AppB extends Applicative, - AppTrav extends Applicative> AppTrav traverse(Function fn, - Function pure) { + AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + Fn1 pure) { return match(t -> pure.apply((TravB) failure(t)), a -> fn.apply(a).fmap(Try::success).fmap(Applicative::coerce).coerce()); } @@ -242,7 +246,7 @@ public static Try failure(T t) { */ public static Try trying(Fn0 supplier) { try { - return success(supplier.get()); + return success(supplier.apply()); } catch (Throwable t) { return failure(t); } @@ -251,20 +255,20 @@ public static Try trying(Fn0 supplier) { /** * Execute runnable, returning a success {@link Unit} or a failure of the thrown {@link Throwable}. * - * @param runnable the runnable + * @param sideEffect the runnable * @return a new {@link Try} around either a successful {@link Unit} result or the thrown {@link Throwable} */ - public static Try trying(CheckedRunnable runnable) { + public static Try trying(SideEffect sideEffect) { return trying(() -> { - runnable.run(); + IO.io(sideEffect).unsafePerformIO(); return UNIT; }); } /** - * Given a {@link Fn0}<{@link AutoCloseable}> aSupplier and a - * {@link Function} fn, apply fn to the result of aSupplier, ensuring - * that the result has its {@link AutoCloseable#close() close} method invoked, regardless of the outcome. + * Given a {@link Fn0}<{@link AutoCloseable}> aSupplier and an {@link Fn1} + * fn, apply fn to the result of aSupplier, ensuring that the result has its + * {@link AutoCloseable#close() close} method invoked, regardless of the outcome. *

* If the resource creation process throws, the function body throws, or the * {@link AutoCloseable#close() close method} throws, the result is a failure. If both the function body and the @@ -354,7 +358,7 @@ public A orThrow() { } @Override - public R match(Function aFn, Function bFn) { + public R match(Fn1 aFn, Fn1 bFn) { return aFn.apply(t); } @@ -389,7 +393,7 @@ public A orThrow() { } @Override - public R match(Function aFn, Function bFn) { + public R match(Fn1 aFn, Fn1 bFn) { return bFn.apply(a); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice2.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice2.java index d056ae87c..24cc10bc5 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice2.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice2.java @@ -5,6 +5,7 @@ import com.jnape.palatable.lambda.adt.coproduct.CoProduct2; import com.jnape.palatable.lambda.adt.hlist.HList; import com.jnape.palatable.lambda.adt.hlist.Tuple2; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; import com.jnape.palatable.lambda.functor.Functor; @@ -13,7 +14,6 @@ import com.jnape.palatable.lambda.traversable.Traversable; import java.util.Objects; -import java.util.function.Function; import static com.jnape.palatable.lambda.functions.builtin.fn2.Into.into; import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; @@ -66,7 +66,7 @@ public Choice2 invert() { * {@inheritDoc} */ @Override - public final Choice2 fmap(Function fn) { + public final Choice2 fmap(Fn1 fn) { return Monad.super.fmap(fn).coerce(); } @@ -74,26 +74,24 @@ public final Choice2 fmap(Function fn) { * {@inheritDoc} */ @Override - @SuppressWarnings("unchecked") - public final Choice2 biMapL(Function fn) { - return (Choice2) Bifunctor.super.biMapL(fn); + public final Choice2 biMapL(Fn1 fn) { + return (Choice2) Bifunctor.super.biMapL(fn); } /** * {@inheritDoc} */ @Override - @SuppressWarnings("unchecked") - public final Choice2 biMapR(Function fn) { - return (Choice2) Bifunctor.super.biMapR(fn); + public final Choice2 biMapR(Fn1 fn) { + return (Choice2) Bifunctor.super.biMapR(fn); } /** * {@inheritDoc} */ @Override - public final Choice2 biMap(Function lFn, - Function rFn) { + public final Choice2 biMap(Fn1 lFn, + Fn1 rFn) { return match(a -> a(lFn.apply(a)), b -> b(rFn.apply(b))); } @@ -109,7 +107,7 @@ public Choice2 pure(C c) { * {@inheritDoc} */ @Override - public Choice2 zip(Applicative, Choice2> appFn) { + public Choice2 zip(Applicative, Choice2> appFn) { return Monad.super.zip(appFn).coerce(); } @@ -118,7 +116,7 @@ public Choice2 zip(Applicative, Choic */ @Override public Lazy>> lazyZip( - Lazy, Choice2>> lazyAppFn) { + Lazy, Choice2>> lazyAppFn) { return match(a -> lazy(a(a)), b -> lazyAppFn.fmap(choiceF -> choiceF.fmap(f -> f.apply(b)).coerce())); } @@ -143,7 +141,7 @@ public Choice2 discardR(Applicative> appB) { * {@inheritDoc} */ @Override - public final Choice2 flatMap(Function>> f) { + public final Choice2 flatMap(Fn1>> f) { return match(Choice2::a, b -> f.apply(b).coerce()); } @@ -154,8 +152,8 @@ public final Choice2 flatMap(Function, TravB extends Traversable>, AppB extends Applicative, - AppTrav extends Applicative> AppTrav traverse(Function fn, - Function pure) { + AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + Fn1 pure) { return match(a -> pure.apply((TravB) a(a)), b -> fn.apply(b).>fmap(Choice2::b).fmap(Functor::coerce).coerce()); } @@ -193,7 +191,7 @@ private _A(A a) { } @Override - public R match(Function aFn, Function bFn) { + public R match(Fn1 aFn, Fn1 bFn) { return aFn.apply(a); } @@ -225,7 +223,7 @@ private _B(B b) { } @Override - public R match(Function aFn, Function bFn) { + public R match(Fn1 aFn, Fn1 bFn) { return bFn.apply(b); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice3.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice3.java index 0ba9eddc4..0b58ca14f 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice3.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice3.java @@ -5,6 +5,7 @@ import com.jnape.palatable.lambda.adt.coproduct.CoProduct3; import com.jnape.palatable.lambda.adt.hlist.HList; import com.jnape.palatable.lambda.adt.hlist.Tuple3; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; import com.jnape.palatable.lambda.functor.Functor; @@ -13,7 +14,6 @@ import com.jnape.palatable.lambda.traversable.Traversable; import java.util.Objects; -import java.util.function.Function; import static com.jnape.palatable.lambda.functions.builtin.fn2.Into3.into3; import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; @@ -58,15 +58,15 @@ public final Choice4 diverge() { * {@inheritDoc} */ @Override - public final Choice2 converge(Function> convergenceFn) { - return match(Choice2::a, Choice2::b, convergenceFn.andThen(cp2 -> cp2.match(Choice2::a, Choice2::b))); + public final Choice2 converge(Fn1> convergenceFn) { + return match(Choice2::a, Choice2::b, convergenceFn.fmap(cp2 -> cp2.match(Choice2::a, Choice2::b))); } /** * {@inheritDoc} */ @Override - public final Choice3 fmap(Function fn) { + public final Choice3 fmap(Fn1 fn) { return Monad.super.fmap(fn).coerce(); } @@ -74,26 +74,24 @@ public final Choice3 fmap(Function fn) { * {@inheritDoc} */ @Override - @SuppressWarnings("unchecked") - public final Choice3 biMapL(Function fn) { - return (Choice3) Bifunctor.super.biMapL(fn); + public final Choice3 biMapL(Fn1 fn) { + return (Choice3) Bifunctor.super.biMapL(fn); } /** * {@inheritDoc} */ @Override - @SuppressWarnings("unchecked") - public final Choice3 biMapR(Function fn) { - return (Choice3) Bifunctor.super.biMapR(fn); + public final Choice3 biMapR(Fn1 fn) { + return (Choice3) Bifunctor.super.biMapR(fn); } /** * {@inheritDoc} */ @Override - public final Choice3 biMap(Function lFn, - Function rFn) { + public final Choice3 biMap(Fn1 lFn, + Fn1 rFn) { return match(Choice3::a, b -> b(lFn.apply(b)), c -> c(rFn.apply(c))); } @@ -109,7 +107,7 @@ public Choice3 pure(D d) { * {@inheritDoc} */ @Override - public Choice3 zip(Applicative, Choice3> appFn) { + public Choice3 zip(Applicative, Choice3> appFn) { return Monad.super.zip(appFn).coerce(); } @@ -118,7 +116,7 @@ public Choice3 zip(Applicative, Ch */ @Override public Lazy> lazyZip( - Lazy, Choice3>> lazyAppFn) { + Lazy, Choice3>> lazyAppFn) { return match(a -> lazy(a(a)), b -> lazy(b(b)), c -> lazyAppFn.fmap(choiceF -> choiceF.fmap(f -> f.apply(c)).coerce())); @@ -144,7 +142,7 @@ public Choice3 discardR(Applicative> appB) { * {@inheritDoc} */ @Override - public Choice3 flatMap(Function>> f) { + public Choice3 flatMap(Fn1>> f) { return match(Choice3::a, Choice3::b, c -> f.apply(c).coerce()); } @@ -155,8 +153,8 @@ public Choice3 flatMap(Function, TravB extends Traversable>, AppB extends Applicative, - AppTrav extends Applicative> AppTrav traverse(Function fn, - Function pure) { + AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + Fn1 pure) { return match(a -> pure.apply((TravB) Choice3.a(a)).coerce(), b -> pure.apply((TravB) Choice3.b(b)).coerce(), c -> fn.apply(c).>fmap(Choice3::c).fmap(Functor::coerce).coerce()); @@ -210,8 +208,8 @@ private _A(A a) { } @Override - public R match(Function aFn, Function bFn, - Function cFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn) { return aFn.apply(a); } @@ -243,8 +241,8 @@ private _B(B b) { } @Override - public R match(Function aFn, Function bFn, - Function cFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn) { return bFn.apply(b); } @@ -276,8 +274,8 @@ private _C(C c) { } @Override - public R match(Function aFn, Function bFn, - Function cFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn) { return cFn.apply(c); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice4.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice4.java index f24a04042..a93eae6cd 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice4.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice4.java @@ -5,6 +5,7 @@ import com.jnape.palatable.lambda.adt.coproduct.CoProduct4; import com.jnape.palatable.lambda.adt.hlist.HList; import com.jnape.palatable.lambda.adt.hlist.Tuple4; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; import com.jnape.palatable.lambda.functor.Functor; @@ -13,7 +14,6 @@ import com.jnape.palatable.lambda.traversable.Traversable; import java.util.Objects; -import java.util.function.Function; import static com.jnape.palatable.lambda.functions.builtin.fn2.Into4.into4; import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; @@ -59,18 +59,16 @@ public Choice5 diverge() { * {@inheritDoc} */ @Override - public Choice3 converge(Function> convergenceFn) { - return match(Choice3::a, - Choice3::b, - Choice3::c, - convergenceFn.andThen(cp3 -> cp3.match(Choice3::a, Choice3::b, Choice3::c))); + public Choice3 converge(Fn1> convergenceFn) { + return match(Choice3::a, Choice3::b, Choice3::c, + convergenceFn.fmap(cp3 -> cp3.match(Choice3::a, Choice3::b, Choice3::c))); } /** * {@inheritDoc} */ @Override - public final Choice4 fmap(Function fn) { + public final Choice4 fmap(Fn1 fn) { return Monad.super.fmap(fn).coerce(); } @@ -78,23 +76,21 @@ public final Choice4 fmap(Function fn) { * {@inheritDoc} */ @Override - @SuppressWarnings("unchecked") - public final Choice4 biMapL(Function fn) { - return (Choice4) Bifunctor.super.biMapL(fn); + public final Choice4 biMapL(Fn1 fn) { + return (Choice4) Bifunctor.super.biMapL(fn); } /** * {@inheritDoc} */ @Override - @SuppressWarnings("unchecked") - public final Choice4 biMapR(Function fn) { - return (Choice4) Bifunctor.super.biMapR(fn); + public final Choice4 biMapR(Fn1 fn) { + return (Choice4) Bifunctor.super.biMapR(fn); } @Override - public final Choice4 biMap(Function lFn, - Function rFn) { + public final Choice4 biMap(Fn1 lFn, + Fn1 rFn) { return match(Choice4::a, Choice4::b, c -> c(lFn.apply(c)), d -> d(rFn.apply(d))); } @@ -110,7 +106,7 @@ public Choice4 pure(E e) { * {@inheritDoc} */ @Override - public Choice4 zip(Applicative, Choice4> appFn) { + public Choice4 zip(Applicative, Choice4> appFn) { return Monad.super.zip(appFn).coerce(); } @@ -119,7 +115,7 @@ public Choice4 zip(Applicative, */ @Override public Lazy> lazyZip( - Lazy, Choice4>> lazyAppFn) { + Lazy, Choice4>> lazyAppFn) { return match(a -> lazy(a(a)), b -> lazy(b(b)), c -> lazy(c(c)), @@ -146,7 +142,7 @@ public Choice4 discardR(Applicative> appB * {@inheritDoc} */ @Override - public Choice4 flatMap(Function>> f) { + public Choice4 flatMap(Fn1>> f) { return match(Choice4::a, Choice4::b, Choice4::c, d -> f.apply(d).coerce()); } @@ -157,8 +153,8 @@ public Choice4 flatMap(Function, TravB extends Traversable>, AppB extends Applicative, - AppTrav extends Applicative> AppTrav traverse(Function fn, - Function pure) { + AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + Fn1 pure) { return match(a -> pure.apply((TravB) Choice4.a(a)).coerce(), b -> pure.apply((TravB) Choice4.b(b)).coerce(), c -> pure.apply((TravB) Choice4.c(c)), @@ -230,8 +226,8 @@ private _A(A a) { } @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn) { return aFn.apply(a); } @@ -263,8 +259,8 @@ private _B(B b) { } @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn) { return bFn.apply(b); } @@ -296,8 +292,8 @@ private _C(C c) { } @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn) { return cFn.apply(c); } @@ -329,8 +325,8 @@ private _D(D d) { } @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn) { return dFn.apply(d); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice5.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice5.java index 4008fde0b..e3e4a7958 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice5.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice5.java @@ -5,6 +5,7 @@ import com.jnape.palatable.lambda.adt.coproduct.CoProduct5; import com.jnape.palatable.lambda.adt.hlist.HList; import com.jnape.palatable.lambda.adt.hlist.Tuple5; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; import com.jnape.palatable.lambda.functor.builtin.Lazy; @@ -12,7 +13,6 @@ import com.jnape.palatable.lambda.traversable.Traversable; import java.util.Objects; -import java.util.function.Function; import static com.jnape.palatable.lambda.functions.builtin.fn2.Into5.into5; import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; @@ -59,19 +59,16 @@ public Choice6 diverge() { * {@inheritDoc} */ @Override - public Choice4 converge(Function> convergenceFn) { - return match(Choice4::a, - Choice4::b, - Choice4::c, - Choice4::d, - convergenceFn.andThen(cp4 -> cp4.match(Choice4::a, Choice4::b, Choice4::c, Choice4::d))); + public Choice4 converge(Fn1> convergenceFn) { + return match(Choice4::a, Choice4::b, Choice4::c, Choice4::d, + convergenceFn.fmap(cp4 -> cp4.match(Choice4::a, Choice4::b, Choice4::c, Choice4::d))); } /** * {@inheritDoc} */ @Override - public Choice5 fmap(Function fn) { + public Choice5 fmap(Fn1 fn) { return Monad.super.fmap(fn).coerce(); } @@ -79,26 +76,24 @@ public Choice5 fmap(Function fn) { * {@inheritDoc} */ @Override - @SuppressWarnings("unchecked") - public Choice5 biMapL(Function fn) { - return (Choice5) Bifunctor.super.biMapL(fn); + public Choice5 biMapL(Fn1 fn) { + return (Choice5) Bifunctor.super.biMapL(fn); } /** * {@inheritDoc} */ @Override - @SuppressWarnings("unchecked") - public Choice5 biMapR(Function fn) { - return (Choice5) Bifunctor.super.biMapR(fn); + public Choice5 biMapR(Fn1 fn) { + return (Choice5) Bifunctor.super.biMapR(fn); } /** * {@inheritDoc} */ @Override - public Choice5 biMap(Function lFn, - Function rFn) { + public Choice5 biMap(Fn1 lFn, + Fn1 rFn) { return match(Choice5::a, Choice5::b, Choice5::c, d -> d(lFn.apply(d)), e -> e(rFn.apply(e))); } @@ -114,7 +109,7 @@ public Choice5 pure(F f) { * {@inheritDoc} */ @Override - public Choice5 zip(Applicative, Choice5> appFn) { + public Choice5 zip(Applicative, Choice5> appFn) { return Monad.super.zip(appFn).coerce(); } @@ -123,7 +118,7 @@ public Choice5 zip(Applicative Lazy> lazyZip( - Lazy, Choice5>> lazyAppFn) { + Lazy, Choice5>> lazyAppFn) { return match(a -> lazy(a(a)), b -> lazy(b(b)), c -> lazy(c(c)), @@ -151,7 +146,7 @@ public Choice5 discardR(Applicative * {@inheritDoc} */ @Override - public Choice5 flatMap(Function>> f) { + public Choice5 flatMap(Fn1>> f) { return match(Choice5::a, Choice5::b, Choice5::c, Choice5::d, e -> f.apply(e).coerce()); } @@ -162,8 +157,8 @@ public Choice5 flatMap(Function, TravB extends Traversable>, AppB extends Applicative, - AppTrav extends Applicative> AppTrav traverse(Function fn, - Function pure) { + AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + Fn1 pure) { return match(a -> pure.apply((TravB) Choice5.a(a)).coerce(), b -> pure.apply((TravB) Choice5.b(b)).coerce(), c -> pure.apply((TravB) Choice5.c(c)), @@ -256,9 +251,9 @@ private _A(A a) { } @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn, - Function eFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn, + Fn1 eFn) { return aFn.apply(a); } @@ -290,9 +285,9 @@ private _B(B b) { } @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn, - Function eFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn, + Fn1 eFn) { return bFn.apply(b); } @@ -324,9 +319,9 @@ private _C(C c) { } @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn, - Function eFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn, + Fn1 eFn) { return cFn.apply(c); } @@ -358,9 +353,9 @@ private _D(D d) { } @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn, - Function eFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn, + Fn1 eFn) { return dFn.apply(d); } @@ -392,9 +387,9 @@ private _E(E e) { } @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn, - Function eFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn, + Fn1 eFn) { return eFn.apply(e); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice6.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice6.java index 0f09db9fa..dd788fb5b 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice6.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice6.java @@ -5,6 +5,7 @@ import com.jnape.palatable.lambda.adt.coproduct.CoProduct6; import com.jnape.palatable.lambda.adt.hlist.HList; import com.jnape.palatable.lambda.adt.hlist.Tuple6; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; import com.jnape.palatable.lambda.functor.builtin.Lazy; @@ -12,7 +13,6 @@ import com.jnape.palatable.lambda.traversable.Traversable; import java.util.Objects; -import java.util.function.Function; import static com.jnape.palatable.lambda.functions.builtin.fn2.Into6.into6; import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; @@ -60,20 +60,16 @@ public Choice7 diverge() { * {@inheritDoc} */ @Override - public Choice5 converge(Function> convergenceFn) { - return match(Choice5::a, - Choice5::b, - Choice5::c, - Choice5::d, - Choice5::e, - convergenceFn.andThen(cp5 -> cp5.match(Choice5::a, Choice5::b, Choice5::c, Choice5::d, Choice5::e))); + public Choice5 converge(Fn1> convergenceFn) { + return match(Choice5::a, Choice5::b, Choice5::c, Choice5::d, Choice5::e, + convergenceFn.fmap(cp5 -> cp5.match(Choice5::a, Choice5::b, Choice5::c, Choice5::d, Choice5::e))); } /** * {@inheritDoc} */ @Override - public Choice6 fmap(Function fn) { + public Choice6 fmap(Fn1 fn) { return Monad.super.fmap(fn).coerce(); } @@ -82,7 +78,7 @@ public Choice6 fmap(Function fn) { */ @Override @SuppressWarnings("unchecked") - public Choice6 biMapL(Function fn) { + public Choice6 biMapL(Fn1 fn) { return (Choice6) Bifunctor.super.biMapL(fn); } @@ -91,7 +87,7 @@ public Choice6 biMapL(Function fn) */ @Override @SuppressWarnings("unchecked") - public Choice6 biMapR(Function fn) { + public Choice6 biMapR(Fn1 fn) { return (Choice6) Bifunctor.super.biMapR(fn); } @@ -99,8 +95,8 @@ public Choice6 biMapR(Function fn) * {@inheritDoc} */ @Override - public Choice6 biMap(Function lFn, - Function rFn) { + public Choice6 biMap(Fn1 lFn, + Fn1 rFn) { return match(Choice6::a, Choice6::b, Choice6::c, Choice6::d, e -> e(lFn.apply(e)), f -> f(rFn.apply(f))); } @@ -117,7 +113,7 @@ public Choice6 pure(G g) { */ @Override public Choice6 zip( - Applicative, Choice6> appFn) { + Applicative, Choice6> appFn) { return Monad.super.zip(appFn).coerce(); } @@ -126,7 +122,7 @@ public Choice6 zip( */ @Override public Lazy> lazyZip( - Lazy, Choice6>> lazyAppFn) { + Lazy, Choice6>> lazyAppFn) { return match(a -> lazy(a(a)), b -> lazy(b(b)), c -> lazy(c(c)), @@ -155,8 +151,7 @@ public Choice6 discardR(Applicative Choice6 flatMap( - Function>> fn) { + public Choice6 flatMap(Fn1>> fn) { return match(Choice6::a, Choice6::b, Choice6::c, Choice6::d, Choice6::e, f -> fn.apply(f).coerce()); } @@ -167,8 +162,8 @@ public Choice6 flatMap( @SuppressWarnings("unchecked") public , TravB extends Traversable>, AppB extends Applicative, - AppTrav extends Applicative> AppTrav traverse(Function fn, - Function pure) { + AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + Fn1 pure) { return match(a -> pure.apply((TravB) Choice6.a(a)).coerce(), b -> pure.apply((TravB) Choice6.b(b)).coerce(), c -> pure.apply((TravB) Choice6.c(c)), @@ -283,9 +278,9 @@ private _A(A a) { } @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn, - Function eFn, Function fFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn, + Fn1 eFn, Fn1 fFn) { return aFn.apply(a); } @@ -315,9 +310,9 @@ private _B(B b) { } @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn, - Function eFn, Function fFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn, + Fn1 eFn, Fn1 fFn) { return bFn.apply(b); } @@ -347,9 +342,9 @@ private _C(C c) { } @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn, - Function eFn, Function fFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn, + Fn1 eFn, Fn1 fFn) { return cFn.apply(c); } @@ -379,9 +374,9 @@ private _D(D d) { } @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn, - Function eFn, Function fFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn, + Fn1 eFn, Fn1 fFn) { return dFn.apply(d); } @@ -411,9 +406,9 @@ private _E(E e) { } @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn, - Function eFn, Function fFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn, + Fn1 eFn, Fn1 fFn) { return eFn.apply(e); } @@ -443,9 +438,9 @@ private _F(F f) { } @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn, - Function eFn, Function fFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn, + Fn1 eFn, Fn1 fFn) { return fFn.apply(f); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice7.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice7.java index 6965a2d37..a72489ecb 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice7.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice7.java @@ -5,6 +5,7 @@ import com.jnape.palatable.lambda.adt.coproduct.CoProduct7; import com.jnape.palatable.lambda.adt.hlist.HList; import com.jnape.palatable.lambda.adt.hlist.Tuple7; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; import com.jnape.palatable.lambda.functor.builtin.Lazy; @@ -12,7 +13,6 @@ import com.jnape.palatable.lambda.traversable.Traversable; import java.util.Objects; -import java.util.function.Function; import static com.jnape.palatable.lambda.functions.builtin.fn2.Into7.into7; import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; @@ -61,22 +61,17 @@ public Choice8 diverge() { * {@inheritDoc} */ @Override - public Choice6 converge( - Function> convergenceFn) { - return match(Choice6::a, - Choice6::b, - Choice6::c, - Choice6::d, - Choice6::e, - Choice6::f, - convergenceFn.andThen(cp6 -> cp6.match(Choice6::a, Choice6::b, Choice6::c, Choice6::d, Choice6::e, Choice6::f))); + public Choice6 converge(Fn1> convergenceFn) { + return match(Choice6::a, Choice6::b, Choice6::c, Choice6::d, Choice6::e, Choice6::f, + convergenceFn.fmap(cp6 -> cp6.match(Choice6::a, Choice6::b, Choice6::c, Choice6::d, Choice6::e, + Choice6::f))); } /** * {@inheritDoc} */ @Override - public Choice7 fmap(Function fn) { + public Choice7 fmap(Fn1 fn) { return Monad.super.fmap(fn).coerce(); } @@ -84,26 +79,24 @@ public Choice7 fmap(Function fn * {@inheritDoc} */ @Override - @SuppressWarnings("unchecked") - public Choice7 biMapL(Function fn) { - return (Choice7) Bifunctor.super.biMapL(fn); + public Choice7 biMapL(Fn1 fn) { + return (Choice7) Bifunctor.super.biMapL(fn); } /** * {@inheritDoc} */ @Override - @SuppressWarnings("unchecked") - public Choice7 biMapR(Function fn) { - return (Choice7) Bifunctor.super.biMapR(fn); + public Choice7 biMapR(Fn1 fn) { + return (Choice7) Bifunctor.super.biMapR(fn); } /** * {@inheritDoc} */ @Override - public Choice7 biMap(Function lFn, - Function rFn) { + public Choice7 biMap(Fn1 lFn, + Fn1 rFn) { return match(Choice7::a, Choice7::b, Choice7::c, Choice7::d, Choice7::e, f -> f(lFn.apply(f)), g -> g(rFn.apply(g))); } @@ -120,7 +113,7 @@ public Choice7 pure(H h) { */ @Override public Choice7 zip( - Applicative, Choice7> appFn) { + Applicative, Choice7> appFn) { return Monad.super.zip(appFn).coerce(); } @@ -129,7 +122,7 @@ public Choice7 zip( */ @Override public Lazy> lazyZip( - Lazy, Choice7>> lazyAppFn) { + Lazy, Choice7>> lazyAppFn) { return match(a -> lazy(a(a)), b -> lazy(b(b)), c -> lazy(c(c)), @@ -160,7 +153,7 @@ public Choice7 discardR(Applicative Choice7 flatMap( - Function>> fn) { + Fn1>> fn) { return match(Choice7::a, Choice7::b, Choice7::c, Choice7::d, Choice7::e, Choice7::f, g -> fn.apply(g).coerce()); } @@ -171,8 +164,8 @@ public Choice7 flatMap( @SuppressWarnings("unchecked") public , TravB extends Traversable>, AppB extends Applicative, - AppTrav extends Applicative> AppTrav traverse(Function fn, - Function pure) { + AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + Fn1 pure) { return match(a -> pure.apply((TravB) Choice7.a(a)).coerce(), b -> pure.apply((TravB) Choice7.b(b)).coerce(), c -> pure.apply((TravB) Choice7.c(c)), @@ -311,10 +304,10 @@ private _A(A a) { } @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn, - Function eFn, Function fFn, - Function gFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn, + Fn1 eFn, Fn1 fFn, + Fn1 gFn) { return aFn.apply(a); } @@ -344,10 +337,10 @@ private _B(B b) { } @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn, - Function eFn, Function fFn, - Function gFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn, + Fn1 eFn, Fn1 fFn, + Fn1 gFn) { return bFn.apply(b); } @@ -377,10 +370,10 @@ private _C(C c) { } @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn, - Function eFn, Function fFn, - Function gFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn, + Fn1 eFn, Fn1 fFn, + Fn1 gFn) { return cFn.apply(c); } @@ -410,10 +403,10 @@ private _D(D d) { } @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn, - Function eFn, Function fFn, - Function gFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn, + Fn1 eFn, Fn1 fFn, + Fn1 gFn) { return dFn.apply(d); } @@ -443,10 +436,10 @@ private _E(E e) { } @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn, - Function eFn, Function fFn, - Function gFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn, + Fn1 eFn, Fn1 fFn, + Fn1 gFn) { return eFn.apply(e); } @@ -476,10 +469,10 @@ private _F(F f) { } @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn, - Function eFn, Function fFn, - Function gFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn, + Fn1 eFn, Fn1 fFn, + Fn1 gFn) { return fFn.apply(f); } @@ -509,10 +502,10 @@ private _G(G g) { } @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn, - Function eFn, Function fFn, - Function gFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn, + Fn1 eFn, Fn1 fFn, + Fn1 gFn) { return gFn.apply(g); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice8.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice8.java index a55590886..2d21f27ba 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice8.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice8.java @@ -5,6 +5,7 @@ import com.jnape.palatable.lambda.adt.coproduct.CoProduct8; import com.jnape.palatable.lambda.adt.hlist.HList; import com.jnape.palatable.lambda.adt.hlist.Tuple8; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; import com.jnape.palatable.lambda.functor.builtin.Lazy; @@ -12,7 +13,6 @@ import com.jnape.palatable.lambda.traversable.Traversable; import java.util.Objects; -import java.util.function.Function; import static com.jnape.palatable.lambda.functions.builtin.fn2.Into8.into8; import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; @@ -54,22 +54,17 @@ public Tuple8, Maybe, Maybe, Maybe, Maybe, Maybe, Maybe< */ @Override public Choice7 converge( - Function> convergenceFn) { - return match(Choice7::a, - Choice7::b, - Choice7::c, - Choice7::d, - Choice7::e, - Choice7::f, - Choice7::g, - convergenceFn.andThen(cp7 -> cp7.match(Choice7::a, Choice7::b, Choice7::c, Choice7::d, Choice7::e, Choice7::f, Choice7::g))); + Fn1> convergenceFn) { + return match(Choice7::a, Choice7::b, Choice7::c, Choice7::d, Choice7::e, Choice7::f, Choice7::g, + convergenceFn.fmap(cp7 -> cp7.match(Choice7::a, Choice7::b, Choice7::c, Choice7::d, Choice7::e, + Choice7::f, Choice7::g))); } /** * {@inheritDoc} */ @Override - public Choice8 fmap(Function fn) { + public Choice8 fmap(Fn1 fn) { return Monad.super.fmap(fn).coerce(); } @@ -77,26 +72,24 @@ public Choice8 fmap(Function * {@inheritDoc} */ @Override - @SuppressWarnings("unchecked") - public Choice8 biMapL(Function fn) { - return (Choice8) Bifunctor.super.biMapL(fn); + public Choice8 biMapL(Fn1 fn) { + return (Choice8) Bifunctor.super.biMapL(fn); } /** * {@inheritDoc} */ @Override - @SuppressWarnings("unchecked") - public Choice8 biMapR(Function fn) { - return (Choice8) Bifunctor.super.biMapR(fn); + public Choice8 biMapR(Fn1 fn) { + return (Choice8) Bifunctor.super.biMapR(fn); } /** * {@inheritDoc} */ @Override - public Choice8 biMap(Function lFn, - Function rFn) { + public Choice8 biMap(Fn1 lFn, + Fn1 rFn) { return match(Choice8::a, Choice8::b, Choice8::c, Choice8::d, Choice8::e, Choice8::f, g -> g(lFn.apply(g)), h -> h(rFn.apply(h))); } @@ -113,7 +106,7 @@ public Choice8 pure(I i) { */ @Override public Choice8 zip( - Applicative, Choice8> appFn) { + Applicative, Choice8> appFn) { return Monad.super.zip(appFn).coerce(); } @@ -122,7 +115,7 @@ public Choice8 zip( */ @Override public Lazy> lazyZip( - Lazy, Choice8>> lazyAppFn) { + Lazy, Choice8>> lazyAppFn) { return match(a -> lazy(a(a)), b -> lazy(b(b)), c -> lazy(c(c)), @@ -154,7 +147,7 @@ public Choice8 discardR(Applicative Choice8 flatMap( - Function>> fn) { + Fn1>> fn) { return match(Choice8::a, Choice8::b, Choice8::c, Choice8::d, Choice8::e, Choice8::f, Choice8::g, h -> fn.apply(h).coerce()); } @@ -165,8 +158,8 @@ public Choice8 flatMap( @SuppressWarnings("unchecked") public , TravB extends Traversable>, AppB extends Applicative, - AppTrav extends Applicative> AppTrav traverse(Function fn, - Function pure) { + AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + Fn1 pure) { return match(a -> pure.apply((TravB) Choice8.a(a)).coerce(), b -> pure.apply((TravB) Choice8.b(b)).coerce(), c -> pure.apply((TravB) Choice8.c(c)), @@ -332,10 +325,10 @@ private _A(A a) { } @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn, - Function eFn, Function fFn, - Function gFn, Function hFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn, + Fn1 eFn, Fn1 fFn, + Fn1 gFn, Fn1 hFn) { return aFn.apply(a); } @@ -365,10 +358,10 @@ private _B(B b) { } @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn, - Function eFn, Function fFn, - Function gFn, Function hFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn, + Fn1 eFn, Fn1 fFn, + Fn1 gFn, Fn1 hFn) { return bFn.apply(b); } @@ -398,10 +391,10 @@ private _C(C c) { } @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn, - Function eFn, Function fFn, - Function gFn, Function hFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn, + Fn1 eFn, Fn1 fFn, + Fn1 gFn, Fn1 hFn) { return cFn.apply(c); } @@ -431,10 +424,10 @@ private _D(D d) { } @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn, - Function eFn, Function fFn, - Function gFn, Function hFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn, + Fn1 eFn, Fn1 fFn, + Fn1 gFn, Fn1 hFn) { return dFn.apply(d); } @@ -464,10 +457,10 @@ private _E(E e) { } @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn, - Function eFn, Function fFn, - Function gFn, Function hFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn, + Fn1 eFn, Fn1 fFn, + Fn1 gFn, Fn1 hFn) { return eFn.apply(e); } @@ -497,10 +490,10 @@ private _F(F f) { } @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn, - Function eFn, Function fFn, - Function gFn, Function hFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn, + Fn1 eFn, Fn1 fFn, + Fn1 gFn, Fn1 hFn) { return fFn.apply(f); } @@ -530,10 +523,10 @@ private _G(G g) { } @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn, - Function eFn, Function fFn, - Function gFn, Function hFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn, + Fn1 eFn, Fn1 fFn, + Fn1 gFn, Fn1 hFn) { return gFn.apply(g); } @@ -563,10 +556,10 @@ private _H(H h) { } @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn, - Function eFn, Function fFn, - Function gFn, Function hFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn, + Fn1 eFn, Fn1 fFn, + Fn1 gFn, Fn1 hFn) { return hFn.apply(h); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct2.java b/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct2.java index 5ad1a9908..ecb08fece 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct2.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct2.java @@ -6,8 +6,6 @@ import com.jnape.palatable.lambda.adt.product.Product2; import com.jnape.palatable.lambda.functions.Fn1; -import java.util.function.Function; - import static com.jnape.palatable.lambda.adt.Maybe.just; import static com.jnape.palatable.lambda.adt.Maybe.nothing; import static com.jnape.palatable.lambda.adt.hlist.HList.tuple; @@ -32,12 +30,12 @@ public interface CoProduct2> { /** * Type-safe convergence requiring a match against all potential types. * + * @param result type * @param aFn morphism A -> R * @param bFn morphism B -> R - * @param result type * @return the result of applying the appropriate morphism to this coproduct's unwrapped value */ - R match(Function aFn, Function bFn); + R match(Fn1 aFn, Fn1 bFn); /** * Diverge this coproduct by introducing another possible type that it could represent. As no morphisms can be @@ -63,8 +61,8 @@ public interface CoProduct2> { default CoProduct3> diverge() { return new CoProduct3>() { @Override - public R match(Function aFn, Function bFn, - Function cFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn) { return CoProduct2.this.match(aFn, bFn); } }; @@ -107,7 +105,7 @@ default Maybe projectB() { default CoProduct2> invert() { return new CoProduct2>() { @Override - public R match(Function aFn, Function bFn) { + public R match(Fn1 aFn, Fn1 bFn) { return CoProduct2.this.match(bFn, aFn); } }; @@ -118,14 +116,13 @@ public R match(Function aFn, Function result type * @param aFn morphism A v B -> R, applied in the A case * @param bFn morphism A v B -> R, applied in the B case - * @param result type * @return the result of applying the appropriate morphism to this coproduct */ @SuppressWarnings("unchecked") - default R embed(Function aFn, - Function bFn) { + default R embed(Fn1 aFn, Fn1 bFn) { return this.>match(constantly(fn1(aFn)), constantly(fn1(bFn))) .apply((CP2) this); diff --git a/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct3.java b/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct3.java index 23a97ac9c..aee747317 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct3.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct3.java @@ -1,11 +1,10 @@ package com.jnape.palatable.lambda.adt.coproduct; import com.jnape.palatable.lambda.adt.Maybe; +import com.jnape.palatable.lambda.adt.choice.Choice2; import com.jnape.palatable.lambda.adt.product.Product3; import com.jnape.palatable.lambda.functions.Fn1; -import java.util.function.Function; - import static com.jnape.palatable.lambda.adt.Maybe.just; import static com.jnape.palatable.lambda.adt.Maybe.nothing; import static com.jnape.palatable.lambda.adt.hlist.HList.tuple; @@ -27,15 +26,14 @@ public interface CoProduct3> { /** * Type-safe convergence requiring a match against all potential types. * + * @param result type * @param aFn morphism A -> R * @param bFn morphism B -> R * @param cFn morphism C -> R - * @param result type * @return the result of applying the appropriate morphism to this coproduct's unwrapped value - * @see CoProduct2#match(Function, Function) + * @see CoProduct2#match(Fn1, Fn1) */ - R match(Function aFn, Function bFn, - Function cFn); + R match(Fn1 aFn, Fn1 bFn, Fn1 cFn); /** * Diverge this coproduct by introducing another possible type that it could represent. @@ -47,8 +45,8 @@ R match(Function aFn, Function CoProduct4> diverge() { return new CoProduct4>() { @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn) { return CoProduct3.this.match(aFn, bFn, cFn); } }; @@ -68,18 +66,8 @@ public R match(Function aFn, Function> converge( - Function> convergenceFn) { - return match(a -> new CoProduct2>() { - @Override - public R match(Function aFn, Function bFn) { - return aFn.apply(a); - } - }, b -> new CoProduct2>() { - @Override - public R match(Function aFn, Function bFn) { - return bFn.apply(b); - } - }, convergenceFn); + Fn1> convergenceFn) { + return match(Choice2::a, Choice2::b, convergenceFn::apply); } /** @@ -126,16 +114,15 @@ default Maybe projectC() { * the appropriate morphism to this coproduct as a whole. Like {@link CoProduct3#match}, but without unwrapping the * value. * + * @param result type * @param aFn morphism A v B v C -> R, applied in the A case * @param bFn morphism A v B v C -> R, applied in the B case * @param cFn morphism A v B v C -> R, applied in the C case - * @param result type * @return the result of applying the appropriate morphism to this coproduct */ @SuppressWarnings("unchecked") - default R embed(Function aFn, - Function bFn, - Function cFn) { + default R embed(Fn1 aFn, Fn1 bFn, + Fn1 cFn) { return this.>match(constantly(fn1(aFn)), constantly(fn1(bFn)), constantly(fn1(cFn))) diff --git a/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct4.java b/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct4.java index 2ec2e113d..c8466dfa1 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct4.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct4.java @@ -1,6 +1,7 @@ package com.jnape.palatable.lambda.adt.coproduct; import com.jnape.palatable.lambda.adt.Maybe; +import com.jnape.palatable.lambda.adt.choice.Choice3; import com.jnape.palatable.lambda.adt.product.Product4; import com.jnape.palatable.lambda.functions.Fn1; @@ -28,18 +29,18 @@ public interface CoProduct4> { /** * Type-safe convergence requiring a match against all potential types. * + * @param result type * @param aFn morphism A -> R * @param bFn morphism B -> R * @param cFn morphism C -> R * @param dFn morphism D -> R - * @param result type * @return the result of applying the appropriate morphism from whichever type is represented by this coproduct to R - * @see CoProduct2#match(Function, Function) + * @see CoProduct2#match(Fn1, Fn1) */ - R match(Function aFn, - Function bFn, - Function cFn, - Function dFn); + R match(Fn1 aFn, + Fn1 bFn, + Fn1 cFn, + Fn1 dFn); /** * Diverge this coproduct by introducing another possible type that it could represent. @@ -51,9 +52,9 @@ R match(Function aFn, default CoProduct5> diverge() { return new CoProduct5>() { @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn, - Function eFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn, + Fn1 eFn) { return CoProduct4.this.match(aFn, bFn, cFn, dFn); } }; @@ -68,26 +69,8 @@ public R match(Function aFn, Function> converge( - Function> convergenceFn) { - return match(a -> new CoProduct3>() { - @Override - public R match(Function aFn, Function bFn, - Function cFn) { - return aFn.apply(a); - } - }, b -> new CoProduct3>() { - @Override - public R match(Function aFn, Function bFn, - Function cFn) { - return bFn.apply(b); - } - }, c -> new CoProduct3>() { - @Override - public R match(Function aFn, Function bFn, - Function cFn) { - return cFn.apply(c); - } - }, convergenceFn); + Fn1> convergenceFn) { + return match(Choice3::a, Choice3::b, Choice3::c, convergenceFn::apply); } /** @@ -144,18 +127,18 @@ default Maybe projectD() { * the appropriate morphism to this coproduct as a whole. Like {@link CoProduct4#match}, but without unwrapping the * value. * + * @param result type * @param aFn morphism A v B v C v D -> R, applied in the A case * @param bFn morphism A v B v C v D -> R, applied in the B case * @param cFn morphism A v B v C v D -> R, applied in the C case * @param dFn morphism A v B v C v D -> R, applied in the D case - * @param result type * @return the result of applying the appropriate morphism to this coproduct */ @SuppressWarnings("unchecked") - default R embed(Function aFn, - Function bFn, - Function cFn, - Function dFn) { + default R embed(Fn1 aFn, + Fn1 bFn, + Fn1 cFn, + Fn1 dFn) { return this.>match(constantly(fn1(aFn)), constantly(fn1(bFn)), constantly(fn1(cFn)), diff --git a/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct5.java b/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct5.java index b90aab2f5..03b594ca2 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct5.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct5.java @@ -1,11 +1,10 @@ package com.jnape.palatable.lambda.adt.coproduct; import com.jnape.palatable.lambda.adt.Maybe; +import com.jnape.palatable.lambda.adt.choice.Choice4; import com.jnape.palatable.lambda.adt.product.Product5; import com.jnape.palatable.lambda.functions.Fn1; -import java.util.function.Function; - import static com.jnape.palatable.lambda.adt.Maybe.just; import static com.jnape.palatable.lambda.adt.Maybe.nothing; import static com.jnape.palatable.lambda.adt.hlist.HList.tuple; @@ -29,20 +28,20 @@ public interface CoProduct5 result type * @param aFn morphism A -> R * @param bFn morphism B -> R * @param cFn morphism C -> R * @param dFn morphism D -> R * @param eFn morphism E -> R - * @param result type * @return the result of applying the appropriate morphism from whichever type is represented by this coproduct to R - * @see CoProduct2#match(Function, Function) + * @see CoProduct2#match(Fn1, Fn1) */ - R match(Function aFn, - Function bFn, - Function cFn, - Function dFn, - Function eFn); + R match(Fn1 aFn, + Fn1 bFn, + Fn1 cFn, + Fn1 dFn, + Fn1 eFn); /** * Diverge this coproduct by introducing another possible type that it could represent. @@ -54,9 +53,9 @@ R match(Function aFn, default CoProduct6> diverge() { return new CoProduct6>() { @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn, - Function eFn, Function fFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn, + Fn1 eFn, Fn1 fFn) { return CoProduct5.this.match(aFn, bFn, cFn, dFn, eFn); } }; @@ -70,32 +69,8 @@ public R match(Function aFn, Function> converge( - Function> convergenceFn) { - return match(a -> new CoProduct4>() { - @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn) { - return aFn.apply(a); - } - }, b -> new CoProduct4>() { - @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn) { - return bFn.apply(b); - } - }, c -> new CoProduct4>() { - @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn) { - return cFn.apply(c); - } - }, d -> new CoProduct4>() { - @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn) { - return dFn.apply(d); - } - }, convergenceFn::apply); + Fn1> convergenceFn) { + return match(Choice4::a, Choice4::b, Choice4::c, Choice4::d, convergenceFn::apply); } /** @@ -162,20 +137,20 @@ default Maybe projectE() { * the appropriate morphism to this coproduct as a whole. Like {@link CoProduct5#match}, but without unwrapping the * value. * + * @param result type * @param aFn morphism A v B v C v D v E -> R, applied in the A case * @param bFn morphism A v B v C v D v E -> R, applied in the B case * @param cFn morphism A v B v C v D v E -> R, applied in the C case * @param dFn morphism A v B v C v D v E -> R, applied in the D case * @param eFn morphism A v B v C v D v E -> R, applied in the E case - * @param result type * @return the result of applying the appropriate morphism to this coproduct */ @SuppressWarnings("unchecked") - default R embed(Function aFn, - Function bFn, - Function cFn, - Function dFn, - Function eFn) { + default R embed(Fn1 aFn, + Fn1 bFn, + Fn1 cFn, + Fn1 dFn, + Fn1 eFn) { return this.>match(constantly(fn1(aFn)), constantly(fn1(bFn)), constantly(fn1(cFn)), diff --git a/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct6.java b/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct6.java index a3aa40163..084b3860d 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct6.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct6.java @@ -31,22 +31,22 @@ public interface CoProduct6 result type * @param aFn morphism A -> R * @param bFn morphism B -> R * @param cFn morphism C -> R * @param dFn morphism D -> R * @param eFn morphism E -> R * @param fFn morphism F -> R - * @param result type * @return the result of applying the appropriate morphism from whichever type is represented by this coproduct to R - * @see CoProduct2#match(Function, Function) + * @see CoProduct2#match(Fn1, Fn1) */ - R match(Function aFn, - Function bFn, - Function cFn, - Function dFn, - Function eFn, - Function fFn); + R match(Fn1 aFn, + Fn1 bFn, + Fn1 cFn, + Fn1 dFn, + Fn1 eFn, + Fn1 fFn); /** * Diverge this coproduct by introducing another possible type that it could represent. @@ -58,10 +58,10 @@ R match(Function aFn, default CoProduct7> diverge() { return new CoProduct7>() { @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn, - Function eFn, Function fFn, - Function gFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn, + Fn1 eFn, Fn1 fFn, + Fn1 gFn) { return CoProduct6.this.match(aFn, bFn, cFn, dFn, eFn, fFn); } }; @@ -75,7 +75,7 @@ public R match(Function aFn, Function> converge( - Function> convergenceFn) { + Fn1> convergenceFn) { return match(Choice5::a, Choice5::b, Choice5::c, Choice5::d, Choice5::e, convergenceFn::apply); } @@ -153,22 +153,22 @@ default Maybe projectF() { * the appropriate morphism to this coproduct as a whole. Like {@link CoProduct6#match}, but without unwrapping the * value. * + * @param result type * @param aFn morphism A v B v C v D v E v F -> R, applied in the A case * @param bFn morphism A v B v C v D v E v F -> R, applied in the B case * @param cFn morphism A v B v C v D v E v F -> R, applied in the C case * @param dFn morphism A v B v C v D v E v F -> R, applied in the D case * @param eFn morphism A v B v C v D v E v F -> R, applied in the E case * @param fFn morphism A v B v C v D v E v F -> R, applied in the F case - * @param result type * @return the result of applying the appropriate morphism to this coproduct */ @SuppressWarnings("unchecked") - default R embed(Function aFn, - Function bFn, - Function cFn, - Function dFn, - Function eFn, - Function fFn) { + default R embed(Fn1 aFn, + Fn1 bFn, + Fn1 cFn, + Fn1 dFn, + Fn1 eFn, + Fn1 fFn) { return this.>match(constantly(fn1(aFn)), constantly(fn1(bFn)), constantly(fn1(cFn)), diff --git a/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct7.java b/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct7.java index 18086211c..0f7647f96 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct7.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct7.java @@ -5,8 +5,6 @@ import com.jnape.palatable.lambda.adt.product.Product7; import com.jnape.palatable.lambda.functions.Fn1; -import java.util.function.Function; - import static com.jnape.palatable.lambda.adt.Maybe.just; import static com.jnape.palatable.lambda.adt.Maybe.nothing; import static com.jnape.palatable.lambda.adt.hlist.HList.tuple; @@ -32,6 +30,7 @@ public interface CoProduct7 result type * @param aFn morphism A -> R * @param bFn morphism B -> R * @param cFn morphism C -> R @@ -39,17 +38,16 @@ public interface CoProduct7E -> R * @param fFn morphism F -> R * @param gFn morphism G -> R - * @param result type * @return the result of applying the appropriate morphism from whichever type is represented by this coproduct to R - * @see CoProduct2#match(Function, Function) + * @see CoProduct2#match(Fn1, Fn1) */ - R match(Function aFn, - Function bFn, - Function cFn, - Function dFn, - Function eFn, - Function fFn, - Function gFn); + R match(Fn1 aFn, + Fn1 bFn, + Fn1 cFn, + Fn1 dFn, + Fn1 eFn, + Fn1 fFn, + Fn1 gFn); /** * Diverge this coproduct by introducing another possible type that it could represent. @@ -61,10 +59,10 @@ R match(Function aFn, default CoProduct8> diverge() { return new CoProduct8>() { @Override - public R match(Function aFn, Function bFn, - Function cFn, Function dFn, - Function eFn, Function fFn, - Function gFn, Function hFn) { + public R match(Fn1 aFn, Fn1 bFn, + Fn1 cFn, Fn1 dFn, + Fn1 eFn, Fn1 fFn, + Fn1 gFn, Fn1 hFn) { return CoProduct7.this.match(aFn, bFn, cFn, dFn, eFn, fFn, gFn); } }; @@ -78,7 +76,7 @@ public R match(Function aFn, Function> converge( - Function> convergenceFn) { + Fn1> convergenceFn) { return match(Choice6::a, Choice6::b, Choice6::c, Choice6::d, Choice6::e, Choice6::f, convergenceFn::apply); } @@ -166,6 +164,7 @@ default Maybe projectG() { * the appropriate morphism to this coproduct as a whole. Like {@link CoProduct7#match}, but without unwrapping the * value. * + * @param result type * @param aFn morphism A v B v C v D v E v F v G -> R, applied in the A case * @param bFn morphism A v B v C v D v E v F v G -> R, applied in the B case * @param cFn morphism A v B v C v D v E v F v G -> R, applied in the C case @@ -173,17 +172,16 @@ default Maybe projectG() { * @param eFn morphism A v B v C v D v E v F v G -> R, applied in the E case * @param fFn morphism A v B v C v D v E v F v G -> R, applied in the F case * @param gFn morphism A v B v C v D v E v F v G -> R, applied in the G case - * @param result type * @return the result of applying the appropriate morphism to this coproduct */ @SuppressWarnings("unchecked") - default R embed(Function aFn, - Function bFn, - Function cFn, - Function dFn, - Function eFn, - Function fFn, - Function gFn) { + default R embed(Fn1 aFn, + Fn1 bFn, + Fn1 cFn, + Fn1 dFn, + Fn1 eFn, + Fn1 fFn, + Fn1 gFn) { return this.>match(constantly(fn1(aFn)), constantly(fn1(bFn)), constantly(fn1(cFn)), diff --git a/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct8.java b/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct8.java index 776f067e8..9653e178a 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct8.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct8.java @@ -5,8 +5,6 @@ import com.jnape.palatable.lambda.adt.product.Product8; import com.jnape.palatable.lambda.functions.Fn1; -import java.util.function.Function; - import static com.jnape.palatable.lambda.adt.Maybe.just; import static com.jnape.palatable.lambda.adt.Maybe.nothing; import static com.jnape.palatable.lambda.adt.hlist.HList.tuple; @@ -33,6 +31,7 @@ public interface CoProduct8 result type * @param aFn morphism A -> R * @param bFn morphism B -> R * @param cFn morphism C -> R @@ -41,18 +40,17 @@ public interface CoProduct8F -> R * @param gFn morphism G -> R * @param hFn morphism H -> R - * @param result type * @return the result of applying the appropriate morphism from whichever type is represented by this coproduct to R - * @see CoProduct2#match(Function, Function) + * @see CoProduct2#match(Fn1, Fn1) */ - R match(Function aFn, - Function bFn, - Function cFn, - Function dFn, - Function eFn, - Function fFn, - Function gFn, - Function hFn); + R match(Fn1 aFn, + Fn1 bFn, + Fn1 cFn, + Fn1 dFn, + Fn1 eFn, + Fn1 fFn, + Fn1 gFn, + Fn1 hFn); /** * Converge this coproduct down to a lower order coproduct by mapping the last possible type into an earlier @@ -62,8 +60,9 @@ R match(Function aFn, * @return a {@link CoProduct7}<A, B, C, D, E, F, G> */ default CoProduct7> converge( - Function> convergenceFn) { - return match(Choice7::a, Choice7::b, Choice7::c, Choice7::d, Choice7::e, Choice7::f, Choice7::g, convergenceFn::apply); + Fn1> convergenceFn) { + return match(Choice7::a, Choice7::b, Choice7::c, Choice7::d, Choice7::e, Choice7::f, Choice7::g, + convergenceFn::apply); } /** @@ -160,6 +159,7 @@ default Maybe projectH() { * the appropriate morphism to this coproduct as a whole. Like {@link CoProduct8#match}, but without unwrapping the * value. * + * @param result type * @param aFn morphism A v B v C v D v E v F v G v H -> R, applied in the A case * @param bFn morphism A v B v C v D v E v F v G v H -> R, applied in the B case * @param cFn morphism A v B v C v D v E v F v G v H -> R, applied in the C case @@ -168,18 +168,17 @@ default Maybe projectH() { * @param fFn morphism A v B v C v D v E v F v G v H -> R, applied in the F case * @param gFn morphism A v B v C v D v E v F v G v H -> R, applied in the G case * @param hFn morphism A v B v C v D v E v F v G v H -> R, applied in the H case - * @param result type * @return the result of applying the appropriate morphism to this coproduct */ @SuppressWarnings("unchecked") - default R embed(Function aFn, - Function bFn, - Function cFn, - Function dFn, - Function eFn, - Function fFn, - Function gFn, - Function hFn) { + default R embed(Fn1 aFn, + Fn1 bFn, + Fn1 cFn, + Fn1 dFn, + Fn1 eFn, + Fn1 fFn, + Fn1 gFn, + Fn1 hFn) { return this.>match(constantly(fn1(aFn)), constantly(fn1(bFn)), constantly(fn1(cFn)), diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/SingletonHList.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/SingletonHList.java index 44bff3484..ca8f76b5c 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/SingletonHList.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/SingletonHList.java @@ -2,13 +2,12 @@ import com.jnape.palatable.lambda.adt.hlist.HList.HCons; import com.jnape.palatable.lambda.adt.hlist.HList.HNil; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; -import java.util.function.Function; - /** * A singleton HList. Supports random access. * @@ -33,7 +32,7 @@ public <_0> Tuple2<_0, _1> cons(_0 _0) { } @Override - public <_1Prime> SingletonHList<_1Prime> fmap(Function fn) { + public <_1Prime> SingletonHList<_1Prime> fmap(Fn1 fn) { return Monad.super.<_1Prime>fmap(fn).coerce(); } @@ -44,13 +43,13 @@ public <_1Prime> SingletonHList<_1Prime> pure(_1Prime _1Prime) { @Override public <_1Prime> SingletonHList<_1Prime> zip( - Applicative, SingletonHList> appFn) { + Applicative, SingletonHList> appFn) { return Monad.super.zip(appFn).coerce(); } @Override public <_1Prime> Lazy> lazyZip( - Lazy, SingletonHList>> lazyAppFn) { + Lazy, SingletonHList>> lazyAppFn) { return Monad.super.lazyZip(lazyAppFn).fmap(Monad<_1Prime, SingletonHList>::coerce); } @@ -65,17 +64,15 @@ public <_1Prime> SingletonHList<_1> discardR(Applicative<_1Prime, SingletonHList } @Override - public <_1Prime> SingletonHList<_1Prime> flatMap( - Function>> f) { + public <_1Prime> SingletonHList<_1Prime> flatMap(Fn1>> f) { return f.apply(head()).coerce(); } @Override - @SuppressWarnings("unchecked") public , TravB extends Traversable>, AppB extends Applicative, - AppTrav extends Applicative> AppTrav traverse(Function fn, - Function pure) { + AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + Fn1 pure) { return fn.apply(head()).fmap(SingletonHList::new).fmap(Applicative::coerce).coerce(); } @@ -86,7 +83,7 @@ AppTrav extends Applicative> AppTrav traverse(Function the return type of the function * @return the result of applying the head to the function */ - public R into(Function fn) { + public R into(Fn1 fn) { return fn.apply(head()); } } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple2.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple2.java index 9f952849b..afb1d9e95 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple2.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple2.java @@ -2,6 +2,7 @@ import com.jnape.palatable.lambda.adt.hlist.HList.HCons; import com.jnape.palatable.lambda.adt.product.Product2; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; import com.jnape.palatable.lambda.functor.builtin.Lazy; @@ -9,7 +10,6 @@ import com.jnape.palatable.lambda.traversable.Traversable; import java.util.Map; -import java.util.function.Function; import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; @@ -77,25 +77,25 @@ public Tuple2<_2, _1> invert() { } @Override - public <_2Prime> Tuple2<_1, _2Prime> fmap(Function fn) { + public <_2Prime> Tuple2<_1, _2Prime> fmap(Fn1 fn) { return Monad.super.<_2Prime>fmap(fn).coerce(); } @Override @SuppressWarnings("unchecked") - public <_1Prime> Tuple2<_1Prime, _2> biMapL(Function fn) { + public <_1Prime> Tuple2<_1Prime, _2> biMapL(Fn1 fn) { return (Tuple2<_1Prime, _2>) Bifunctor.super.biMapL(fn); } @Override @SuppressWarnings("unchecked") - public <_2Prime> Tuple2<_1, _2Prime> biMapR(Function fn) { + public <_2Prime> Tuple2<_1, _2Prime> biMapR(Fn1 fn) { return (Tuple2<_1, _2Prime>) Bifunctor.super.biMapR(fn); } @Override - public <_1Prime, _2Prime> Tuple2<_1Prime, _2Prime> biMap(Function lFn, - Function rFn) { + public <_1Prime, _2Prime> Tuple2<_1Prime, _2Prime> biMap(Fn1 lFn, + Fn1 rFn) { return new Tuple2<>(lFn.apply(_1()), tail().fmap(rFn)); } @@ -106,13 +106,13 @@ public <_2Prime> Tuple2<_1, _2Prime> pure(_2Prime _2Prime) { @Override public <_2Prime> Tuple2<_1, _2Prime> zip( - Applicative, Tuple2<_1, ?>> appFn) { + Applicative, Tuple2<_1, ?>> appFn) { return Monad.super.zip(appFn).coerce(); } @Override public <_2Prime> Lazy> lazyZip( - Lazy, Tuple2<_1, ?>>> lazyAppFn) { + Lazy, Tuple2<_1, ?>>> lazyAppFn) { return Monad.super.lazyZip(lazyAppFn).fmap(Monad<_2Prime, Tuple2<_1, ?>>::coerce); } @@ -127,16 +127,15 @@ public <_2Prime> Tuple2<_1, _2> discardR(Applicative<_2Prime, Tuple2<_1, ?>> app } @Override - public <_2Prime> Tuple2<_1, _2Prime> flatMap(Function>> f) { + public <_2Prime> Tuple2<_1, _2Prime> flatMap(Fn1>> f) { return pure(f.apply(_2).>coerce()._2()); } @Override - @SuppressWarnings("unchecked") public <_2Prime, App extends Applicative, TravB extends Traversable<_2Prime, Tuple2<_1, ?>>, AppB extends Applicative<_2Prime, App>, - AppTrav extends Applicative> AppTrav traverse(Function fn, - Function pure) { + AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + Fn1 pure) { return fn.apply(_2).fmap(_2Prime -> fmap(constantly(_2Prime))).fmap(Applicative::coerce).coerce(); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple3.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple3.java index dd57f1771..74f21bc8f 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple3.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple3.java @@ -2,6 +2,7 @@ import com.jnape.palatable.lambda.adt.hlist.HList.HCons; import com.jnape.palatable.lambda.adt.product.Product3; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; import com.jnape.palatable.lambda.functor.builtin.Lazy; @@ -79,25 +80,25 @@ public Tuple3<_2, _1, _3> invert() { @Override @SuppressWarnings("unchecked") - public <_3Prime> Tuple3<_1, _2, _3Prime> fmap(Function fn) { + public <_3Prime> Tuple3<_1, _2, _3Prime> fmap(Fn1 fn) { return (Tuple3<_1, _2, _3Prime>) Monad.super.fmap(fn); } @Override @SuppressWarnings("unchecked") - public <_2Prime> Tuple3<_1, _2Prime, _3> biMapL(Function fn) { + public <_2Prime> Tuple3<_1, _2Prime, _3> biMapL(Fn1 fn) { return (Tuple3<_1, _2Prime, _3>) Bifunctor.super.biMapL(fn); } @Override @SuppressWarnings("unchecked") - public <_3Prime> Tuple3<_1, _2, _3Prime> biMapR(Function fn) { + public <_3Prime> Tuple3<_1, _2, _3Prime> biMapR(Fn1 fn) { return (Tuple3<_1, _2, _3Prime>) Bifunctor.super.biMapR(fn); } @Override - public <_2Prime, _3Prime> Tuple3<_1, _2Prime, _3Prime> biMap(Function lFn, - Function rFn) { + public <_2Prime, _3Prime> Tuple3<_1, _2Prime, _3Prime> biMap(Fn1 lFn, + Fn1 rFn) { return new Tuple3<>(_1(), tail().biMap(lFn, rFn)); } @@ -108,13 +109,13 @@ public <_3Prime> Tuple3<_1, _2, _3Prime> pure(_3Prime _3Prime) { @Override public <_3Prime> Tuple3<_1, _2, _3Prime> zip( - Applicative, Tuple3<_1, _2, ?>> appFn) { - return biMapR(appFn.>>coerce()._3()); + Applicative, Tuple3<_1, _2, ?>> appFn) { + return biMapR(appFn.>>coerce()._3()::apply); } @Override public <_3Prime> Lazy> lazyZip( - Lazy, Tuple3<_1, _2, ?>>> lazyAppFn) { + Lazy, Tuple3<_1, _2, ?>>> lazyAppFn) { return Monad.super.lazyZip(lazyAppFn).fmap(Monad<_3Prime, Tuple3<_1, _2, ?>>::coerce); } @@ -130,16 +131,15 @@ public <_3Prime> Tuple3<_1, _2, _3> discardR(Applicative<_3Prime, Tuple3<_1, _2, @Override public <_3Prime> Tuple3<_1, _2, _3Prime> flatMap( - Function>> f) { + Fn1>> f) { return pure(f.apply(_3).>coerce()._3); } @Override - @SuppressWarnings("unchecked") public <_3Prime, App extends Applicative, TravB extends Traversable<_3Prime, Tuple3<_1, _2, ?>>, AppB extends Applicative<_3Prime, App>, - AppTrav extends Applicative> AppTrav traverse(Function fn, - Function pure) { + AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + Fn1 pure) { return fn.apply(_3).fmap(_3Prime -> fmap(constantly(_3Prime))).fmap(Applicative::coerce).coerce(); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple4.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple4.java index 7ffeb72c5..90a1d3ec6 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple4.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple4.java @@ -2,14 +2,13 @@ import com.jnape.palatable.lambda.adt.hlist.HList.HCons; import com.jnape.palatable.lambda.adt.product.Product4; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; -import java.util.function.Function; - import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; /** @@ -96,23 +95,23 @@ public Tuple4<_2, _1, _3, _4> invert() { } @Override - public <_4Prime> Tuple4<_1, _2, _3, _4Prime> fmap(Function fn) { + public <_4Prime> Tuple4<_1, _2, _3, _4Prime> fmap(Fn1 fn) { return (Tuple4<_1, _2, _3, _4Prime>) Monad.super.<_4Prime>fmap(fn); } @Override - public <_3Prime> Tuple4<_1, _2, _3Prime, _4> biMapL(Function fn) { + public <_3Prime> Tuple4<_1, _2, _3Prime, _4> biMapL(Fn1 fn) { return (Tuple4<_1, _2, _3Prime, _4>) Bifunctor.super.<_3Prime>biMapL(fn); } @Override - public <_4Prime> Tuple4<_1, _2, _3, _4Prime> biMapR(Function fn) { + public <_4Prime> Tuple4<_1, _2, _3, _4Prime> biMapR(Fn1 fn) { return (Tuple4<_1, _2, _3, _4Prime>) Bifunctor.super.<_4Prime>biMapR(fn); } @Override - public <_3Prime, _4Prime> Tuple4<_1, _2, _3Prime, _4Prime> biMap(Function lFn, - Function rFn) { + public <_3Prime, _4Prime> Tuple4<_1, _2, _3Prime, _4Prime> biMap(Fn1 lFn, + Fn1 rFn) { return new Tuple4<>(_1(), tail().biMap(lFn, rFn)); } @@ -123,13 +122,13 @@ public <_4Prime> Tuple4<_1, _2, _3, _4Prime> pure(_4Prime _4Prime) { @Override public <_4Prime> Tuple4<_1, _2, _3, _4Prime> zip( - Applicative, Tuple4<_1, _2, _3, ?>> appFn) { - return biMapR(appFn.>>coerce()._4()); + Applicative, Tuple4<_1, _2, _3, ?>> appFn) { + return biMapR(appFn.>>coerce()._4()::apply); } @Override public <_4Prime> Lazy> lazyZip( - Lazy, Tuple4<_1, _2, _3, ?>>> lazyAppFn) { + Lazy, Tuple4<_1, _2, _3, ?>>> lazyAppFn) { return Monad.super.lazyZip(lazyAppFn).fmap(Monad<_4Prime, Tuple4<_1, _2, _3, ?>>::coerce); } @@ -145,16 +144,15 @@ public <_4Prime> Tuple4<_1, _2, _3, _4> discardR(Applicative<_4Prime, Tuple4<_1, @Override public <_4Prime> Tuple4<_1, _2, _3, _4Prime> flatMap( - Function>> f) { + Fn1>> f) { return pure(f.apply(_4).>coerce()._4); } @Override - @SuppressWarnings("unchecked") public <_4Prime, App extends Applicative, TravB extends Traversable<_4Prime, Tuple4<_1, _2, _3, ?>>, AppB extends Applicative<_4Prime, App>, - AppTrav extends Applicative> AppTrav traverse(Function fn, - Function pure) { + AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + Fn1 pure) { return fn.apply(_4).fmap(_4Prime -> fmap(constantly(_4Prime))).fmap(Applicative::coerce).coerce(); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple5.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple5.java index 7e6eeb24f..2e321fbae 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple5.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple5.java @@ -2,14 +2,13 @@ import com.jnape.palatable.lambda.adt.hlist.HList.HCons; import com.jnape.palatable.lambda.adt.product.Product5; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; -import java.util.function.Function; - import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; /** @@ -114,25 +113,25 @@ public Tuple5<_2, _1, _3, _4, _5> invert() { } @Override - public <_5Prime> Tuple5<_1, _2, _3, _4, _5Prime> fmap(Function fn) { + public <_5Prime> Tuple5<_1, _2, _3, _4, _5Prime> fmap(Fn1 fn) { return Monad.super.<_5Prime>fmap(fn).coerce(); } @Override @SuppressWarnings("unchecked") - public <_4Prime> Tuple5<_1, _2, _3, _4Prime, _5> biMapL(Function fn) { + public <_4Prime> Tuple5<_1, _2, _3, _4Prime, _5> biMapL(Fn1 fn) { return (Tuple5<_1, _2, _3, _4Prime, _5>) Bifunctor.super.biMapL(fn); } @Override @SuppressWarnings("unchecked") - public <_5Prime> Tuple5<_1, _2, _3, _4, _5Prime> biMapR(Function fn) { + public <_5Prime> Tuple5<_1, _2, _3, _4, _5Prime> biMapR(Fn1 fn) { return (Tuple5<_1, _2, _3, _4, _5Prime>) Bifunctor.super.biMapR(fn); } @Override - public <_4Prime, _5Prime> Tuple5<_1, _2, _3, _4Prime, _5Prime> biMap(Function lFn, - Function rFn) { + public <_4Prime, _5Prime> Tuple5<_1, _2, _3, _4Prime, _5Prime> biMap(Fn1 lFn, + Fn1 rFn) { return new Tuple5<>(_1(), tail().biMap(lFn, rFn)); } @@ -143,13 +142,13 @@ public <_5Prime> Tuple5<_1, _2, _3, _4, _5Prime> pure(_5Prime _5Prime) { @Override public <_5Prime> Tuple5<_1, _2, _3, _4, _5Prime> zip( - Applicative, Tuple5<_1, _2, _3, _4, ?>> appFn) { + Applicative, Tuple5<_1, _2, _3, _4, ?>> appFn) { return Monad.super.zip(appFn).coerce(); } @Override public <_5Prime> Lazy> lazyZip( - Lazy, Tuple5<_1, _2, _3, _4, ?>>> lazyAppFn) { + Lazy, Tuple5<_1, _2, _3, _4, ?>>> lazyAppFn) { return Monad.super.lazyZip(lazyAppFn).fmap(Monad<_5Prime, Tuple5<_1, _2, _3, _4, ?>>::coerce); } @@ -165,16 +164,15 @@ public <_5Prime> Tuple5<_1, _2, _3, _4, _5> discardR(Applicative<_5Prime, Tuple5 @Override public <_5Prime> Tuple5<_1, _2, _3, _4, _5Prime> flatMap( - Function>> f) { + Fn1>> f) { return pure(f.apply(_5).>coerce()._5()); } @Override - @SuppressWarnings("unchecked") public <_5Prime, App extends Applicative, TravB extends Traversable<_5Prime, Tuple5<_1, _2, _3, _4, ?>>, AppB extends Applicative<_5Prime, App>, - AppTrav extends Applicative> AppTrav traverse(Function fn, - Function pure) { + AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + Fn1 pure) { return fn.apply(_5).fmap(_3Prime -> fmap(constantly(_3Prime))).fmap(Applicative::coerce).coerce(); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple6.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple6.java index 464a5abcd..4ec22546b 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple6.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple6.java @@ -2,14 +2,13 @@ import com.jnape.palatable.lambda.adt.hlist.HList.HCons; import com.jnape.palatable.lambda.adt.product.Product6; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; -import java.util.function.Function; - import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; /** @@ -133,26 +132,26 @@ public Tuple6<_2, _1, _3, _4, _5, _6> invert() { } @Override - public <_6Prime> Tuple6<_1, _2, _3, _4, _5, _6Prime> fmap(Function fn) { + public <_6Prime> Tuple6<_1, _2, _3, _4, _5, _6Prime> fmap(Fn1 fn) { return Monad.super.<_6Prime>fmap(fn).coerce(); } @Override @SuppressWarnings("unchecked") - public <_5Prime> Tuple6<_1, _2, _3, _4, _5Prime, _6> biMapL(Function fn) { + public <_5Prime> Tuple6<_1, _2, _3, _4, _5Prime, _6> biMapL(Fn1 fn) { return (Tuple6<_1, _2, _3, _4, _5Prime, _6>) Bifunctor.super.biMapL(fn); } @Override @SuppressWarnings("unchecked") - public <_6Prime> Tuple6<_1, _2, _3, _4, _5, _6Prime> biMapR(Function fn) { + public <_6Prime> Tuple6<_1, _2, _3, _4, _5, _6Prime> biMapR(Fn1 fn) { return (Tuple6<_1, _2, _3, _4, _5, _6Prime>) Bifunctor.super.biMapR(fn); } @Override public <_5Prime, _6Prime> Tuple6<_1, _2, _3, _4, _5Prime, _6Prime> biMap( - Function lFn, - Function rFn) { + Fn1 lFn, + Fn1 rFn) { return new Tuple6<>(_1(), tail().biMap(lFn, rFn)); } @@ -163,13 +162,13 @@ public <_6Prime> Tuple6<_1, _2, _3, _4, _5, _6Prime> pure(_6Prime _6Prime) { @Override public <_6Prime> Tuple6<_1, _2, _3, _4, _5, _6Prime> zip( - Applicative, Tuple6<_1, _2, _3, _4, _5, ?>> appFn) { + Applicative, Tuple6<_1, _2, _3, _4, _5, ?>> appFn) { return Monad.super.zip(appFn).coerce(); } @Override public <_6Prime> Lazy> lazyZip( - Lazy, Tuple6<_1, _2, _3, _4, _5, ?>>> lazyAppFn) { + Lazy, Tuple6<_1, _2, _3, _4, _5, ?>>> lazyAppFn) { return Monad.super.lazyZip(lazyAppFn).fmap(Monad<_6Prime, Tuple6<_1, _2, _3, _4, _5, ?>>::coerce); } @@ -186,16 +185,15 @@ public <_6Prime> Tuple6<_1, _2, _3, _4, _5, _6> discardR(Applicative<_6Prime, Tu @Override public <_6Prime> Tuple6<_1, _2, _3, _4, _5, _6Prime> flatMap( - Function>> f) { + Fn1>> f) { return pure(f.apply(_6).>coerce()._6()); } @Override - @SuppressWarnings("unchecked") public <_6Prime, App extends Applicative, TravB extends Traversable<_6Prime, Tuple6<_1, _2, _3, _4, _5, ?>>, AppB extends Applicative<_6Prime, App>, - AppTrav extends Applicative> AppTrav traverse(Function fn, - Function pure) { + AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + Fn1 pure) { return fn.apply(_6).fmap(_6Prime -> fmap(constantly(_6Prime))).fmap(Applicative::coerce).coerce(); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple7.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple7.java index bd0c6bbf4..e42cc4968 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple7.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple7.java @@ -2,14 +2,13 @@ import com.jnape.palatable.lambda.adt.hlist.HList.HCons; import com.jnape.palatable.lambda.adt.product.Product7; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; -import java.util.function.Function; - import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; /** @@ -152,26 +151,26 @@ public Tuple7<_2, _1, _3, _4, _5, _6, _7> invert() { } @Override - public <_7Prime> Tuple7<_1, _2, _3, _4, _5, _6, _7Prime> fmap(Function fn) { + public <_7Prime> Tuple7<_1, _2, _3, _4, _5, _6, _7Prime> fmap(Fn1 fn) { return Monad.super.<_7Prime>fmap(fn).coerce(); } @Override @SuppressWarnings("unchecked") - public <_6Prime> Tuple7<_1, _2, _3, _4, _5, _6Prime, _7> biMapL(Function fn) { + public <_6Prime> Tuple7<_1, _2, _3, _4, _5, _6Prime, _7> biMapL(Fn1 fn) { return (Tuple7<_1, _2, _3, _4, _5, _6Prime, _7>) Bifunctor.super.biMapL(fn); } @Override @SuppressWarnings("unchecked") - public <_7Prime> Tuple7<_1, _2, _3, _4, _5, _6, _7Prime> biMapR(Function fn) { + public <_7Prime> Tuple7<_1, _2, _3, _4, _5, _6, _7Prime> biMapR(Fn1 fn) { return (Tuple7<_1, _2, _3, _4, _5, _6, _7Prime>) Bifunctor.super.biMapR(fn); } @Override public <_6Prime, _7Prime> Tuple7<_1, _2, _3, _4, _5, _6Prime, _7Prime> biMap( - Function lFn, - Function rFn) { + Fn1 lFn, + Fn1 rFn) { return new Tuple7<>(_1(), tail().biMap(lFn, rFn)); } @@ -182,13 +181,13 @@ public <_7Prime> Tuple7<_1, _2, _3, _4, _5, _6, _7Prime> pure(_7Prime _7Prime) { @Override public <_7Prime> Tuple7<_1, _2, _3, _4, _5, _6, _7Prime> zip( - Applicative, Tuple7<_1, _2, _3, _4, _5, _6, ?>> appFn) { + Applicative, Tuple7<_1, _2, _3, _4, _5, _6, ?>> appFn) { return Monad.super.zip(appFn).coerce(); } @Override public <_7Prime> Lazy> lazyZip( - Lazy, Tuple7<_1, _2, _3, _4, _5, _6, ?>>> lazyAppFn) { + Lazy, Tuple7<_1, _2, _3, _4, _5, _6, ?>>> lazyAppFn) { return Monad.super.lazyZip(lazyAppFn).fmap(Monad<_7Prime, Tuple7<_1, _2, _3, _4, _5, _6, ?>>::coerce); } @@ -206,17 +205,16 @@ public <_7Prime> Tuple7<_1, _2, _3, _4, _5, _6, _7> discardR( @Override public <_7Prime> Tuple7<_1, _2, _3, _4, _5, _6, _7Prime> flatMap( - Function>> f) { + Fn1>> f) { return pure(f.apply(_7).>coerce()._7()); } @Override - @SuppressWarnings("unchecked") public <_7Prime, App extends Applicative, TravB extends Traversable<_7Prime, Tuple7<_1, _2, _3, _4, _5, _6, ?>>, AppB extends Applicative<_7Prime, App>, - AppTrav extends Applicative> AppTrav traverse(Function fn, - Function pure) { + AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + Fn1 pure) { return fn.apply(_7).fmap(_7Prime -> fmap(constantly(_7Prime))).fmap(Applicative::coerce).coerce(); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple8.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple8.java index b30e68a76..e9db4aba9 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple8.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple8.java @@ -2,14 +2,13 @@ import com.jnape.palatable.lambda.adt.hlist.HList.HCons; import com.jnape.palatable.lambda.adt.product.Product8; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; -import java.util.function.Function; - import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; /** @@ -171,26 +170,26 @@ public Tuple8<_2, _1, _3, _4, _5, _6, _7, _8> invert() { } @Override - public <_8Prime> Tuple8<_1, _2, _3, _4, _5, _6, _7, _8Prime> fmap(Function fn) { + public <_8Prime> Tuple8<_1, _2, _3, _4, _5, _6, _7, _8Prime> fmap(Fn1 fn) { return Monad.super.<_8Prime>fmap(fn).coerce(); } @Override @SuppressWarnings("unchecked") - public <_7Prime> Tuple8<_1, _2, _3, _4, _5, _6, _7Prime, _8> biMapL(Function fn) { + public <_7Prime> Tuple8<_1, _2, _3, _4, _5, _6, _7Prime, _8> biMapL(Fn1 fn) { return (Tuple8<_1, _2, _3, _4, _5, _6, _7Prime, _8>) Bifunctor.super.biMapL(fn); } @Override @SuppressWarnings("unchecked") - public <_8Prime> Tuple8<_1, _2, _3, _4, _5, _6, _7, _8Prime> biMapR(Function fn) { + public <_8Prime> Tuple8<_1, _2, _3, _4, _5, _6, _7, _8Prime> biMapR(Fn1 fn) { return (Tuple8<_1, _2, _3, _4, _5, _6, _7, _8Prime>) Bifunctor.super.biMapR(fn); } @Override public <_7Prime, _8Prime> Tuple8<_1, _2, _3, _4, _5, _6, _7Prime, _8Prime> biMap( - Function lFn, - Function rFn) { + Fn1 lFn, + Fn1 rFn) { return new Tuple8<>(_1(), tail().biMap(lFn, rFn)); } @@ -201,13 +200,13 @@ public <_8Prime> Tuple8<_1, _2, _3, _4, _5, _6, _7, _8Prime> pure(_8Prime _8Prim @Override public <_8Prime> Tuple8<_1, _2, _3, _4, _5, _6, _7, _8Prime> zip( - Applicative, Tuple8<_1, _2, _3, _4, _5, _6, _7, ?>> appFn) { + Applicative, Tuple8<_1, _2, _3, _4, _5, _6, _7, ?>> appFn) { return Monad.super.zip(appFn).coerce(); } @Override public <_8Prime> Lazy> lazyZip( - Lazy, + Lazy, Tuple8<_1, _2, _3, _4, _5, _6, _7, ?>>> lazyAppFn) { return Monad.super.lazyZip(lazyAppFn).fmap(Monad<_8Prime, Tuple8<_1, _2, _3, _4, _5, _6, _7, ?>>::coerce); } @@ -226,17 +225,16 @@ public <_8Prime> Tuple8<_1, _2, _3, _4, _5, _6, _7, _8> discardR( @Override public <_8Prime> Tuple8<_1, _2, _3, _4, _5, _6, _7, _8Prime> flatMap( - Function>> f) { + Fn1>> f) { return pure(f.apply(_8).>coerce()._8()); } @Override - @SuppressWarnings("unchecked") public <_8Prime, App extends Applicative, TravB extends Traversable<_8Prime, Tuple8<_1, _2, _3, _4, _5, _6, _7, ?>>, AppB extends Applicative<_8Prime, App>, - AppTrav extends Applicative> AppTrav traverse(Function fn, - Function pure) { + AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + Fn1 pure) { return fn.apply(_8).fmap(_8Prime -> fmap(constantly(_8Prime))).fmap(Applicative::coerce).coerce(); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/product/Product2.java b/src/main/java/com/jnape/palatable/lambda/adt/product/Product2.java index 4c3d64da0..0a76df761 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/product/Product2.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/product/Product2.java @@ -1,9 +1,9 @@ package com.jnape.palatable.lambda.adt.product; import com.jnape.palatable.lambda.adt.hlist.Tuple2; +import com.jnape.palatable.lambda.functions.Fn2; import java.util.Map; -import java.util.function.BiFunction; /** * The minimal shape of the combination of two potentially distinctly typed values, supporting destructuring via @@ -35,11 +35,11 @@ public interface Product2<_1, _2> extends Map.Entry<_1, _2> { * Destructure and apply this product to a function accepting the same number of arguments as this product's * slots. This can be thought of as a kind of dual to uncurrying a function and applying a product to it. * - * @param fn the function to apply * @param the return type of the function + * @param fn the function to apply * @return the result of applying the destructured product to the function */ - default R into(BiFunction fn) { + default R into(Fn2 fn) { return fn.apply(_1(), _2()); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/product/Product3.java b/src/main/java/com/jnape/palatable/lambda/adt/product/Product3.java index 063456453..18da0491f 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/product/Product3.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/product/Product3.java @@ -30,7 +30,7 @@ public interface Product3<_1, _2, _3> extends Product2<_1, _2> { * @return the result of applying the destructured product to the function */ default R into(Fn3 fn) { - return Product2.super.into(fn.toBiFunction()).apply(_3()); + return Product2.super.into(fn).apply(_3()); } /** diff --git a/src/main/java/com/jnape/palatable/lambda/adt/product/Product4.java b/src/main/java/com/jnape/palatable/lambda/adt/product/Product4.java index 2703f8229..87a33376d 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/product/Product4.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/product/Product4.java @@ -1,6 +1,7 @@ package com.jnape.palatable.lambda.adt.product; import com.jnape.palatable.lambda.adt.hlist.Tuple4; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functions.Fn4; /** @@ -31,7 +32,7 @@ public interface Product4<_1, _2, _3, _4> extends Product3<_1, _2, _3> { * @return the result of applying the destructured product to the function */ default R into(Fn4 fn) { - return Product3.super.into(fn).apply(_4()); + return Product3.super.>into(fn).apply(_4()); } /** diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Effect.java b/src/main/java/com/jnape/palatable/lambda/functions/Effect.java index 3115bef10..8516c19c8 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Effect.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Effect.java @@ -1,13 +1,14 @@ package com.jnape.palatable.lambda.functions; import com.jnape.palatable.lambda.adt.Unit; +import com.jnape.palatable.lambda.functions.specialized.SideEffect; import com.jnape.palatable.lambda.functions.specialized.checked.Runtime; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.io.IO; import java.util.function.Consumer; -import java.util.function.Function; +import static com.jnape.palatable.lambda.adt.Unit.UNIT; import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; import static com.jnape.palatable.lambda.io.IO.io; @@ -16,76 +17,77 @@ * * @param the argument type * @see Fn0 - * @see Consumer */ @FunctionalInterface -public interface Effect extends Fn1>, Consumer { +public interface Effect extends Fn1> { - void checkedAccept(A a) throws Throwable; + @Override + IO checkedApply(A a) throws Throwable; + + /** + * Convert this {@link Effect} to a java {@link Consumer} + * + * @return the {@link Consumer} + */ + default Consumer toConsumer() { + return a -> apply(a).unsafePerformIO(); + } + /** + * {@inheritDoc} + */ @Override - default void accept(A a) { + default IO apply(A a) { try { - checkedAccept(a); + return checkedApply(a); } catch (Throwable t) { throw Runtime.throwChecked(t); } } + /** + * {@inheritDoc} + */ @Override - default IO apply(A a) { - return io(() -> accept(a)); - } - - @Override - default IO checkedApply(A a) throws Throwable { - return io(() -> accept(a)); - } - - @Override - default Effect diMapL(Function fn) { + default Effect diMapL(Fn1 fn) { return effect(Fn1.super.diMapL(fn)); } + /** + * {@inheritDoc} + */ @Override - default Effect contraMap(Function fn) { + default Effect contraMap(Fn1 fn) { return effect(Fn1.super.contraMap(fn)); } - @Override - default Effect compose(Function before) { - return effect(Fn1.super.compose(before)); - } - + /** + * {@inheritDoc} + */ @Override default Effect discardR(Applicative> appB) { return effect(Fn1.super.discardR(appB)); } - @Override - default Effect andThen(Consumer after) { - return Consumer.super.andThen(after)::accept; - } - /** - * Static factory method to aid in inference. + * Static factory method to create an {@link Effect} from a java {@link Consumer}. * - * @param effect the effect - * @param the effect argument type - * @return the effect + * @param consumer the {@link Consumer} + * @param the input type + * @return the {@link Effect} */ - static Effect effect(Consumer effect) { - return effect::accept; + static Effect fromConsumer(Consumer consumer) { + return a -> io(() -> consumer.accept(a)); } /** - * Create an {@link Effect} from a {@link Runnable}; + * Create an {@link Effect} from a {@link SideEffect}; * - * @param runnable the runnable - * @return the effect + * @param sideEffect the {@link SideEffect} + * @return the {@link Effect} */ - static Effect effect(Runnable runnable) { - return effect(constantly(io(runnable))); + static Effect effect(SideEffect sideEffect) { + return effect(constantly(io(sideEffect))); } /** @@ -96,6 +98,6 @@ static Effect effect(Runnable runnable) { * @return the effect */ static Effect effect(Fn1> fn) { - return a -> fn.apply(a).unsafePerformIO(); + return fn.fmap(io -> io.fmap(constantly(UNIT)))::apply; } } \ No newline at end of file diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn0.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn0.java index 902bcd940..3352046fe 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Fn0.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn0.java @@ -5,7 +5,6 @@ import com.jnape.palatable.lambda.monad.Monad; import java.util.concurrent.Callable; -import java.util.function.Function; import java.util.function.Supplier; import static com.jnape.palatable.lambda.adt.Unit.UNIT; @@ -15,11 +14,10 @@ * * @param the result type * @see Fn1 - * @see Supplier * @see Callable */ @FunctionalInterface -public interface Fn0 extends Fn1, Supplier, Callable { +public interface Fn0 extends Fn1 { A checkedApply() throws Throwable; @@ -32,6 +30,24 @@ default A apply() { return apply(UNIT); } + /** + * Convert this {@link Fn0} to a java {@link Supplier} + * + * @return the {@link Supplier} + */ + default Supplier toSupplier() { + return this::apply; + } + + /** + * Convert this {@link Fn0} to a java {@link Callable} + * + * @return the {@link Callable} + */ + default Callable toCallable() { + return this::apply; + } + /** * {@inheritDoc} */ @@ -41,12 +57,12 @@ default A checkedApply(Unit unit) throws Throwable { } @Override - default Fn0 flatMap(Function>> f) { + default Fn0 flatMap(Fn1>> f) { return Fn1.super.flatMap(f).thunk(UNIT); } @Override - default Fn0 fmap(Function f) { + default Fn0 fmap(Fn1 f) { return Fn1.super.fmap(f).thunk(UNIT); } @@ -56,7 +72,7 @@ default Fn0 pure(B b) { } @Override - default Fn0 zip(Applicative, Fn1> appFn) { + default Fn0 zip(Applicative, Fn1> appFn) { return Fn1.super.zip(appFn).thunk(UNIT); } @@ -76,30 +92,10 @@ default Fn0 discardR(Applicative> appB) { } @Override - default Fn0 diMapR(Function fn) { + default Fn0 diMapR(Fn1 fn) { return Fn1.super.diMapR(fn).thunk(UNIT); } - @Override - default Fn1 compose(Function before) { - return Fn1.super.compose(before)::apply; - } - - @Override - default Fn0 andThen(Function after) { - return Fn1.super.andThen(after).thunk(UNIT); - } - - @Override - default A get() { - return apply(); - } - - @Override - default A call() { - return apply(); - } - /** * Convenience method for converting a {@link Supplier} to an {@link Fn0}. * @@ -107,42 +103,41 @@ default A call() { * @param the output type * @return the {@link Fn0} */ - static Fn0 fn0(Supplier supplier) { + static Fn0 fromSupplier(Supplier supplier) { return supplier::get; } /** - * Static factory method for coercing a lambda to an {@link Fn0}. + * Convenience method for converting a {@link Callable} to an {@link Fn0}. * - * @param fn the lambda to coerce - * @param the output type + * @param callable the callable + * @param the output type * @return the {@link Fn0} */ - static Fn0 fn0(Fn0 fn) { - return fn; + static Fn0 fromCallable(Callable callable) { + return callable::call; } /** - * Static factory method for adapting a {@link Runnable} to an {@link Fn0}<{@link Unit}>. + * Static factory method for coercing a lambda to an {@link Fn0}. * - * @param runnable the {@link Runnable} + * @param fn the lambda to coerce + * @param the output type * @return the {@link Fn0} */ - static Fn0 fn0(Runnable runnable) { - return fn0(() -> { - runnable.run(); - return UNIT; - }); + static Fn0 fn0(Fn0 fn) { + return fn; } /** - * Static factory method for adapting a {@link Function} to an {@link Fn0}. + * Static factory method for adapting an {@link Fn1}<Unit, A> to an + * {@link Fn0}<A>. * - * @param fn the {@link Function} + * @param fn the {@link Fn1} * @param the output type * @return the {@link Fn0} */ - static Fn0 fn0(Function fn) { + static Fn0 fn0(Fn1 fn) { return fn0(() -> fn.apply(UNIT)); } } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java index 8704f92f4..49c69d2de 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java @@ -10,7 +10,6 @@ import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; -import java.util.function.BiFunction; import java.util.function.Function; import static com.jnape.palatable.lambda.functions.Fn2.fn2; @@ -27,8 +26,7 @@ public interface Fn1 extends Monad>, Cartesian>, - Cocartesian>, - Function { + Cocartesian> { /** * Invoke this function explosively with the given argument. @@ -49,6 +47,7 @@ default B apply(A a) { * * @param a the argument * @return the result of the function application + * @throws Throwable anything possibly thrown by the function */ B checkedApply(A a) throws Throwable; @@ -73,11 +72,20 @@ default Fn2 widen() { return fn2(constantly(this)); } + /** + * Convert this {@link Fn1} to a java {@link Function}. + * + * @return the {@link Function} + */ + default Function toFunction() { + return this::apply; + } + /** * {@inheritDoc} */ @Override - default Fn1 flatMap(Function>> f) { + default Fn1 flatMap(Fn1>> f) { return a -> f.apply(apply(a)).>coerce().apply(a); } @@ -89,8 +97,8 @@ default Fn1 flatMap(Function>> * @return a function representing the composition of this function and f */ @Override - default Fn1 fmap(Function f) { - return Monad.super.fmap(f).coerce(); + default Fn1 fmap(Fn1 f) { + return a -> f.apply(apply(a)); } /** @@ -105,7 +113,7 @@ default Fn1 pure(C c) { * {@inheritDoc} */ @Override - default Fn1 zip(Applicative, Fn1> appFn) { + default Fn1 zip(Applicative, Fn1> appFn) { return Monad.super.zip(appFn).coerce(); } @@ -114,15 +122,14 @@ default Fn1 zip(Applicative, Fn1 Fn1 zip(Fn2 appFn) { - return zip((Fn1>) (Object) appFn); + return zip((Fn1>) (Object) appFn); } /** * {@inheritDoc} */ @Override - default Lazy> lazyZip( - Lazy, Fn1>> lazyAppFn) { + default Lazy> lazyZip(Lazy, Fn1>> lazyAppFn) { return Monad.super.lazyZip(lazyAppFn).fmap(Monad>::coerce); } @@ -151,7 +158,7 @@ default Fn1 discardR(Applicative> appB) { * @return an {@link Fn1}<Z, B> */ @Override - default Fn1 diMapL(Function fn) { + default Fn1 diMapL(Fn1 fn) { return (Fn1) Cartesian.super.diMapL(fn); } @@ -164,7 +171,7 @@ default Fn1 diMapL(Function fn) { * @return an {@link Fn1}<A, C> */ @Override - default Fn1 diMapR(Function fn) { + default Fn1 diMapR(Fn1 fn) { return (Fn1) Cartesian.super.diMapR(fn); } @@ -178,8 +185,8 @@ default Fn1 diMapR(Function fn) { * @return an {@link Fn1}<Z, C> */ @Override - default Fn1 diMap(Function lFn, Function rFn) { - return lFn.andThen(this).andThen(rFn)::apply; + default Fn1 diMap(Fn1 lFn, Fn1 rFn) { + return lFn.fmap(this).fmap(rFn)::apply; } /** @@ -222,36 +229,12 @@ default Fn1> choose() { return a -> Either.trying(() -> apply(a), constantly(a)).match(Choice2::a, Choice2::b); } - @Override - default Fn1 contraMap(Function fn) { - return (Fn1) Cartesian.super.contraMap(fn); - } - /** - * Override of {@link Function#compose(Function)}, returning an instance of {@link Fn1} for compatibility. - * Right-to-left composition. - * - * @param before the function who's return value is this function's argument - * @param the new argument type - * @return an {@link Fn1}<Z, B> + * {@inheritDoc} */ @Override - default Fn1 compose(Function before) { - return z -> apply(before.apply(z)); - } - - /** - * Right-to-left composition between different arity functions. Preserves highest arity in the return type, - * specialized to lambda types (in this case, {@link BiFunction} -> {@link Fn2}). - * - * @param before the function to pass its return value to this function's input - * @param the resulting function's first argument type - * @param the resulting function's second argument type - * @return an {@link Fn2}<Y, Z, B> - */ - @SuppressWarnings({"overloads"}) - default Fn2 compose(BiFunction before) { - return compose(fn2(before)); + default Fn1 contraMap(Fn1 fn) { + return (Fn1) Cartesian.super.contraMap(fn); } /** @@ -262,47 +245,43 @@ default Fn2 compose(BiFunction the resulting function's second argument type * @return an {@link Fn2}<Y, Z, B> */ - @SuppressWarnings({"overloads"}) default Fn2 compose(Fn2 before) { - return fn2(before.fmap(this::compose))::apply; + return fn2(before.fmap(this::contraMap))::apply; } /** - * Left-to-right composition between different arity functions. Preserves highest arity in the return type, - * specialized to lambda types (in this case, {@link BiFunction} -> {@link Fn2}). + * Left-to-right composition between different arity functions. Preserves highest arity in the return type. * * @param after the function to invoke on this function's return value * @param the resulting function's second argument type * @param the resulting function's return type * @return an {@link Fn2}<A, C, D> */ - default Fn2 andThen(BiFunction after) { + default Fn2 andThen(Fn2 after) { return (a, c) -> after.apply(apply(a), c); } /** - * Override of {@link Function#andThen(Function)}, returning an instance of {@link Fn1} for compatibility. - * Left-to-right composition. + * Static factory method for avoid explicit casting when using method references as {@link Fn1}s. * - * @param after the function to invoke on this function's return value - * @param the new result type - * @return an {@link Fn1}<A, C> + * @param fn the function to adapt + * @param the input type + * @param the output type + * @return the {@link Fn1} */ - @Override - default Fn1 andThen(Function after) { - return a -> after.apply(apply(a)); + static Fn1 fn1(Fn1 fn) { + return fn::apply; } /** - * Static factory method for wrapping a {@link Function} in an {@link Fn1}. Useful for avoid explicit casting when - * using method references as {@link Fn1}s. + * Static factory method for wrapping a java {@link Function} in an {@link Fn1}. * - * @param function the function to adapt - * @param the input argument type + * @param function the function + * @param the input type * @param the output type * @return the {@link Fn1} */ - static Fn1 fn1(Function function) { + static Fn1 fromFunction(Function function) { return function::apply; } } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn2.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn2.java index cbe3a0929..7620ea9a7 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Fn2.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn2.java @@ -57,18 +57,6 @@ default Fn3 widen() { return fn3(constantly(this)); } - /** - * Same as normal composition, except that the result is an instance of {@link Fn2} for convenience. - * - * @param before the function who's return value is this function's argument - * @param the new argument type - * @return an {@link Fn2}<Z, B, C> - */ - @Override - default Fn2 compose(Function before) { - return fn2(Fn1.super.compose(before)); - } - /** * Partially apply this function by passing its first argument. * @@ -120,7 +108,7 @@ default Fn2 discardR(Applicative> appB) { * {@inheritDoc} */ @Override - default Fn2 diMapL(Function fn) { + default Fn2 diMapL(Fn1 fn) { return fn2(Fn1.super.diMapL(fn)); } @@ -128,18 +116,10 @@ default Fn2 diMapL(Function fn) { * {@inheritDoc} */ @Override - default Fn2 contraMap(Function fn) { + default Fn2 contraMap(Fn1 fn) { return fn2(Fn1.super.contraMap(fn)); } - /** - * {@inheritDoc} - */ - @Override - default Fn3 compose(BiFunction before) { - return fn3(Fn1.super.compose(before)); - } - /** * {@inheritDoc} */ @@ -149,8 +129,7 @@ default Fn3 compose(Fn2 be } /** - * Static factory method for wrapping a {@link BiFunction} in an {@link Fn2}. Useful for avoid explicit casting when - * using method references as {@link Fn2}s. + * Static factory method for wrapping a {@link BiFunction} in an {@link Fn2}. * * @param biFunction the biFunction to adapt * @param the first input argument type @@ -158,7 +137,7 @@ default Fn3 compose(Fn2 be * @param the output type * @return the {@link Fn2} */ - static Fn2 fn2(BiFunction biFunction) { + static Fn2 fromBiFunction(BiFunction biFunction) { return biFunction::apply; } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn3.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn3.java index 84b46a1ae..9003aa0ac 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Fn3.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn3.java @@ -4,9 +4,6 @@ import com.jnape.palatable.lambda.functions.specialized.checked.Runtime; import com.jnape.palatable.lambda.functor.Applicative; -import java.util.function.BiFunction; -import java.util.function.Function; - import static com.jnape.palatable.lambda.functions.Fn4.fn4; import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; @@ -106,20 +103,15 @@ default Fn3 discardR(Applicative> appB) { } @Override - default Fn3 diMapL(Function fn) { + default Fn3 diMapL(Fn1 fn) { return fn3(Fn2.super.diMapL(fn)); } @Override - default Fn3 contraMap(Function fn) { + default Fn3 contraMap(Fn1 fn) { return fn3(Fn2.super.contraMap(fn)); } - @Override - default Fn4 compose(BiFunction before) { - return fn4(Fn2.super.compose(before)); - } - @Override default Fn4 compose(Fn2 before) { return fn4(Fn2.super.compose(before)); diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn4.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn4.java index e38856550..aa49270d5 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Fn4.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn4.java @@ -4,9 +4,6 @@ import com.jnape.palatable.lambda.functions.specialized.checked.Runtime; import com.jnape.palatable.lambda.functor.Applicative; -import java.util.function.BiFunction; -import java.util.function.Function; - import static com.jnape.palatable.lambda.functions.Fn5.fn5; import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; @@ -121,20 +118,15 @@ default Fn4 discardR(Applicative> appB) { } @Override - default Fn4 diMapL(Function fn) { + default Fn4 diMapL(Fn1 fn) { return fn4(Fn3.super.diMapL(fn)); } @Override - default Fn4 contraMap(Function fn) { + default Fn4 contraMap(Fn1 fn) { return fn4(Fn3.super.contraMap(fn)); } - @Override - default Fn5 compose(BiFunction before) { - return fn5(Fn3.super.compose(before)); - } - @Override default Fn5 compose(Fn2 before) { return fn5(Fn3.super.compose(before)); diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn5.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn5.java index 16bc6efa2..b0c0acfba 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Fn5.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn5.java @@ -4,9 +4,6 @@ import com.jnape.palatable.lambda.functions.specialized.checked.Runtime; import com.jnape.palatable.lambda.functor.Applicative; -import java.util.function.BiFunction; -import java.util.function.Function; - import static com.jnape.palatable.lambda.functions.Fn6.fn6; import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; @@ -138,20 +135,15 @@ default Fn5 discardR(Applicative> appB) { } @Override - default Fn5 diMapL(Function fn) { + default Fn5 diMapL(Fn1 fn) { return fn5(Fn4.super.diMapL(fn)); } @Override - default Fn5 contraMap(Function fn) { + default Fn5 contraMap(Fn1 fn) { return fn5(Fn4.super.contraMap(fn)); } - @Override - default Fn6 compose(BiFunction before) { - return fn6(Fn4.super.compose(before)); - } - @Override default Fn6 compose(Fn2 before) { return fn6(Fn4.super.compose(before)); diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn6.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn6.java index 62917ce3a..0f06798c6 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Fn6.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn6.java @@ -4,9 +4,6 @@ import com.jnape.palatable.lambda.functions.specialized.checked.Runtime; import com.jnape.palatable.lambda.functor.Applicative; -import java.util.function.BiFunction; -import java.util.function.Function; - import static com.jnape.palatable.lambda.functions.Fn7.fn7; import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; @@ -155,20 +152,15 @@ default Fn6 discardR(Applicative> appB) { } @Override - default Fn6 diMapL(Function fn) { + default Fn6 diMapL(Fn1 fn) { return fn6(Fn5.super.diMapL(fn)); } @Override - default Fn6 contraMap(Function fn) { + default Fn6 contraMap(Fn1 fn) { return fn6(Fn5.super.contraMap(fn)); } - @Override - default Fn7 compose(BiFunction before) { - return fn7(Fn5.super.compose(before)); - } - @Override default Fn7 compose(Fn2 before) { return fn7(Fn5.super.compose(before)); diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn7.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn7.java index 2e18bef97..70b7ba3f6 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Fn7.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn7.java @@ -4,9 +4,6 @@ import com.jnape.palatable.lambda.functions.specialized.checked.Runtime; import com.jnape.palatable.lambda.functor.Applicative; -import java.util.function.BiFunction; -import java.util.function.Function; - import static com.jnape.palatable.lambda.functions.Fn8.fn8; import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; @@ -172,20 +169,15 @@ default Fn7 discardR(Applicative> appB) } @Override - default Fn7 diMapL(Function fn) { + default Fn7 diMapL(Fn1 fn) { return fn7(Fn6.super.diMapL(fn)); } @Override - default Fn7 contraMap(Function fn) { + default Fn7 contraMap(Fn1 fn) { return fn7(Fn6.super.contraMap(fn)); } - @Override - default Fn8 compose(BiFunction before) { - return fn8(Fn6.super.compose(before)); - } - @Override default Fn8 compose(Fn2 before) { return fn8(Fn6.super.compose(before)); diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn8.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn8.java index 07e8fb165..040fa4346 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Fn8.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn8.java @@ -4,9 +4,6 @@ import com.jnape.palatable.lambda.functions.specialized.checked.Runtime; import com.jnape.palatable.lambda.functor.Applicative; -import java.util.function.BiFunction; -import java.util.function.Function; - /** * A function taking six arguments. Defined in terms of {@link Fn7}, so similarly auto-curried. * @@ -180,21 +177,15 @@ default Fn8 discardR(Applicative> ap } @Override - default Fn8 diMapL(Function fn) { + default Fn8 diMapL(Fn1 fn) { return fn8(Fn7.super.diMapL(fn)); } @Override - default Fn8 contraMap(Function fn) { + default Fn8 contraMap(Fn1 fn) { return fn8(Fn7.super.contraMap(fn)); } - @Override - default Fn8> compose( - BiFunction before) { - return Fn7.super.compose(before); - } - @Override default Fn8> compose(Fn2 before) { return Fn7.super.compose(before); diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Empty.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Empty.java index dca2ebe09..6ea6e6254 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Empty.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Empty.java @@ -25,6 +25,6 @@ public static Empty empty() { } public static Boolean empty(Iterable as) { - return Empty.empty().test(as); + return Empty.empty().apply(as); } } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Inits.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Inits.java index e2b33f928..846762200 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Inits.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Inits.java @@ -26,7 +26,7 @@ private Inits() { @Override public Iterable> checkedApply(Iterable as) { - return scanLeft(Snoc.snoc().flip().toBiFunction(), Collections::emptyIterator, as); + return scanLeft(Snoc.snoc().flip(), Collections::emptyIterator, as); } @SuppressWarnings("unchecked") diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Magnetize.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Magnetize.java index b50429e51..ce2d2e2a3 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Magnetize.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Magnetize.java @@ -19,7 +19,7 @@ private Magnetize() { @Override public Iterable> checkedApply(Iterable as) { - return magnetizeBy(eq().toBiFunction(), as); + return magnetizeBy(eq(), as); } @SuppressWarnings("unchecked") diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Not.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Not.java index 74374b434..e148fadcb 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Not.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Not.java @@ -1,23 +1,22 @@ package com.jnape.palatable.lambda.functions.builtin.fn1; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functions.specialized.BiPredicate; import com.jnape.palatable.lambda.functions.specialized.Predicate; -import java.util.function.Function; - /** * Negate a predicate function. * * @param the input argument type */ -public final class Not implements BiPredicate, A> { +public final class Not implements BiPredicate, A> { private static final Not INSTANCE = new Not<>(); private Not() { } @Override - public Boolean checkedApply(Function pred, A a) { + public Boolean checkedApply(Fn1 pred, A a) { return !pred.apply(a); } @@ -26,11 +25,11 @@ public static Not not() { return (Not) INSTANCE; } - public static Predicate not(Function pred) { + public static Predicate not(Fn1 pred) { return Not.not().apply(pred); } - public static Boolean not(Function pred, A a) { + public static Boolean not(Fn1 pred, A a) { return not(pred).apply(a); } } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/All.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/All.java index 42a97c86f..26d76101f 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/All.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/All.java @@ -3,8 +3,6 @@ import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functions.specialized.BiPredicate; -import java.util.function.Function; - /** * Eagerly apply a predicate to each element in an Iterable, returning true if every element * satisfies the predicate, and false otherwise. This method short-circuits on the first false @@ -13,7 +11,7 @@ * @param The input Iterable element type * @see Any */ -public final class All implements BiPredicate, Iterable> { +public final class All implements BiPredicate, Iterable> { private static final All INSTANCE = new All<>(); @@ -21,7 +19,7 @@ private All() { } @Override - public Boolean checkedApply(Function predicate, Iterable as) { + public Boolean checkedApply(Fn1 predicate, Iterable as) { for (A a : as) if (!predicate.apply(a)) return false; @@ -34,11 +32,11 @@ public static All all() { return (All) INSTANCE; } - public static Fn1, ? extends Boolean> all(Function predicate) { + public static Fn1, ? extends Boolean> all(Fn1 predicate) { return All.all().apply(predicate); } - public static Boolean all(Function predicate, Iterable as) { + public static Boolean all(Fn1 predicate, Iterable as) { return All.all(predicate).apply(as); } } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Any.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Any.java index 048b79cef..524b83159 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Any.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Any.java @@ -1,10 +1,9 @@ package com.jnape.palatable.lambda.functions.builtin.fn2; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functions.specialized.BiPredicate; import com.jnape.palatable.lambda.functions.specialized.Predicate; -import java.util.function.Function; - /** * Eagerly apply a predicate to each element in an Iterable, returning true if any element * satisfies the predicate, and false otherwise. This method short-circuits on the first true @@ -13,7 +12,7 @@ * @param The input Iterable element type * @see All */ -public final class Any implements BiPredicate, Iterable> { +public final class Any implements BiPredicate, Iterable> { private static final Any INSTANCE = new Any<>(); @@ -21,7 +20,7 @@ private Any() { } @Override - public Boolean checkedApply(Function predicate, Iterable as) { + public Boolean checkedApply(Fn1 predicate, Iterable as) { for (A a : as) if (predicate.apply(a)) return true; @@ -34,11 +33,11 @@ public static Any any() { return (Any) INSTANCE; } - public static Predicate> any(Function predicate) { + public static Predicate> any(Fn1 predicate) { return Any.any().apply(predicate); } - public static Boolean any(Function predicate, Iterable as) { + public static Boolean any(Fn1 predicate, Iterable as) { return Any.any(predicate).apply(as); } } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Both.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Both.java index fcd964c7c..0d22f7216 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Both.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Both.java @@ -4,8 +4,6 @@ import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functions.Fn3; -import java.util.function.Function; - /** * Given two functions f and g, produce a * {@link Fn1}<A, {@link Tuple2}<B, C>> (the dual application of both functions). @@ -14,7 +12,8 @@ * @param the first function return type * @param the second function return type */ -public final class Both implements Fn3, Function, A, Tuple2> { +public final class Both implements + Fn3, Fn1, A, Tuple2> { private static final Both INSTANCE = new Both<>(); @@ -22,10 +21,8 @@ private Both() { } @Override - public Tuple2 checkedApply(Function f, - Function g, - A a) { - return Tuple2.fill(a).biMap(f, g); + public Tuple2 checkedApply(Fn1 f, Fn1 g, A a) { + return Tuple2.fill(a).biMap(f::apply, g::apply); } @SuppressWarnings("unchecked") @@ -33,19 +30,15 @@ public static Both both() { return (Both) INSTANCE; } - public static Fn1, Fn1>> both( - Function f) { + public static Fn1, Fn1>> both(Fn1 f) { return Both.both().apply(f); } - public static Fn1> both(Function f, - Function g) { + public static Fn1> both(Fn1 f, Fn1 g) { return Both.both(f).apply(g); } - public static Tuple2 both(Function f, - Function g, - A a) { + public static Tuple2 both(Fn1 f, Fn1 g, A a) { return Both.both(f, g).apply(a); } } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/DropWhile.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/DropWhile.java index 3585ef135..f91d8ba15 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/DropWhile.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/DropWhile.java @@ -4,8 +4,6 @@ import com.jnape.palatable.lambda.functions.Fn2; import com.jnape.palatable.lambda.iteration.PredicatedDroppingIterable; -import java.util.function.Function; - /** * Lazily limit the Iterable by skipping the first contiguous group of elements that satisfy the predicate, * beginning iteration at the first element for which the predicate evaluates to false. @@ -16,7 +14,7 @@ * @see TakeWhile */ -public final class DropWhile implements Fn2, Iterable, Iterable> { +public final class DropWhile implements Fn2, Iterable, Iterable> { private static final DropWhile INSTANCE = new DropWhile<>(); @@ -24,7 +22,7 @@ private DropWhile() { } @Override - public Iterable checkedApply(Function predicate, Iterable as) { + public Iterable checkedApply(Fn1 predicate, Iterable as) { return new PredicatedDroppingIterable<>(predicate, as); } @@ -33,11 +31,11 @@ public static DropWhile dropWhile() { return (DropWhile) INSTANCE; } - public static Fn1, Iterable> dropWhile(Function predicate) { + public static Fn1, Iterable> dropWhile(Fn1 predicate) { return DropWhile.dropWhile().apply(predicate); } - public static Iterable dropWhile(Function predicate, Iterable as) { + public static Iterable dropWhile(Fn1 predicate, Iterable as) { return DropWhile.dropWhile(predicate).apply(as); } } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Filter.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Filter.java index f8954ae8e..2074ec59c 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Filter.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Filter.java @@ -4,8 +4,6 @@ import com.jnape.palatable.lambda.functions.Fn2; import com.jnape.palatable.lambda.iteration.FilteringIterable; -import java.util.function.Function; - /** * Lazily apply a predicate to each element in an Iterable, returning an Iterable of just the * elements for which the predicate evaluated to true. @@ -14,7 +12,7 @@ * @see TakeWhile * @see DropWhile */ -public final class Filter implements Fn2, Iterable, Iterable> { +public final class Filter implements Fn2, Iterable, Iterable> { private static final Filter INSTANCE = new Filter<>(); @@ -22,7 +20,7 @@ private Filter() { } @Override - public Iterable checkedApply(Function predicate, Iterable as) { + public Iterable checkedApply(Fn1 predicate, Iterable as) { return new FilteringIterable<>(predicate, as); } @@ -31,11 +29,11 @@ public static Filter filter() { return (Filter) INSTANCE; } - public static Fn1, Iterable> filter(Function predicate) { + public static Fn1, Iterable> filter(Fn1 predicate) { return Filter.filter().apply(predicate); } - public static Iterable filter(Function predicate, Iterable as) { + public static Iterable filter(Fn1 predicate, Iterable as) { return Filter.filter(predicate).apply(as); } } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Find.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Find.java index 5539d71fc..0bb5c4e6b 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Find.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Find.java @@ -4,8 +4,6 @@ import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functions.Fn2; -import java.util.function.Function; - import static com.jnape.palatable.lambda.functions.builtin.fn1.Head.head; import static com.jnape.palatable.lambda.functions.builtin.fn1.Not.not; import static com.jnape.palatable.lambda.functions.builtin.fn2.DropWhile.dropWhile; @@ -18,7 +16,7 @@ * * @param the Iterable element type */ -public final class Find implements Fn2, Iterable, Maybe> { +public final class Find implements Fn2, Iterable, Maybe> { private static final Find INSTANCE = new Find<>(); @@ -26,7 +24,7 @@ private Find() { } @Override - public Maybe checkedApply(Function predicate, Iterable as) { + public Maybe checkedApply(Fn1 predicate, Iterable as) { return head(dropWhile(not(predicate), as)); } @@ -35,11 +33,11 @@ public static Find find() { return (Find) INSTANCE; } - public static Fn1, Maybe> find(Function predicate) { + public static Fn1, Maybe> find(Fn1 predicate) { return Find.find().apply(predicate); } - public static Maybe find(Function predicate, Iterable as) { + public static Maybe find(Fn1 predicate, Iterable as) { return Find.find(predicate).apply(as); } } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GroupBy.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GroupBy.java index 9cbc91ee8..42e61912a 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GroupBy.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/GroupBy.java @@ -7,7 +7,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.function.Function; import static com.jnape.palatable.lambda.functions.builtin.fn3.FoldLeft.foldLeft; @@ -20,7 +19,7 @@ * @param the Map value type * @see InGroupsOf */ -public final class GroupBy implements Fn2, Iterable, Map>> { +public final class GroupBy implements Fn2, Iterable, Map>> { private static final GroupBy INSTANCE = new GroupBy<>(); @@ -28,7 +27,7 @@ private GroupBy() { } @Override - public Map> checkedApply(Function keyFn, Iterable vs) { + public Map> checkedApply(Fn1 keyFn, Iterable vs) { return foldLeft((m, v) -> { m.computeIfAbsent(keyFn.apply(v), __ -> new ArrayList<>()).add(v); return m; @@ -40,11 +39,11 @@ public static GroupBy groupBy() { return (GroupBy) INSTANCE; } - public static Fn1, Map>> groupBy(Function keyFn) { + public static Fn1, Map>> groupBy(Fn1 keyFn) { return GroupBy.groupBy().apply(keyFn); } - public static Map> groupBy(Function keyFn, Iterable vs) { + public static Map> groupBy(Fn1 keyFn, Iterable vs) { return GroupBy.groupBy(keyFn).apply(vs); } } \ No newline at end of file diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into.java index cd5b061de..523c08543 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into.java @@ -4,17 +4,16 @@ import com.jnape.palatable.lambda.functions.Fn2; import java.util.Map; -import java.util.function.BiFunction; /** - * Given a {@link BiFunction}<A, B, C> and a {@link Map.Entry}<A, B>, destructure - * the entry and apply the key and value as arguments to the function, returning the result. + * Given an {@link Fn2}<A, B, C> and a {@link Map.Entry}<A, B>, destructure the + * entry and apply the key and value as arguments to the function, returning the result. * * @param the first argument type * @param the second argument type * @param the result type */ -public final class Into implements Fn2, Map.Entry, C> { +public final class Into implements Fn2, Map.Entry, C> { private static final Into INSTANCE = new Into<>(); @@ -22,7 +21,7 @@ private Into() { } @Override - public C checkedApply(BiFunction fn, Map.Entry entry) { + public C checkedApply(Fn2 fn, Map.Entry entry) { return fn.apply(entry.getKey(), entry.getValue()); } @@ -32,11 +31,11 @@ public static Into into() { } public static Fn1, C> into( - BiFunction fn) { + Fn2 fn) { return Into.into().apply(fn); } - public static C into(BiFunction fn, + public static C into(Fn2 fn, Map.Entry entry) { return Into.into(fn).apply(entry); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into1.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into1.java index 526fcb7e5..3b574146b 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into1.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into1.java @@ -4,21 +4,19 @@ import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functions.Fn2; -import java.util.function.Function; - /** - * Given a {@link Function}<A, B> and a {@link SingletonHList}<A>, - * pop the head and apply it to the function, returning the result. + * Given an {@link Fn1}<A, B> and a {@link SingletonHList}<A>, pop the head and + * apply it to the function, returning the result. * * @param the first argument type * @param the result type */ -public final class Into1 implements Fn2, SingletonHList, B> { +public final class Into1 implements Fn2, SingletonHList, B> { private static final Into1 INSTANCE = new Into1<>(); @Override - public B checkedApply(Function fn, SingletonHList singletonHList) { + public B checkedApply(Fn1 fn, SingletonHList singletonHList) { return fn.apply(singletonHList.head()); } @@ -27,11 +25,11 @@ public static Into1 into1() { return (Into1) INSTANCE; } - public static Fn1, B> into1(Function fn) { + public static Fn1, B> into1(Fn1 fn) { return Into1.into1().apply(fn); } - public static B into1(Function fn, SingletonHList singletonHList) { + public static B into1(Fn1 fn, SingletonHList singletonHList) { return Into1.into1(fn).apply(singletonHList); } } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into3.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into3.java index 05daec1ef..d58969d57 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into3.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Into3.java @@ -20,7 +20,7 @@ public final class Into3 implements Fn2 fn, Product3 product) { - return product.into(fn); + return product.into(fn); } @SuppressWarnings("unchecked") diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Iterate.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Iterate.java index 17a96235c..19fba6f79 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Iterate.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Iterate.java @@ -3,20 +3,18 @@ import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functions.Fn2; -import java.util.function.Function; - import static com.jnape.palatable.lambda.adt.Maybe.just; import static com.jnape.palatable.lambda.adt.hlist.HList.tuple; import static com.jnape.palatable.lambda.functions.builtin.fn2.Unfoldr.unfoldr; /** - * Lazily generate an infinite Iterable from the successive applications of the function first to the - * initial seed value, then to the result, and so on; i.e., the result of iterate(x -> x + 1, 0) would - * produce an infinite Iterable over the elements 0, 1, 2, 3, ... and so on. + * Lazily generate an infinite {@link Iterable} from the successive applications of the function first to the initial + * seed value, then to the result, and so on; i.e., the result of iterate(x -> x + 1, 0) would produce + * an infinite {@link Iterable} over the elements 0, 1, 2, 3, ... and so on. * * @param The Iterable element type */ -public final class Iterate implements Fn2, A, Iterable> { +public final class Iterate implements Fn2, A, Iterable> { private static final Iterate INSTANCE = new Iterate<>(); @@ -24,7 +22,7 @@ private Iterate() { } @Override - public Iterable checkedApply(Function fn, A seed) { + public Iterable checkedApply(Fn1 fn, A seed) { return unfoldr(a -> just(tuple(a, fn.apply(a))), seed); } @@ -33,11 +31,11 @@ public static Iterate iterate() { return (Iterate) INSTANCE; } - public static Fn1> iterate(Function fn) { + public static Fn1> iterate(Fn1 fn) { return Iterate.iterate().apply(fn); } - public static Iterable iterate(Function fn, A seed) { + public static Iterable iterate(Fn1 fn, A seed) { return Iterate.iterate(fn).apply(seed); } } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LazyRec.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LazyRec.java index fe14186b7..7ebb8fe6f 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LazyRec.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/LazyRec.java @@ -4,16 +4,13 @@ import com.jnape.palatable.lambda.functions.Fn2; import com.jnape.palatable.lambda.functor.builtin.Lazy; -import java.util.function.BiFunction; -import java.util.function.Function; - import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; import static com.jnape.palatable.lambda.monad.Monad.join; /** - * Given a {@link BiFunction} that receives a recursive function and an input and yields a {@link Lazy lazy} result, and - * an input, produce a {@link Lazy lazy} result that, when forced, will recursively invoke the function until it - * terminates in a stack-safe way. + * Given a {@link Fn2} that receives a recursive function and an input and yields a {@link Lazy lazy} result, and an + * input, produce a {@link Lazy lazy} result that, when forced, will recursively invoke the function until it terminates + * in a stack-safe way. *

* Example: *

@@ -29,8 +26,7 @@
  * @param  the input type
  * @param  the output type
  */
-public final class LazyRec implements
-        Fn2>, A, Lazy>, A, Lazy> {
+public final class LazyRec implements Fn2>, A, Lazy>, A, Lazy> {
 
     private static final LazyRec INSTANCE = new LazyRec<>();
 
@@ -38,7 +34,7 @@ private LazyRec() {
     }
 
     @Override
-    public Lazy checkedApply(BiFunction>, A, Lazy> fn, A a) {
+    public Lazy checkedApply(Fn2>, A, Lazy> fn, A a) {
         return join(lazy(() -> fn.apply(nextA -> apply(fn, nextA), a)));
     }
 
@@ -47,11 +43,11 @@ public static  LazyRec lazyRec() {
         return (LazyRec) INSTANCE;
     }
 
-    public static  Fn1> lazyRec(BiFunction>, A, Lazy> fn) {
+    public static  Fn1> lazyRec(Fn2>, A, Lazy> fn) {
         return LazyRec.lazyRec().apply(fn);
     }
 
-    public static  Lazy lazyRec(BiFunction>, A, Lazy> fn, A a) {
+    public static  Lazy lazyRec(Fn2>, A, Lazy> fn, A a) {
         return lazyRec(fn).apply(a);
     }
 }
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/MagnetizeBy.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/MagnetizeBy.java
index 6456f62fb..43697b8a5 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/MagnetizeBy.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/MagnetizeBy.java
@@ -4,7 +4,6 @@
 import com.jnape.palatable.lambda.functions.Fn2;
 
 import java.util.Collections;
-import java.util.function.BiFunction;
 
 import static com.jnape.palatable.lambda.adt.Maybe.just;
 import static com.jnape.palatable.lambda.adt.Maybe.nothing;
@@ -25,7 +24,7 @@
  *
  * @param  the {@link Iterable} element type
  */
-public final class MagnetizeBy implements Fn2, Iterable, Iterable>> {
+public final class MagnetizeBy implements Fn2, Iterable, Iterable>> {
 
     private static final MagnetizeBy INSTANCE = new MagnetizeBy<>();
 
@@ -33,7 +32,7 @@ private MagnetizeBy() {
     }
 
     @Override
-    public Iterable> checkedApply(BiFunction predicate,
+    public Iterable> checkedApply(Fn2 predicate,
                                               Iterable as) {
         return () -> uncons(as).fmap(into((A head, Iterable tail) -> {
             Iterable group = cons(head, unfoldr(into((pivot, ys) -> uncons(ys)
@@ -50,12 +49,12 @@ public static  MagnetizeBy magnetizeBy() {
     }
 
     public static  Fn1, Iterable>> magnetizeBy(
-            BiFunction predicate) {
+            Fn2 predicate) {
         return MagnetizeBy.magnetizeBy().apply(predicate);
     }
 
     public static  Iterable> magnetizeBy(
-            BiFunction predicate,
+            Fn2 predicate,
             Iterable as) {
         return MagnetizeBy.magnetizeBy(predicate).apply(as);
     }
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Map.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Map.java
index 35c771ea1..f5f37332b 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Map.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Map.java
@@ -4,8 +4,6 @@
 import com.jnape.palatable.lambda.functions.Fn2;
 import com.jnape.palatable.lambda.iteration.MappingIterable;
 
-import java.util.function.Function;
-
 /**
  * Lazily apply a function to each element in an Iterable, producing an Iterable of the mapped
  * results.
@@ -13,7 +11,7 @@
  * @param  A type contravariant to the input Iterable element type
  * @param  A type covariant to the output Iterable element type
  */
-public final class Map implements Fn2, Iterable, Iterable> {
+public final class Map implements Fn2, Iterable, Iterable> {
 
     private static final Map INSTANCE = new Map<>();
 
@@ -21,7 +19,7 @@ private Map() {
     }
 
     @Override
-    public Iterable checkedApply(Function fn, Iterable as) {
+    public Iterable checkedApply(Fn1 fn, Iterable as) {
         return new MappingIterable<>(fn, as);
     }
 
@@ -30,11 +28,11 @@ public static  Map map() {
         return (Map) INSTANCE;
     }
 
-    public static  Fn1, Iterable> map(Function fn) {
+    public static  Fn1, Iterable> map(Fn1 fn) {
         return Map.map().apply(fn);
     }
 
-    public static  Iterable map(Function fn, Iterable as) {
+    public static  Iterable map(Fn1 fn, Iterable as) {
         return Map.map(fn).apply(as);
     }
 }
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partial2.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partial2.java
deleted file mode 100644
index 8adb7e847..000000000
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partial2.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.jnape.palatable.lambda.functions.builtin.fn2;
-
-import com.jnape.palatable.lambda.functions.Fn1;
-import com.jnape.palatable.lambda.functions.Fn2;
-
-import java.util.function.BiFunction;
-
-/**
- * Partially apply (fix) the first argument of a {@link BiFunction}, producing an Fn1 that
- * takes the remaining argument. This is isomorphic to calling {@link Fn2#apply(Object)}.
- *
- * @param  The type of the value to be supplied
- * @param  The input argument type of the resulting function
- * @param  The return type of the resulting function
- * @see Partial3
- */
-public final class Partial2 implements Fn2, A, Fn1> {
-
-    private static final Partial2 INSTANCE = new Partial2<>();
-
-    private Partial2() {
-    }
-
-    @Override
-    public Fn1 checkedApply(BiFunction fn, A a) {
-        return b -> fn.apply(a, b);
-    }
-
-    @SuppressWarnings("unchecked")
-    public static  Partial2, A, Fn1> partial2() {
-        return (Partial2, A, Fn1>) INSTANCE;
-    }
-
-    public static  Fn1> partial2(BiFunction fn) {
-        return Partial2.partial2().apply(new Partial2().toBiFunction(), fn);
-    }
-
-    public static  Fn1 partial2(BiFunction fn, A a) {
-        return partial2(fn).apply(a);
-    }
-}
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partial3.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partial3.java
deleted file mode 100644
index 151d8f20f..000000000
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partial3.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.jnape.palatable.lambda.functions.builtin.fn2;
-
-import com.jnape.palatable.lambda.functions.Fn1;
-import com.jnape.palatable.lambda.functions.Fn2;
-import com.jnape.palatable.lambda.functions.Fn3;
-
-/**
- * Partially apply (fix) the first argument of a Fn3, producing a Fn2 that takes the remaining
- * two argument. This is isomorphic to calling {@link Fn3#apply(Object)}.
- *
- * @param  The type of the value to be supplied
- * @param  The first input argument type of the resulting function
- * @param  The second input argument type of the resulting function
- * @param  The return type of the resulting function
- * @see Partial2
- */
-public final class Partial3 implements Fn2, A, Fn2> {
-
-    private static final Partial3 INSTANCE = new Partial3<>();
-
-    private Partial3() {
-    }
-
-    @Override
-    public Fn2 checkedApply(Fn3 fn, A a) {
-        return fn.apply(a);
-    }
-
-    @SuppressWarnings("unchecked")
-    public static  Partial3 partial3() {
-        return (Partial3) INSTANCE;
-    }
-
-    public static  Fn1> partial3(Fn3 fn) {
-        return Partial3.partial3().apply(fn);
-    }
-
-    public static  Fn2 partial3(Fn3 fn, A a) {
-        return partial3(fn).apply(a);
-    }
-}
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partition.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partition.java
index 41acd66b9..20efa316f 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partition.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partition.java
@@ -6,7 +6,6 @@
 import com.jnape.palatable.lambda.functions.Fn2;
 
 import java.util.Collections;
-import java.util.function.Function;
 
 import static com.jnape.palatable.lambda.functions.builtin.fn1.Flatten.flatten;
 import static com.jnape.palatable.lambda.functions.builtin.fn2.Map.map;
@@ -24,7 +23,7 @@
  * @param  The output right Iterable element type, as well as the CoProduct2 B type
  * @see CoProduct2
  */
-public final class Partition implements Fn2>, Iterable, Tuple2, Iterable>> {
+public final class Partition implements Fn2>, Iterable, Tuple2, Iterable>> {
 
     private static final Partition INSTANCE = new Partition<>();
 
@@ -32,7 +31,7 @@ private Partition() {
     }
 
     @Override
-    public Tuple2, Iterable> checkedApply(Function> function,
+    public Tuple2, Iterable> checkedApply(Fn1> function,
                                                          Iterable as) {
         return Tuple2.>>fill(map(function, as))
                 .biMap(Map., Iterable>map(cp -> cp.match(Collections::singleton, __ -> emptySet())),
@@ -46,12 +45,12 @@ public static  Partition partition() {
     }
 
     public static  Fn1, Tuple2, Iterable>> partition(
-            Function> function) {
+            Fn1> function) {
         return Partition.partition().apply(function);
     }
 
     public static  Tuple2, Iterable> partition(
-            Function> function,
+            Fn1> function,
             Iterable as) {
         return Partition.partition(function).apply(as);
     }
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek.java
index c12c45d55..83a33484d 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek.java
@@ -1,20 +1,18 @@
 package com.jnape.palatable.lambda.functions.builtin.fn2;
 
+import com.jnape.palatable.lambda.functions.Effect;
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functions.Fn2;
 import com.jnape.palatable.lambda.functor.Functor;
 
-import java.util.function.Consumer;
-import java.util.function.Function;
-
 /**
- * Given a {@link Consumer}, "peek" at the value contained inside a {@link Functor} via
- * {@link Functor#fmap(Function)}, applying the {@link Consumer} to the contained value, if there is one.
+ * Given an {@link Effect}, "peek" at the value contained inside a {@link Functor} via {@link Functor#fmap(Fn1)},
+ * applying the {@link Effect} to the contained value, if there is one.
  *
  * @param   the functor parameter type
  * @param  the functor type
  */
-public final class Peek> implements Fn2, FA, FA> {
+public final class Peek> implements Fn2, FA, FA> {
     private static final Peek INSTANCE = new Peek<>();
 
     private Peek() {
@@ -22,9 +20,9 @@ private Peek() {
 
     @Override
     @SuppressWarnings("unchecked")
-    public FA checkedApply(Consumer consumer, FA fa) {
+    public FA checkedApply(Effect consumer, FA fa) {
         return (FA) fa.fmap(a -> {
-            consumer.accept(a);
+            consumer.apply(a).unsafePerformIO();
             return a;
         });
     }
@@ -34,11 +32,11 @@ public FA checkedApply(Consumer consumer, FA fa) {
         return (Peek) INSTANCE;
     }
 
-    public static > Fn1 peek(Consumer consumer) {
+    public static > Fn1 peek(Effect consumer) {
         return Peek.peek().apply(consumer);
     }
 
-    public static > FA peek(Consumer consumer, FA fa) {
+    public static > FA peek(Effect consumer, FA fa) {
         return Peek.peek(consumer).apply(fa);
     }
 }
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek2.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek2.java
index f9d63e0b6..7e3d3c465 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek2.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek2.java
@@ -1,24 +1,22 @@
 package com.jnape.palatable.lambda.functions.builtin.fn2;
 
+import com.jnape.palatable.lambda.functions.Effect;
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functions.Fn2;
 import com.jnape.palatable.lambda.functions.Fn3;
 import com.jnape.palatable.lambda.functor.Bifunctor;
 import com.jnape.palatable.lambda.functor.BoundedBifunctor;
 
-import java.util.function.Consumer;
-import java.util.function.Function;
-
 /**
- * Given two {@link Consumer}s, "peek" at the values contained inside a {@link Bifunctor} via
- * {@link Bifunctor#biMap(Function, Function)}, applying the {@link Consumer}s to the contained values,
- * if there are any.
+ * Given two {@link Effect}s, "peek" at the values contained inside a {@link Bifunctor} via
+ * {@link BoundedBifunctor#biMap(Fn1, Fn1)}, applying the {@link Effect}s to the contained values, if there are any.
  *
  * @param    the bifunctor's first parameter type
  * @param    the bifunctor's second parameter type
  * @param  the bifunctor type
  */
-public final class Peek2> implements Fn3, Consumer, FAB, FAB> {
+public final class Peek2> implements
+        Fn3, Effect, FAB, FAB> {
     private static final Peek2 INSTANCE = new Peek2<>();
 
     private Peek2() {
@@ -26,12 +24,12 @@ private Peek2() {
 
     @Override
     @SuppressWarnings("unchecked")
-    public FAB checkedApply(Consumer aConsumer, Consumer bConsumer, FAB fab) {
+    public FAB checkedApply(Effect aConsumer, Effect bConsumer, FAB fab) {
         return (FAB) fab.biMap(a -> {
-            aConsumer.accept(a);
+            aConsumer.apply(a).unsafePerformIO();
             return a;
         }, b -> {
-            bConsumer.accept(b);
+            bConsumer.apply(b).unsafePerformIO();
             return b;
         });
     }
@@ -41,20 +39,20 @@ public FAB checkedApply(Consumer aConsumer, Consumer bCons
         return (Peek2) INSTANCE;
     }
 
-    public static > Fn2, FAB, FAB> peek2(
-            Consumer aConsumer) {
+    public static > Fn2, FAB, FAB>
+    peek2(Effect aConsumer) {
         return Peek2.peek2().apply(aConsumer);
     }
 
     public static > Fn1 peek2(
-            Consumer aConsumer,
-            Consumer bConsumer) {
+            Effect aConsumer,
+            Effect bConsumer) {
         return Peek2.peek2(aConsumer).apply(bConsumer);
     }
 
     public static > FAB peek2(
-            Consumer aConsumer,
-            Consumer bConsumer,
+            Effect aConsumer,
+            Effect bConsumer,
             FAB fab) {
         return Peek2.peek2(aConsumer, bConsumer).apply(fab);
     }
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ReduceLeft.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ReduceLeft.java
index d77872e71..aae71023f 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ReduceLeft.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ReduceLeft.java
@@ -6,14 +6,13 @@
 import com.jnape.palatable.lambda.functions.builtin.fn3.FoldLeft;
 
 import java.util.Iterator;
-import java.util.function.BiFunction;
 
 import static com.jnape.palatable.lambda.adt.Maybe.just;
 import static com.jnape.palatable.lambda.adt.Maybe.nothing;
 import static com.jnape.palatable.lambda.functions.builtin.fn3.FoldLeft.foldLeft;
 
 /**
- * Given an {@link Iterable}<A> and a {@link BiFunction}<A, A, A>, iteratively
+ * Given an {@link Iterable}<A> and a {@link Fn2}<A, A, A>, iteratively
  * accumulate over the {@link Iterable}, returning {@link Maybe}<A>. If the {@link Iterable} is
  * empty, the result is {@link Maybe#nothing()}; otherwise, the result is wrapped in {@link Maybe#just}. For this
  * reason, null accumulation results are considered erroneous and will throw.
@@ -25,7 +24,7 @@
  * @see ReduceRight
  * @see FoldLeft
  */
-public final class ReduceLeft implements Fn2, Iterable, Maybe> {
+public final class ReduceLeft implements Fn2, Iterable, Maybe> {
 
     private static final ReduceLeft INSTANCE = new ReduceLeft<>();
 
@@ -33,7 +32,7 @@ private ReduceLeft() {
     }
 
     @Override
-    public Maybe checkedApply(BiFunction fn, Iterable as) {
+    public Maybe checkedApply(Fn2 fn, Iterable as) {
         Iterator iterator = as.iterator();
         return !iterator.hasNext() ? nothing() : just(foldLeft(fn, iterator.next(), () -> iterator));
     }
@@ -43,11 +42,11 @@ public static  ReduceLeft reduceLeft() {
         return (ReduceLeft) INSTANCE;
     }
 
-    public static  Fn1, Maybe> reduceLeft(BiFunction fn) {
+    public static  Fn1, Maybe> reduceLeft(Fn2 fn) {
         return ReduceLeft.reduceLeft().apply(fn);
     }
 
-    public static  Maybe reduceLeft(BiFunction fn, Iterable as) {
+    public static  Maybe reduceLeft(Fn2 fn, Iterable as) {
         return ReduceLeft.reduceLeft(fn).apply(as);
     }
 }
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ReduceRight.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ReduceRight.java
index 97ed627d5..6d027c594 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ReduceRight.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ReduceRight.java
@@ -5,13 +5,11 @@
 import com.jnape.palatable.lambda.functions.Fn2;
 import com.jnape.palatable.lambda.functions.builtin.fn3.FoldRight;
 
-import java.util.function.BiFunction;
-
 import static com.jnape.palatable.lambda.functions.builtin.fn1.Reverse.reverse;
 import static com.jnape.palatable.lambda.functions.builtin.fn2.ReduceLeft.reduceLeft;
 
 /**
- * Given an {@link Iterable}<A> and a {@link BiFunction}<A, A, A>, iteratively
+ * Given an {@link Iterable}<A> and a {@link Fn2}<A, A, A>, iteratively
  * accumulate over the {@link Iterable}, returning {@link Maybe}<A>. If the {@link Iterable} is
  * empty, the result is {@link Maybe#nothing()}; otherwise, the result is wrapped in {@link Maybe#just}. For this
  * reason, null accumulation results are considered erroneous and will throw.
@@ -23,7 +21,7 @@
  * @see ReduceLeft
  * @see FoldRight
  */
-public final class ReduceRight implements Fn2, Iterable, Maybe> {
+public final class ReduceRight implements Fn2, Iterable, Maybe> {
 
     private static final ReduceRight INSTANCE = new ReduceRight<>();
 
@@ -31,7 +29,7 @@ private ReduceRight() {
     }
 
     @Override
-    public final Maybe checkedApply(BiFunction fn, Iterable as) {
+    public final Maybe checkedApply(Fn2 fn, Iterable as) {
         return reduceLeft((b, a) -> fn.apply(a, b), reverse(as));
     }
 
@@ -40,11 +38,11 @@ public static  ReduceRight reduceRight() {
         return (ReduceRight) INSTANCE;
     }
 
-    public static  Fn1, Maybe> reduceRight(BiFunction fn) {
+    public static  Fn1, Maybe> reduceRight(Fn2 fn) {
         return ReduceRight.reduceRight().apply(fn);
     }
 
-    public static  Maybe reduceRight(BiFunction fn, Iterable as) {
+    public static  Maybe reduceRight(Fn2 fn, Iterable as) {
         return ReduceRight.reduceRight(fn).apply(as);
     }
 }
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Sequence.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Sequence.java
index a00eaff48..2237966c3 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Sequence.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Sequence.java
@@ -8,7 +8,6 @@
 import com.jnape.palatable.lambda.traversable.Traversable;
 
 import java.util.Map;
-import java.util.function.Function;
 
 import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id;
 
@@ -34,7 +33,7 @@ public final class Sequence, Trav extends Tra
         AppA extends Applicative,
         TravA extends Traversable,
         AppTrav extends Applicative,
-        TravApp extends Traversable> implements Fn2, AppTrav> {
+        TravApp extends Traversable> implements Fn2, AppTrav> {
 
     private static final Sequence INSTANCE = new Sequence<>();
 
@@ -42,7 +41,7 @@ private Sequence() {
     }
 
     @Override
-    public AppTrav checkedApply(TravApp traversable, Function pure) {
+    public AppTrav checkedApply(TravApp traversable, Fn1 pure) {
         return traversable.traverse(id(), pure);
     }
 
@@ -59,7 +58,7 @@ TravApp extends Traversable> Sequence,
             TravA extends Traversable,
             AppTrav extends Applicative,
-            TravApp extends Traversable> Fn1, AppTrav> sequence(
+            TravApp extends Traversable> Fn1, AppTrav> sequence(
             TravApp traversable) {
         return Sequence.sequence().apply(traversable);
     }
@@ -69,33 +68,38 @@ TravApp extends Traversable> Sequence,
             AppTrav extends Applicative,
             TravApp extends Traversable> AppTrav sequence(TravApp traversable,
-                                                                      Function pure) {
+                                                                      Fn1 pure) {
         return Sequence.sequence(traversable).apply(pure);
     }
 
     @SuppressWarnings({"unchecked", "RedundantTypeArguments"})
-    public static , AppA extends Applicative, AppIterable extends Applicative, App>, IterableApp extends Iterable>
-    Fn1, ? extends AppIterable>, AppIterable> sequence(IterableApp iterableApp) {
+    public static , AppA extends Applicative,
+            AppIterable extends Applicative, App>,
+            IterableApp extends Iterable>
+    Fn1, ? extends AppIterable>, AppIterable> sequence(IterableApp iterableApp) {
         return pure -> (AppIterable) Sequence., LambdaIterable, AppA, Applicative, App>, LambdaIterable>sequence(
                 LambdaIterable.wrap(iterableApp), x -> pure.apply(x.unwrap()).fmap(LambdaIterable::wrap))
                 .fmap(LambdaIterable::unwrap);
     }
 
-    public static , AppA extends Applicative, AppIterable extends Applicative, App>, IterableApp extends Iterable>
-    AppIterable sequence(IterableApp iterableApp, Function, ? extends AppIterable> pure) {
+    public static , AppA extends Applicative,
+            AppIterable extends Applicative, App>, IterableApp extends Iterable>
+    AppIterable sequence(IterableApp iterableApp, Fn1, ? extends AppIterable> pure) {
         return Sequence.sequence(iterableApp).apply(pure);
     }
 
     @SuppressWarnings({"unchecked", "RedundantTypeArguments"})
-    public static , AppB extends Applicative, AppMap extends Applicative, App>, MapApp extends Map>
-    Fn1, ? extends AppMap>, AppMap> sequence(MapApp mapApp) {
+    public static , AppB extends Applicative,
+            AppMap extends Applicative, App>, MapApp extends Map>
+    Fn1, ? extends AppMap>, AppMap> sequence(MapApp mapApp) {
         return pure -> (AppMap) Sequence., LambdaMap, AppB, Applicative, App>, LambdaMap>sequence(
                 LambdaMap.wrap(mapApp), x -> pure.apply(x.unwrap()).fmap(LambdaMap::wrap))
                 .fmap(LambdaMap::unwrap);
     }
 
-    public static , AppB extends Applicative, AppMap extends Applicative, App>, MapApp extends Map>
-    AppMap sequence(MapApp mapApp, Function, ? extends AppMap> pure) {
+    public static , AppB extends Applicative,
+            AppMap extends Applicative, App>, MapApp extends Map>
+    AppMap sequence(MapApp mapApp, Fn1, ? extends AppMap> pure) {
         return Sequence.sequence(mapApp).apply(pure);
     }
 }
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/SortBy.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/SortBy.java
index de3d55858..13ea9d0df 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/SortBy.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/SortBy.java
@@ -5,7 +5,6 @@
 import com.jnape.palatable.lambda.functions.builtin.fn1.Sort;
 
 import java.util.List;
-import java.util.function.Function;
 
 import static com.jnape.palatable.lambda.functions.builtin.fn2.SortWith.sortWith;
 import static java.util.Comparator.comparing;
@@ -20,7 +19,7 @@
  * @see Sort
  * @see SortWith
  */
-public final class SortBy> implements Fn2, Iterable, List> {
+public final class SortBy> implements Fn2, Iterable, List> {
 
     private static final SortBy INSTANCE = new SortBy<>();
 
@@ -28,8 +27,8 @@ private SortBy() {
     }
 
     @Override
-    public List checkedApply(Function fn, Iterable as) {
-        return sortWith(comparing(fn), as);
+    public List checkedApply(Fn1 fn, Iterable as) {
+        return sortWith(comparing(fn.toFunction()), as);
     }
 
     @SuppressWarnings("unchecked")
@@ -37,12 +36,11 @@ public static > SortBy sortBy() {
         return (SortBy) INSTANCE;
     }
 
-    public static > Fn1, List> sortBy(
-            Function fn) {
+    public static > Fn1, List> sortBy(Fn1 fn) {
         return SortBy.sortBy().apply(fn);
     }
 
-    public static > List sortBy(Function fn, Iterable as) {
+    public static > List sortBy(Fn1 fn, Iterable as) {
         return SortBy.sortBy(fn).apply(as);
     }
 }
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Span.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Span.java
index d74702b35..966b6518d 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Span.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Span.java
@@ -4,8 +4,6 @@
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functions.Fn2;
 
-import java.util.function.Function;
-
 import static com.jnape.palatable.lambda.functions.builtin.fn2.DropWhile.dropWhile;
 import static com.jnape.palatable.lambda.functions.builtin.fn2.TakeWhile.takeWhile;
 
@@ -15,7 +13,8 @@
  *
  * @param  the {@link Iterable} element type
  */
-public final class Span implements Fn2, Iterable, Tuple2, Iterable>> {
+public final class Span implements
+        Fn2, Iterable, Tuple2, Iterable>> {
 
     private static final Span INSTANCE = new Span<>();
 
@@ -23,8 +22,7 @@ private Span() {
     }
 
     @Override
-    public Tuple2, Iterable> checkedApply(Function predicate,
-                                                         Iterable as) {
+    public Tuple2, Iterable> checkedApply(Fn1 predicate, Iterable as) {
         return Tuple2.fill(as).biMap(takeWhile(predicate), dropWhile(predicate));
     }
 
@@ -34,11 +32,11 @@ public static  Span span() {
     }
 
     public static  Fn1, Tuple2, Iterable>> span(
-            Function predicate) {
+            Fn1 predicate) {
         return Span.span().apply(predicate);
     }
 
-    public static  Tuple2, Iterable> span(Function predicate,
+    public static  Tuple2, Iterable> span(Fn1 predicate,
                                                             Iterable as) {
         return Span.span(predicate).apply(as);
     }
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/TakeWhile.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/TakeWhile.java
index 098cd6a17..d0d051dce 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/TakeWhile.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/TakeWhile.java
@@ -4,8 +4,6 @@
 import com.jnape.palatable.lambda.functions.Fn2;
 import com.jnape.palatable.lambda.iteration.PredicatedTakingIterable;
 
-import java.util.function.Function;
-
 /**
  * Lazily limit the Iterable to the first group of contiguous elements that satisfy the predicate by
  * iterating up to, but not including, the first element for which the predicate evaluates to false.
@@ -15,7 +13,7 @@
  * @see Filter
  * @see DropWhile
  */
-public final class TakeWhile implements Fn2, Iterable, Iterable> {
+public final class TakeWhile implements Fn2, Iterable, Iterable> {
 
     private static final TakeWhile INSTANCE = new TakeWhile<>();
 
@@ -23,7 +21,7 @@ private TakeWhile() {
     }
 
     @Override
-    public Iterable checkedApply(Function predicate, Iterable as) {
+    public Iterable checkedApply(Fn1 predicate, Iterable as) {
         return new PredicatedTakingIterable<>(predicate, as);
     }
 
@@ -32,11 +30,11 @@ public static  TakeWhile takeWhile() {
         return (TakeWhile) INSTANCE;
     }
 
-    public static  Fn1, Iterable> takeWhile(Function predicate) {
+    public static  Fn1, Iterable> takeWhile(Fn1 predicate) {
         return TakeWhile.takeWhile().apply(predicate);
     }
 
-    public static  Iterable takeWhile(Function predicate, Iterable as) {
+    public static  Iterable takeWhile(Fn1 predicate, Iterable as) {
         return TakeWhile.takeWhile(predicate).apply(as);
     }
 }
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToCollection.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToCollection.java
index 3e2fb05e1..535d90e0a 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToCollection.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToCollection.java
@@ -1,20 +1,20 @@
 package com.jnape.palatable.lambda.functions.builtin.fn2;
 
+import com.jnape.palatable.lambda.functions.Fn0;
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functions.Fn2;
 
 import java.util.Collection;
-import java.util.function.Supplier;
 
 /**
- * Given a {@link Supplier} of some {@link Collection} C, create an instance of C and add
- * all of the elements in the provided Iterable to the instance. Note that instances of C
- * must support {@link Collection#add} (which is to say, must not throw on invocation).
+ * Given an {@link Fn0} of some {@link Collection} C, create an instance of C and add all of
+ * the elements in the provided Iterable to the instance. Note that instances of C must
+ * support {@link Collection#add} (which is to say, must not throw on invocation).
  *
  * @param  the iterable element type
  * @param  the resulting collection type
  */
-public final class ToCollection> implements Fn2, Iterable, C> {
+public final class ToCollection> implements Fn2, Iterable, C> {
 
     private static final ToCollection INSTANCE = new ToCollection<>();
 
@@ -22,8 +22,8 @@ private ToCollection() {
     }
 
     @Override
-    public C checkedApply(Supplier cSupplier, Iterable as) {
-        C c = cSupplier.get();
+    public C checkedApply(Fn0 cFn0, Iterable as) {
+        C c = cFn0.apply();
         as.forEach(c::add);
         return c;
     }
@@ -33,11 +33,11 @@ public static > ToCollection toCollection() {
         return (ToCollection) INSTANCE;
     }
 
-    public static > Fn1, C> toCollection(Supplier cSupplier) {
-        return ToCollection.toCollection().apply(cSupplier);
+    public static > Fn1, C> toCollection(Fn0 cFn0) {
+        return ToCollection.toCollection().apply(cFn0);
     }
 
-    public static > C toCollection(Supplier cSupplier, Iterable as) {
-        return toCollection(cSupplier).apply(as);
+    public static > C toCollection(Fn0 cFn0, Iterable as) {
+        return toCollection(cFn0).apply(as);
     }
 }
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToMap.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToMap.java
index e674673fb..85dad9e41 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToMap.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToMap.java
@@ -1,23 +1,23 @@
 package com.jnape.palatable.lambda.functions.builtin.fn2;
 
+import com.jnape.palatable.lambda.functions.Fn0;
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functions.Fn2;
 
 import java.util.Map;
-import java.util.function.Supplier;
 
 import static com.jnape.palatable.lambda.functions.builtin.fn3.FoldLeft.foldLeft;
 
 /**
- * Given a {@link Supplier} of some {@link Map} M, create an instance of M and put
- * all of the entries in the provided Iterable into the instance. Note that instances of M
- * must support {@link java.util.Map#put} (which is to say, must not throw on invocation).
+ * Given an {@link Fn0} of some {@link Map} M, create an instance of M and put all of the
+ * entries in the provided Iterable into the instance. Note that instances of M must support
+ * {@link java.util.Map#put} (which is to say, must not throw on invocation).
  *
  * @param  the key element type
  * @param  the value element type
  * @param  the resulting map type
  */
-public final class ToMap> implements Fn2, Iterable>, M> {
+public final class ToMap> implements Fn2, Iterable>, M> {
 
     private static final ToMap INSTANCE = new ToMap<>();
 
@@ -25,11 +25,11 @@ private ToMap() {
     }
 
     @Override
-    public M checkedApply(Supplier mSupplier, Iterable> entries) {
+    public M checkedApply(Fn0 mFn0, Iterable> entries) {
         return foldLeft((m, kv) -> {
             m.put(kv.getKey(), kv.getValue());
             return m;
-        }, mSupplier.get(), entries);
+        }, mFn0.apply(), entries);
     }
 
     @SuppressWarnings("unchecked")
@@ -37,12 +37,12 @@ public static > ToMap toMap() {
         return (ToMap) INSTANCE;
     }
 
-    public static > Fn1>, M> toMap(Supplier mSupplier) {
-        return ToMap.toMap().apply(mSupplier);
+    public static > Fn1>, M> toMap(Fn0 mFn0) {
+        return ToMap.toMap().apply(mFn0);
     }
 
-    public static > M toMap(Supplier mSupplier,
+    public static > M toMap(Fn0 mFn0,
                                                       Iterable> entries) {
-        return toMap(mSupplier).apply(entries);
+        return toMap(mFn0).apply(entries);
     }
 }
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Unfoldr.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Unfoldr.java
index e0c63eeb2..aa451768b 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Unfoldr.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Unfoldr.java
@@ -6,8 +6,6 @@
 import com.jnape.palatable.lambda.functions.Fn2;
 import com.jnape.palatable.lambda.iteration.UnfoldingIterator;
 
-import java.util.function.Function;
-
 /**
  * Given an initial seed value and a function that takes the seed type and produces an {@link Maybe}<{@link
  * Tuple2}<X, Seed>>, where the tuple's first slot represents the next Iterable element,
@@ -29,7 +27,7 @@
  * @param  The output Iterable element type
  * @param  The unfolding function input type
  */
-public final class Unfoldr implements Fn2>>, B, Iterable> {
+public final class Unfoldr implements Fn2>>, B, Iterable> {
 
     private static final Unfoldr INSTANCE = new Unfoldr<>();
 
@@ -37,7 +35,7 @@ private Unfoldr() {
     }
 
     @Override
-    public Iterable checkedApply(Function>> fn, B b) {
+    public Iterable checkedApply(Fn1>> fn, B b) {
         return () -> new UnfoldingIterator<>(fn, b);
     }
 
@@ -46,11 +44,11 @@ public static  Unfoldr unfoldr() {
         return (Unfoldr) INSTANCE;
     }
 
-    public static  Fn1> unfoldr(Function>> fn) {
+    public static  Fn1> unfoldr(Fn1>> fn) {
         return Unfoldr.unfoldr().apply(fn);
     }
 
-    public static  Iterable unfoldr(Function>> fn, B b) {
+    public static  Iterable unfoldr(Fn1>> fn, B b) {
         return unfoldr(fn).apply(b);
     }
 }
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Zip.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Zip.java
index 8f896e14c..ff41594b1 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Zip.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Zip.java
@@ -4,6 +4,7 @@
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functions.Fn2;
 
+import static com.jnape.palatable.lambda.functions.builtin.fn2.Tupler2.tupler;
 import static com.jnape.palatable.lambda.functions.builtin.fn3.ZipWith.zipWith;
 
 /**
@@ -24,7 +25,7 @@ private Zip() {
 
     @Override
     public Iterable> checkedApply(Iterable as, Iterable bs) {
-        return zipWith(Tupler2.tupler().toBiFunction(), as, bs);
+        return zipWith(tupler(), as, bs);
     }
 
     @SuppressWarnings("unchecked")
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/CmpEqBy.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/CmpEqBy.java
index db202c66a..3b483aeaf 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/CmpEqBy.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/CmpEqBy.java
@@ -1,11 +1,12 @@
 package com.jnape.palatable.lambda.functions.builtin.fn3;
 
+import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functions.Fn3;
 import com.jnape.palatable.lambda.functions.builtin.fn2.CmpEq;
 import com.jnape.palatable.lambda.functions.specialized.BiPredicate;
 import com.jnape.palatable.lambda.functions.specialized.Predicate;
 
-import java.util.function.Function;
+import static com.jnape.palatable.lambda.functions.specialized.Predicate.predicate;
 
 /**
  * Given a mapping function from some type A to some {@link Comparable} type B and two values
@@ -18,7 +19,7 @@
  * @see LTBy
  * @see GTBy
  */
-public final class CmpEqBy> implements Fn3, A, A, Boolean> {
+public final class CmpEqBy> implements Fn3, A, A, Boolean> {
 
     private static final CmpEqBy INSTANCE = new CmpEqBy<>();
 
@@ -26,18 +27,18 @@ private CmpEqBy() {
     }
 
     @Override
-    public Boolean checkedApply(Function compareFn, A x, A y) {
+    public Boolean checkedApply(Fn1 compareFn, A x, A y) {
         return compareFn.apply(x).compareTo(compareFn.apply(y)) == 0;
     }
 
     @Override
-    public BiPredicate apply(Function compareFn) {
+    public BiPredicate apply(Fn1 compareFn) {
         return Fn3.super.apply(compareFn)::apply;
     }
 
     @Override
-    public Predicate apply(Function compareFn, A x) {
-        return Fn3.super.apply(compareFn, x)::apply;
+    public Predicate apply(Fn1 compareFn, A x) {
+        return predicate(Fn3.super.apply(compareFn, x));
     }
 
     @SuppressWarnings("unchecked")
@@ -45,15 +46,15 @@ public static > CmpEqBy cmpEqBy() {
         return (CmpEqBy) INSTANCE;
     }
 
-    public static > BiPredicate cmpEqBy(Function compareFn) {
+    public static > BiPredicate cmpEqBy(Fn1 compareFn) {
         return CmpEqBy.cmpEqBy().apply(compareFn);
     }
 
-    public static > Predicate cmpEqBy(Function compareFn, A x) {
+    public static > Predicate cmpEqBy(Fn1 compareFn, A x) {
         return CmpEqBy.cmpEqBy(compareFn).apply(x);
     }
 
-    public static > Boolean cmpEqBy(Function compareFn, A x, A y) {
+    public static > Boolean cmpEqBy(Fn1 compareFn, A x, A y) {
         return cmpEqBy(compareFn, x).apply(y);
     }
 }
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/FoldLeft.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/FoldLeft.java
index d7f9a24e6..e05b1bcf0 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/FoldLeft.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/FoldLeft.java
@@ -4,12 +4,10 @@
 import com.jnape.palatable.lambda.functions.Fn2;
 import com.jnape.palatable.lambda.functions.Fn3;
 
-import java.util.function.BiFunction;
-
 /**
- * Given an Iterable of As, a starting value B, and a {@link
- * BiFunction}<B, A, B>, iteratively accumulate over the Iterable, ultimately returning a
- * final B value. If the Iterable is empty, just return the starting B value.
+ * Given an Iterable of As, a starting value B, and a
+ * {@link Fn2}<B, A, B>, iteratively accumulate over the Iterable, ultimately returning
+ * a final B value. If the Iterable is empty, just return the starting B value.
  * Note that, as the name implies, this function accumulates from left to right, such that foldLeft(f, 0,
  * asList(1, 2, 3, 4, 5)) is evaluated as f(f(f(f(f(0, 1), 2), 3), 4), 5).
  * 

@@ -20,15 +18,15 @@ * @param The accumulation type * @see FoldRight */ -public final class FoldLeft implements Fn3, B, Iterable, B> { +public final class FoldLeft implements Fn3, B, Iterable, B> { - private static final FoldLeft INSTANCE = new FoldLeft<>(); + private static final FoldLeft INSTANCE = new FoldLeft<>(); private FoldLeft() { } @Override - public B checkedApply(BiFunction fn, B acc, Iterable as) { + public B checkedApply(Fn2 fn, B acc, Iterable as) { B accumulation = acc; for (A a : as) accumulation = fn.apply(accumulation, a); @@ -40,15 +38,15 @@ public static FoldLeft foldLeft() { return (FoldLeft) INSTANCE; } - public static Fn2, B> foldLeft(BiFunction fn) { + public static Fn2, B> foldLeft(Fn2 fn) { return FoldLeft.foldLeft().apply(fn); } - public static Fn1, B> foldLeft(BiFunction fn, B acc) { + public static Fn1, B> foldLeft(Fn2 fn, B acc) { return FoldLeft.foldLeft(fn).apply(acc); } - public static B foldLeft(BiFunction fn, B acc, Iterable as) { + public static B foldLeft(Fn2 fn, B acc, Iterable as) { return FoldLeft.foldLeft(fn, acc).apply(as); } } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/FoldRight.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/FoldRight.java index 4086204ed..21116dd84 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/FoldRight.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/FoldRight.java @@ -5,18 +5,16 @@ import com.jnape.palatable.lambda.functions.Fn3; import com.jnape.palatable.lambda.functor.builtin.Lazy; -import java.util.function.BiFunction; - import static com.jnape.palatable.lambda.functions.builtin.fn2.LazyRec.lazyRec; import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; /** * Given an Iterable of As, a starting {@link Lazy lazy} value B, and a - * {@link BiFunction}<A, {@link Lazy}<B>, {@link Lazy}<B>>, iteratively accumulate over - * the Iterable, ultimately returning a final {@link Lazy}<B> value. If the - * Iterable is empty, just return the starting {@link Lazy}<B> value. - * This function is computationally the iterative inverse of {@link FoldLeft}, but uses {@link Lazy} to allow support - * stack-safe execution. + * {@link Fn2}<A, {@link Lazy}<B>, {@link Lazy}<B>>, iteratively accumulate over the + * Iterable, ultimately returning a final {@link Lazy}<B> value. If the + * Iterable is empty, just return the starting {@link Lazy}<B> value. This function is + * computationally the iterative inverse of {@link FoldLeft}, but uses {@link Lazy} to allow support stack-safe + * execution. *

* Example: *

@@ -39,7 +37,7 @@
  * @see FoldLeft
  */
 public final class FoldRight implements
-        Fn3, ? extends Lazy>, Lazy, Iterable, Lazy> {
+        Fn3, ? extends Lazy>, Lazy, Iterable, Lazy> {
 
     private static final FoldRight INSTANCE = new FoldRight<>();
 
@@ -47,7 +45,7 @@ private FoldRight() {
     }
 
     @Override
-    public Lazy checkedApply(BiFunction, ? extends Lazy> fn, Lazy acc,
+    public Lazy checkedApply(Fn2, ? extends Lazy> fn, Lazy acc,
                                 Iterable as) {
         return lazyRec((f, lazyIt) -> lazyIt.flatMap(it -> it.hasNext()
                                                            ? fn.apply(it.next(), f.apply(lazy(it)))
@@ -61,17 +59,17 @@ public static  FoldRight foldRight() {
     }
 
     public static  Fn2, Iterable, Lazy> foldRight(
-            BiFunction, ? extends Lazy> fn) {
+            Fn2, ? extends Lazy> fn) {
         return FoldRight.foldRight().apply(fn);
     }
 
     public static  Fn1, Lazy> foldRight(
-            BiFunction, ? extends Lazy> fn,
+            Fn2, ? extends Lazy> fn,
             Lazy acc) {
         return FoldRight.foldRight(fn).apply(acc);
     }
 
-    public static  Lazy foldRight(BiFunction, ? extends Lazy> fn, Lazy acc,
+    public static  Lazy foldRight(Fn2, ? extends Lazy> fn, Lazy acc,
                                            Iterable as) {
         return FoldRight.foldRight(fn, acc).apply(as);
     }
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/GTBy.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/GTBy.java
index 0a6bf807d..cb9b45168 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/GTBy.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/GTBy.java
@@ -1,11 +1,12 @@
 package com.jnape.palatable.lambda.functions.builtin.fn3;
 
+import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functions.Fn3;
 import com.jnape.palatable.lambda.functions.builtin.fn2.GT;
 import com.jnape.palatable.lambda.functions.specialized.BiPredicate;
 import com.jnape.palatable.lambda.functions.specialized.Predicate;
 
-import java.util.function.Function;
+import static com.jnape.palatable.lambda.functions.specialized.Predicate.predicate;
 
 /**
  * Given a mapping function from some type A to some {@link Comparable} type B and two values
@@ -17,7 +18,7 @@
  * @see GT
  * @see LTBy
  */
-public final class GTBy> implements Fn3, A, A, Boolean> {
+public final class GTBy> implements Fn3, A, A, Boolean> {
 
     private static final GTBy INSTANCE = new GTBy<>();
 
@@ -25,18 +26,18 @@ private GTBy() {
     }
 
     @Override
-    public Boolean checkedApply(Function compareFn, A y, A x) {
+    public Boolean checkedApply(Fn1 compareFn, A y, A x) {
         return compareFn.apply(x).compareTo(compareFn.apply(y)) > 0;
     }
 
     @Override
-    public BiPredicate apply(Function compareFn) {
+    public BiPredicate apply(Fn1 compareFn) {
         return Fn3.super.apply(compareFn)::apply;
     }
 
     @Override
-    public Predicate apply(Function compareFn, A x) {
-        return Fn3.super.apply(compareFn, x)::apply;
+    public Predicate apply(Fn1 compareFn, A x) {
+        return predicate(Fn3.super.apply(compareFn, x));
     }
 
     @SuppressWarnings("unchecked")
@@ -44,15 +45,15 @@ public static > GTBy gtBy() {
         return (GTBy) INSTANCE;
     }
 
-    public static > BiPredicate gtBy(Function fn) {
+    public static > BiPredicate gtBy(Fn1 fn) {
         return GTBy.gtBy().apply(fn);
     }
 
-    public static > Predicate gtBy(Function fn, A y) {
+    public static > Predicate gtBy(Fn1 fn, A y) {
         return GTBy.gtBy(fn).apply(y);
     }
 
-    public static > Boolean gtBy(Function fn, A y, A x) {
+    public static > Boolean gtBy(Fn1 fn, A y, A x) {
         return gtBy(fn, y).apply(x);
     }
 }
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/GTEBy.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/GTEBy.java
index 6c956e366..30ef09852 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/GTEBy.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/GTEBy.java
@@ -1,13 +1,13 @@
 package com.jnape.palatable.lambda.functions.builtin.fn3;
 
+import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functions.Fn3;
 import com.jnape.palatable.lambda.functions.builtin.fn2.GTE;
 import com.jnape.palatable.lambda.functions.specialized.BiPredicate;
 import com.jnape.palatable.lambda.functions.specialized.Predicate;
 
-import java.util.function.Function;
-
 import static com.jnape.palatable.lambda.functions.builtin.fn3.CmpEqBy.cmpEqBy;
+import static com.jnape.palatable.lambda.functions.specialized.Predicate.predicate;
 
 /**
  * Given a mapping function from some type A to some {@link Comparable} type B and two values
@@ -20,7 +20,7 @@
  * @see GTE
  * @see LTEBy
  */
-public final class GTEBy> implements Fn3, A, A, Boolean> {
+public final class GTEBy> implements Fn3, A, A, Boolean> {
 
     private static final GTEBy INSTANCE = new GTEBy<>();
 
@@ -28,18 +28,18 @@ private GTEBy() {
     }
 
     @Override
-    public Boolean checkedApply(Function compareFn, A y, A x) {
+    public Boolean checkedApply(Fn1 compareFn, A y, A x) {
         return GTBy.gtBy(compareFn).or(cmpEqBy(compareFn)).apply(y, x);
     }
 
     @Override
-    public BiPredicate apply(Function compareFn) {
+    public BiPredicate apply(Fn1 compareFn) {
         return Fn3.super.apply(compareFn)::apply;
     }
 
     @Override
-    public Predicate apply(Function compareFn, A y) {
-        return Fn3.super.apply(compareFn, y)::apply;
+    public Predicate apply(Fn1 compareFn, A y) {
+        return predicate(Fn3.super.apply(compareFn, y));
     }
 
     @SuppressWarnings("unchecked")
@@ -47,15 +47,15 @@ public static > GTEBy gteBy() {
         return (GTEBy) INSTANCE;
     }
 
-    public static > BiPredicate gteBy(Function fn) {
+    public static > BiPredicate gteBy(Fn1 fn) {
         return GTEBy.gteBy().apply(fn);
     }
 
-    public static > Predicate gteBy(Function fn, A y) {
+    public static > Predicate gteBy(Fn1 fn, A y) {
         return GTEBy.gteBy(fn).apply(y);
     }
 
-    public static > Boolean gteBy(Function fn, A y, A x) {
+    public static > Boolean gteBy(Fn1 fn, A y, A x) {
         return gteBy(fn, y).apply(x);
     }
 }
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LTBy.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LTBy.java
index be547f38b..c442d9871 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LTBy.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LTBy.java
@@ -1,11 +1,12 @@
 package com.jnape.palatable.lambda.functions.builtin.fn3;
 
+import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functions.Fn3;
 import com.jnape.palatable.lambda.functions.builtin.fn2.LT;
 import com.jnape.palatable.lambda.functions.specialized.BiPredicate;
 import com.jnape.palatable.lambda.functions.specialized.Predicate;
 
-import java.util.function.Function;
+import static com.jnape.palatable.lambda.functions.specialized.Predicate.predicate;
 
 /**
  * Given a mapping function from some type A to some {@link Comparable} type B and two values
@@ -17,26 +18,26 @@
  * @see LT
  * @see GTBy
  */
-public final class LTBy> implements Fn3, A, A, Boolean> {
+public final class LTBy> implements Fn3, A, A, Boolean> {
 
-    private static final LTBy INSTANCE = new LTBy<>();
+    private static final LTBy INSTANCE = new LTBy<>();
 
     private LTBy() {
     }
 
     @Override
-    public Boolean checkedApply(Function compareFn, A y, A x) {
+    public Boolean checkedApply(Fn1 compareFn, A y, A x) {
         return compareFn.apply(x).compareTo(compareFn.apply(y)) < 0;
     }
 
     @Override
-    public BiPredicate apply(Function compareFn) {
+    public BiPredicate apply(Fn1 compareFn) {
         return Fn3.super.apply(compareFn)::apply;
     }
 
     @Override
-    public Predicate apply(Function compareFn, A y) {
-        return Fn3.super.apply(compareFn, y)::apply;
+    public Predicate apply(Fn1 compareFn, A y) {
+        return predicate(Fn3.super.apply(compareFn, y));
     }
 
     @SuppressWarnings("unchecked")
@@ -44,15 +45,15 @@ public static > LTBy ltBy() {
         return (LTBy) INSTANCE;
     }
 
-    public static > BiPredicate ltBy(Function fn) {
+    public static > BiPredicate ltBy(Fn1 fn) {
         return LTBy.ltBy().apply(fn);
     }
 
-    public static > Predicate ltBy(Function fn, A y) {
+    public static > Predicate ltBy(Fn1 fn, A y) {
         return LTBy.ltBy(fn).apply(y);
     }
 
-    public static > Boolean ltBy(Function fn, A y, A x) {
+    public static > Boolean ltBy(Fn1 fn, A y, A x) {
         return ltBy(fn, y).apply(x);
     }
 }
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 2dda81ce4..bc755470d 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
@@ -1,12 +1,11 @@
 package com.jnape.palatable.lambda.functions.builtin.fn3;
 
+import com.jnape.palatable.lambda.functions.Fn1;
 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.function.Function;
-
 import static com.jnape.palatable.lambda.functions.builtin.fn3.CmpEqBy.cmpEqBy;
 
 /**
@@ -20,25 +19,25 @@
  * @see LTE
  * @see GTEBy
  */
-public final class LTEBy> implements Fn3, A, A, Boolean> {
+public final class LTEBy> implements Fn3, A, A, Boolean> {
 
-    private static final LTEBy INSTANCE = new LTEBy<>();
+    private static final LTEBy INSTANCE = new LTEBy<>();
 
     private LTEBy() {
     }
 
     @Override
-    public Boolean checkedApply(Function compareFn, A y, A x) {
+    public Boolean checkedApply(Fn1 compareFn, A y, A x) {
         return LTBy.ltBy(compareFn).or(cmpEqBy(compareFn)).apply(y, x);
     }
 
     @Override
-    public BiPredicate apply(Function compareFn) {
+    public BiPredicate apply(Fn1 compareFn) {
         return Fn3.super.apply(compareFn)::apply;
     }
 
     @Override
-    public Predicate apply(Function compareFn, A y) {
+    public Predicate apply(Fn1 compareFn, A y) {
         return Fn3.super.apply(compareFn, y)::apply;
     }
 
@@ -47,15 +46,15 @@ public static > LTEBy lteBy() {
         return (LTEBy) INSTANCE;
     }
 
-    public static > BiPredicate lteBy(Function fn) {
+    public static > BiPredicate lteBy(Fn1 fn) {
         return LTEBy.lteBy().apply(fn);
     }
 
-    public static > Predicate lteBy(Function fn, A y) {
+    public static > Predicate lteBy(Fn1 fn, A y) {
         return LTEBy.lteBy(fn).apply(y);
     }
 
-    public static > Boolean lteBy(Function fn, A y, A x) {
+    public static > Boolean lteBy(Fn1 fn, A y, A x) {
         return lteBy(fn, y).apply(x);
     }
 }
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LiftA2.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LiftA2.java
index fbfc78c06..e83048652 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LiftA2.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/LiftA2.java
@@ -5,10 +5,8 @@
 import com.jnape.palatable.lambda.functions.Fn3;
 import com.jnape.palatable.lambda.functor.Applicative;
 
-import java.util.function.BiFunction;
-
 /**
- * Lift into and apply a {@link BiFunction} to two {@link Applicative} values, returning the result inside the same
+ * Lift into and apply an {@link Fn2} to two {@link Applicative} values, returning the result inside the same
  * {@link Applicative} context. Functionally equivalent to appB.zip(appA.fmap(fn)).
  *
  * @param     the function's first argument type
@@ -24,7 +22,7 @@ public final class LiftA2,
         AppA extends Applicative,
         AppB extends Applicative,
         AppC extends Applicative> implements
-        Fn3, AppA, AppB, AppC> {
+        Fn3, AppA, AppB, AppC> {
 
     private static final LiftA2 INSTANCE = new LiftA2<>();
 
@@ -32,8 +30,8 @@ private LiftA2() {
     }
 
     @Override
-    public AppC checkedApply(BiFunction fn, AppA appA, AppB appB) {
-        return appB.zip(appA.fmap(Fn2.fn2(fn))).coerce();
+    public AppC checkedApply(Fn2 fn, AppA appA, AppB appB) {
+        return appB.zip(appA.fmap(fn)).coerce();
     }
 
     @SuppressWarnings("unchecked")
@@ -46,20 +44,20 @@ AppC extends Applicative> LiftA2 liftA2(
     public static , AppA extends Applicative,
             AppB extends Applicative,
             AppC extends Applicative> Fn2 liftA2(
-            BiFunction fn) {
+            Fn2 fn) {
         return LiftA2.liftA2().apply(fn);
     }
 
     public static , AppA extends Applicative,
             AppB extends Applicative,
-            AppC extends Applicative> Fn1 liftA2(BiFunction fn,
+            AppC extends Applicative> Fn1 liftA2(Fn2 fn,
                                                                      AppA appA) {
         return LiftA2.liftA2(fn).apply(appA);
     }
 
     public static , AppA extends Applicative,
             AppB extends Applicative,
-            AppC extends Applicative> AppC liftA2(BiFunction fn,
+            AppC extends Applicative> AppC liftA2(Fn2 fn,
                                                           AppA appA,
                                                           AppB appB) {
         return LiftA2.liftA2(fn, appA).apply(appB);
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/ScanLeft.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/ScanLeft.java
index f99e6ec8c..49f77d96c 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/ScanLeft.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/ScanLeft.java
@@ -5,28 +5,27 @@
 import com.jnape.palatable.lambda.functions.Fn3;
 import com.jnape.palatable.lambda.iteration.ScanningIterator;
 
-import java.util.function.BiFunction;
-
 /**
- * Given an Iterable of As, a starting value B, and a {@link
- * BiFunction}<B, A, B>, iteratively accumulate over the Iterable, collecting each function
- * application result, finally returning an Iterable of all the results. Note that, as the name implies,
- * this function accumulates from left to right, such that scanLeft(f, 0, asList(1,2,3,4,5)) is evaluated
- * as 0, f(0, 1), f(f(0, 1), 2), f(f(f(0, 1), 2), 3), f(f(f(f(0, 1), 2), 3), 4), f(f(f(f(f(0, 1), 2), 3), 4), 5).
+ * Given an Iterable of As, a starting value B, and a
+ * {@link Fn2}<B, A, B>, iteratively accumulate over the Iterable, collecting each
+ * function application result, finally returning an Iterable of all the results. Note that, as the name
+ * implies, this function accumulates from left to right, such that scanLeft(f, 0, asList(1,2,3,4,5)) is
+ * evaluated as 0, f(0, 1), f(f(0, 1), 2), f(f(f(0, 1), 2), 3), f(f(f(f(0, 1), 2), 3), 4), f(f(f(f(f(0, 1), 2),
+ * 3), 4), 5).
  *
  * @param  The Iterable element type
  * @param  The accumulation type
  * @see FoldLeft
  */
-public final class ScanLeft implements Fn3, B, Iterable, Iterable> {
+public final class ScanLeft implements Fn3, B, Iterable, Iterable> {
 
-    private static final ScanLeft INSTANCE = new ScanLeft<>();
+    private static final ScanLeft INSTANCE = new ScanLeft<>();
 
     private ScanLeft() {
     }
 
     @Override
-    public Iterable checkedApply(BiFunction fn, B b, Iterable as) {
+    public Iterable checkedApply(Fn2 fn, B b, Iterable as) {
         return () -> new ScanningIterator<>(fn, b, as.iterator());
     }
 
@@ -35,15 +34,15 @@ public static  ScanLeft scanLeft() {
         return (ScanLeft) INSTANCE;
     }
 
-    public static  Fn2, Iterable> scanLeft(BiFunction fn) {
+    public static  Fn2, Iterable> scanLeft(Fn2 fn) {
         return ScanLeft.scanLeft().apply(fn);
     }
 
-    public static  Fn1, Iterable> scanLeft(BiFunction fn, B b) {
+    public static  Fn1, Iterable> scanLeft(Fn2 fn, B b) {
         return ScanLeft.scanLeft(fn).apply(b);
     }
 
-    public static  Iterable scanLeft(BiFunction fn, B b, Iterable as) {
+    public static  Iterable scanLeft(Fn2 fn, B b, Iterable as) {
         return ScanLeft.scanLeft(fn, b).apply(as);
     }
 }
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/Times.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/Times.java
index 10db14166..c23277e63 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/Times.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/Times.java
@@ -4,8 +4,6 @@
 import com.jnape.palatable.lambda.functions.Fn2;
 import com.jnape.palatable.lambda.functions.Fn3;
 
-import java.util.function.Function;
-
 import static com.jnape.palatable.lambda.functions.builtin.fn2.Replicate.replicate;
 import static com.jnape.palatable.lambda.functions.builtin.fn3.FoldLeft.foldLeft;
 
@@ -20,7 +18,7 @@
  *
  * @param  the input and output type
  */
-public final class Times implements Fn3, A, A> {
+public final class Times implements Fn3, A, A> {
 
     private static final Times INSTANCE = new Times<>();
 
@@ -28,7 +26,7 @@ private Times() {
     }
 
     @Override
-    public A checkedApply(Integer n, Function fn, A a) {
+    public A checkedApply(Integer n, Fn1 fn, A a) {
         if (n < 0)
             throw new IllegalStateException("n must not be less than 0");
 
@@ -40,15 +38,15 @@ public static  Times times() {
         return (Times) INSTANCE;
     }
 
-    public static  Fn2, A, A> times(Integer n) {
+    public static  Fn2, A, A> times(Integer n) {
         return Times.times().apply(n);
     }
 
-    public static  Fn1 times(Integer n, Function fn) {
+    public static  Fn1 times(Integer n, Fn1 fn) {
         return Times.times(n).apply(fn);
     }
 
-    public static  A times(Integer n, Function fn, A a) {
+    public static  A times(Integer n, Fn1 fn, A a) {
         return Times.times(n, fn).apply(a);
     }
 }
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/ZipWith.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/ZipWith.java
index 218b1db48..96c072bd2 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/ZipWith.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/ZipWith.java
@@ -17,7 +17,7 @@
  * @param  The output Iterable element type
  * @see com.jnape.palatable.lambda.functions.builtin.fn2.Zip
  */
-public final class ZipWith implements Fn3, Iterable, Iterable, Iterable> {
+public final class ZipWith implements Fn3, Iterable, Iterable, Iterable> {
 
     private static final ZipWith INSTANCE = new ZipWith<>();
 
@@ -25,7 +25,7 @@ private ZipWith() {
     }
 
     @Override
-    public Iterable checkedApply(BiFunction zipper, Iterable as,
+    public Iterable checkedApply(Fn2 zipper, Iterable as,
                                     Iterable bs) {
         return () -> new ZippingIterator<>(zipper, as.iterator(), bs.iterator());
     }
@@ -36,16 +36,16 @@ public static  ZipWith zipWith() {
     }
 
     public static  Fn2, Iterable, Iterable> zipWith(
-            BiFunction zipper) {
+            Fn2 zipper) {
         return ZipWith.zipWith().apply(zipper);
     }
 
-    public static  Fn1, Iterable> zipWith(BiFunction zipper,
+    public static  Fn1, Iterable> zipWith(Fn2 zipper,
                                                                   Iterable as) {
         return ZipWith.zipWith(zipper).apply(as);
     }
 
-    public static  Iterable zipWith(BiFunction zipper, Iterable as,
+    public static  Iterable zipWith(Fn2 zipper, Iterable as,
                                                 Iterable bs) {
         return ZipWith.zipWith(zipper, as).apply(bs);
     }
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/IfThenElse.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/IfThenElse.java
index 38f0bbe3e..70336b79a 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/IfThenElse.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/IfThenElse.java
@@ -5,9 +5,8 @@
 import com.jnape.palatable.lambda.functions.Fn3;
 import com.jnape.palatable.lambda.functions.Fn4;
 
-import java.util.function.Function;
-
-public final class IfThenElse implements Fn4, Function, Function, A, B> {
+public final class IfThenElse implements
+        Fn4, Fn1, Fn1, A, B> {
 
     private static final IfThenElse INSTANCE = new IfThenElse<>();
 
@@ -15,8 +14,8 @@ private IfThenElse() {
     }
 
     @Override
-    public B checkedApply(Function predicate, Function thenCase,
-                          Function elseCase, A a) {
+    public B checkedApply(Fn1 predicate, Fn1 thenCase,
+                          Fn1 elseCase, A a) {
         return predicate.apply(a) ? thenCase.apply(a) : elseCase.apply(a);
     }
 
@@ -25,26 +24,24 @@ public static  IfThenElse ifThenElse() {
         return (IfThenElse) INSTANCE;
     }
 
-    public static  Fn3, Function, A, B> ifThenElse(
-            Function predicate) {
+    public static  Fn3, Fn1, A, B> ifThenElse(
+            Fn1 predicate) {
         return IfThenElse.ifThenElse().apply(predicate);
     }
 
-    public static  Fn2, A, B> ifThenElse(
-            Function predicate, Function thenCase) {
+    public static  Fn2, A, B> ifThenElse(Fn1 predicate,
+                                                                           Fn1 thenCase) {
         return IfThenElse.ifThenElse(predicate).apply(thenCase);
     }
 
-    public static  Fn1 ifThenElse(
-            Function predicate, Function thenCase,
-            Function elseCase) {
+    public static  Fn1 ifThenElse(Fn1 predicate,
+                                              Fn1 thenCase,
+                                              Fn1 elseCase) {
         return IfThenElse.ifThenElse(predicate, thenCase).apply(elseCase);
     }
 
-    public static  B ifThenElse(
-            Function predicate, Function thenCase,
-            Function elseCase,
-            A a) {
+    public static  B ifThenElse(Fn1 predicate, Fn1 thenCase,
+                                      Fn1 elseCase, A a) {
         return ifThenElse(predicate, thenCase, elseCase).apply(a);
     }
 }
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/RateLimit.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/RateLimit.java
index 2da5fb3b2..fa5a0844c 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/RateLimit.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/RateLimit.java
@@ -1,5 +1,6 @@
 package com.jnape.palatable.lambda.functions.builtin.fn4;
 
+import com.jnape.palatable.lambda.functions.Fn0;
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functions.Fn2;
 import com.jnape.palatable.lambda.functions.Fn3;
@@ -9,27 +10,29 @@
 
 import java.time.Duration;
 import java.time.Instant;
-import java.util.function.Supplier;
 
 import static com.jnape.palatable.lambda.adt.hlist.HList.tuple;
 import static java.util.Collections.singleton;
 
 /**
- * Given a {@link Supplier} of {@link Instant Instants} (presumably backed by a clock), a limit, a {@link
- * Duration}, and an {@link Iterable} as, return an {@link Iterable} that iterates as
- * according to the threshold specified by the limit per duration, using the {@link Supplier} to advance time.
+ * Given an {@link Fn0} of {@link Instant Instants} (presumably backed by a clock), a limit, a
+ * {@link Duration}, and an {@link Iterable} as, return an {@link Iterable} that iterates as
+ * according to the threshold specified by the limit per duration, using the {@link Fn0} to advance time.
  * 

* As an example, the following will print at most 10 elements per second: *


- * rateLimit(Clock.systemUTC()::instant, 10L, Duration.ofSeconds(1), iterate(x -> x + 1, 1)).forEach(System.out::println);
+ * rateLimit(Clock.systemUTC()::instant, 10L, Duration.ofSeconds(1), iterate(x -> x + 1, 1))
+ *     .forEach(System.out::println);
  * 
* Currying allows different rate limits to be combined naturally: *

  * Iterable<Integer> elements = iterate(x -> x + 1, 1);
  *
- * Supplier<Instant> instantSupplier = Clock.systemUTC()::instant;
- * Fn1<Iterable<Integer>, Iterable<Integer>> tenPerSecond = rateLimit(instantSupplier, 10L, Duration.ofSeconds(1));
- * Fn1<Iterable<Integer>, Iterable<Integer>> oneHundredEveryTwoMinutes = rateLimit(instantSupplier, 100L, Duration.ofMinutes(2));
+ * Supplier<Instant> instantFn0 = Clock.systemUTC()::instant;
+ * Fn1<Iterable<Integer>, Iterable<Integer>> tenPerSecond =
+ *     rateLimit(instantFn0, 10L, Duration.ofSeconds(1));
+ * Fn1<Iterable<Integer>, Iterable<Integer>> oneHundredEveryTwoMinutes =
+ *     rateLimit(instantFn0, 100L, Duration.ofMinutes(2));
  *
  * tenPerSecond.fmap(oneHundredEveryTwoMinutes).apply(elements).forEach(System.out::println);
  * 
@@ -45,7 +48,7 @@ * * @param
the {@link Iterable} element type */ -public final class RateLimit implements Fn4, Long, Duration, Iterable, Iterable> { +public final class RateLimit implements Fn4, Long, Duration, Iterable, Iterable> { private static final RateLimit INSTANCE = new RateLimit<>(); @@ -53,11 +56,11 @@ private RateLimit() { } @Override - public Iterable checkedApply(Supplier instantSupplier, Long limit, Duration duration, Iterable as) { + public Iterable checkedApply(Fn0 instantFn0, Long limit, Duration duration, Iterable as) { if (limit < 1) throw new IllegalArgumentException("Limit must be greater than 0: " + limit); - return new RateLimitingIterable<>(as, singleton(tuple(limit, duration, instantSupplier))); + return new RateLimitingIterable<>(as, singleton(tuple(limit, duration, instantFn0))); } @SuppressWarnings("unchecked") @@ -65,21 +68,19 @@ public static RateLimit rateLimit() { return (RateLimit) INSTANCE; } - public static Fn3, Iterable> rateLimit(Supplier instantSupplier) { - return RateLimit.rateLimit().apply(instantSupplier); + public static Fn3, Iterable> rateLimit(Fn0 instantFn0) { + return RateLimit.rateLimit().apply(instantFn0); } - public static Fn2, Iterable> rateLimit(Supplier instantSupplier, Long limit) { - return RateLimit.rateLimit(instantSupplier).apply(limit); + public static Fn2, Iterable> rateLimit(Fn0 instantFn0, Long limit) { + return RateLimit.rateLimit(instantFn0).apply(limit); } - public static Fn1, Iterable> rateLimit(Supplier instantSupplier, Long limit, - Duration duration) { - return RateLimit.rateLimit(instantSupplier, limit).apply(duration); + public static Fn1, Iterable> rateLimit(Fn0 instantFn0, Long limit, Duration duration) { + return RateLimit.rateLimit(instantFn0, limit).apply(duration); } - public static Iterable rateLimit(Supplier instantSupplier, Long limit, Duration duration, - Iterable as) { - return RateLimit.rateLimit(instantSupplier, limit, duration).apply(as); + public static Iterable rateLimit(Fn0 instantFn0, Long limit, Duration duration, Iterable as) { + return RateLimit.rateLimit(instantFn0, limit, duration).apply(as); } } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/recursion/RecursiveResult.java b/src/main/java/com/jnape/palatable/lambda/functions/recursion/RecursiveResult.java index afef70f6d..29ddc08c8 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/recursion/RecursiveResult.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/recursion/RecursiveResult.java @@ -1,13 +1,13 @@ package com.jnape.palatable.lambda.functions.recursion; import com.jnape.palatable.lambda.adt.coproduct.CoProduct2; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; import java.util.Objects; -import java.util.function.Function; /** * Specialized {@link CoProduct2} representing the possible results of a primitive recursive function. @@ -30,25 +30,24 @@ public RecursiveResult invert() { @Override @SuppressWarnings("unchecked") - public RecursiveResult biMapL(Function fn) { + public RecursiveResult biMapL(Fn1 fn) { return (RecursiveResult) Bifunctor.super.biMapL(fn); } @Override @SuppressWarnings("unchecked") - public RecursiveResult biMapR(Function fn) { + public RecursiveResult biMapR(Fn1 fn) { return (RecursiveResult) Bifunctor.super.biMapR(fn); } @Override - public RecursiveResult biMap(Function lFn, - Function rFn) { + public RecursiveResult biMap(Fn1 lFn, + Fn1 rFn) { return match(a -> recurse(lFn.apply(a)), b -> terminate(rFn.apply(b))); } @Override - public RecursiveResult flatMap( - Function>> f) { + public RecursiveResult flatMap(Fn1>> f) { return match(RecursiveResult::recurse, b -> f.apply(b).coerce()); } @@ -58,13 +57,12 @@ public RecursiveResult pure(C c) { } @Override - public RecursiveResult fmap(Function fn) { + public RecursiveResult fmap(Fn1 fn) { return Monad.super.fmap(fn).coerce(); } @Override - public RecursiveResult zip( - Applicative, RecursiveResult> appFn) { + public RecursiveResult zip(Applicative, RecursiveResult> appFn) { return Monad.super.zip(appFn).coerce(); } @@ -79,11 +77,10 @@ public RecursiveResult discardR(Applicative> } @Override - @SuppressWarnings("unchecked") public , TravB extends Traversable>, AppB extends Applicative, - AppTrav extends Applicative> AppTrav traverse(Function fn, - Function pure) { + AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + Fn1 pure) { return match(__ -> pure.apply(coerce()), b -> fn.apply(b).fmap(this::pure).fmap(RecursiveResult::coerce).coerce()); } @@ -104,7 +101,7 @@ private Recurse(A a) { } @Override - public R match(Function aFn, Function bFn) { + public R match(Fn1 aFn, Fn1 bFn) { return aFn.apply(a); } @@ -134,7 +131,7 @@ private Terminate(B b) { } @Override - public R match(Function aFn, Function bFn) { + public R match(Fn1 aFn, Fn1 bFn) { return bFn.apply(b); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/recursion/Trampoline.java b/src/main/java/com/jnape/palatable/lambda/functions/recursion/Trampoline.java index 70e8f4fd7..6637219ec 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/recursion/Trampoline.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/recursion/Trampoline.java @@ -7,25 +7,23 @@ import com.jnape.palatable.lambda.functions.recursion.RecursiveResult.Recurse; import com.jnape.palatable.lambda.functions.recursion.RecursiveResult.Terminate; -import java.util.function.Function; - /** - * Given a {@link Function}<A, {@link CoProduct2}<A, B, ?>> (analogous to "recurse" and - * "return" tail position instructions, respectively), produce a {@link Function}<A, B> that - * unrolls the original function by iteratively passing each result that matches the input (A) back - * to the original function, and then terminating on and returning the first output (B). + * Given an {@link Fn1}<A, {@link CoProduct2}<A, B, ?>> (analogous to "recurse" and "return" + * tail position instructions, respectively), produce a {@link Fn1}<A, B> that unrolls the original + * function by iteratively passing each result that matches the input (A) back to the original function, + * and then terminating on and returning the first output (B). *

* This is isomorphic to - though presumably faster than - taking the last element of an {@link Unfoldr} call. * * @param the trampolined function's input type * @param the trampolined function's output type */ -public final class Trampoline implements Fn2>, A, B> { +public final class Trampoline implements Fn2>, A, B> { private static final Trampoline INSTANCE = new Trampoline<>(); @Override - public B checkedApply(Function> fn, A a) { + public B checkedApply(Fn1> fn, A a) { RecursiveResult next = fn.apply(a); while (next instanceof Recurse) next = fn.apply(((Recurse) next).a); @@ -37,11 +35,11 @@ public static Trampoline trampoline() { return (Trampoline) INSTANCE; } - public static Fn1 trampoline(Function> fn) { + public static Fn1 trampoline(Fn1> fn) { return Trampoline.trampoline().apply(fn); } - public static B trampoline(Function> fn, A a) { + public static B trampoline(Fn1> fn, A a) { return trampoline(fn).apply(a); } } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/BiPredicate.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/BiPredicate.java index 8d28fb290..54d11cd92 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/BiPredicate.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/specialized/BiPredicate.java @@ -1,42 +1,41 @@ package com.jnape.palatable.lambda.functions.specialized; import com.jnape.palatable.lambda.adt.product.Product2; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functions.Fn2; - -import java.util.function.Function; +import com.jnape.palatable.lambda.functor.Applicative; /** - * A specialized {@link Fn2} that returns a Boolean when fully applied, - * or a {@link Predicate} when partially applied. + * A specialized {@link Fn2} that returns a Boolean when fully applied, or a {@link Predicate} when partially applied. * * @param the first argument type * @param the second argument type */ @FunctionalInterface -public interface BiPredicate extends Fn2, java.util.function.BiPredicate { +public interface BiPredicate extends Fn2 { /** * {@inheritDoc} */ @Override - default boolean test(A a, B b) { - return apply(a, b); + default Predicate apply(A a) { + return Fn2.super.apply(a)::apply; } /** * {@inheritDoc} */ @Override - default Predicate apply(A a) { - return Fn2.super.apply(a)::apply; + default BiPredicate flip() { + return Fn2.super.flip()::apply; } /** * {@inheritDoc} */ @Override - default BiPredicate flip() { - return Fn2.super.flip()::apply; + default BiPredicate discardR(Applicative> appB) { + return Fn2.super.discardR(appB)::apply; } /** @@ -51,7 +50,7 @@ default BiPredicate flip() { * {@inheritDoc} */ @Override - default BiPredicate diMapL(Function fn) { + default BiPredicate diMapL(Fn1 fn) { return Fn2.super.diMapL(fn)::apply; } @@ -59,42 +58,57 @@ default BiPredicate diMapL(Function fn) { * {@inheritDoc} */ @Override - default Fn2 contraMap(Function fn) { + default Fn2 contraMap(Fn1 fn) { return Fn2.super.contraMap(fn)::apply; } /** - * Override of {@link java.util.function.BiPredicate#and(java.util.function.BiPredicate)}, returning an instance of - * BiPredicate for compatibility. Left-to-right composition. + * Left-to-right short-circuiting logical conjunction. * * @param other the biPredicate to test if this one succeeds * @return a biPredicate representing the conjunction of this biPredicate and other */ - @Override - default BiPredicate and(java.util.function.BiPredicate other) { - return (a, b) -> apply(a, b) && other.test(a, b); + default BiPredicate and(BiPredicate other) { + return (a, b) -> apply(a, b) && other.apply(a, b); } /** - * Override of {@link java.util.function.BiPredicate#or(java.util.function.BiPredicate)}, returning an instance of - * BiPredicate for compatibility. Left-to-right composition. + * Left-to-right short-circuiting logical disjunction. * * @param other the biPredicate to test if this one fails * @return a biPredicate representing the disjunction of this biPredicate and other */ - @Override - default BiPredicate or(java.util.function.BiPredicate other) { - return (a, b) -> apply(a, b) || other.test(a, b); + default BiPredicate or(BiPredicate other) { + return (a, b) -> apply(a, b) || other.apply(a, b); } /** - * Override of {@link java.util.function.BiPredicate#negate()}, returning an instance of BiPredicate - * for compatibility. + * Logical negation. * * @return the negation of this biPredicate */ - @Override default BiPredicate negate() { return (a, b) -> !apply(a, b); } + + /** + * Convert this {@link BiPredicate} to a java {@link java.util.function.BiPredicate}. + * + * @return {@link java.util.function.BiPredicate} + */ + default java.util.function.BiPredicate toBiPredicate() { + return this::apply; + } + + /** + * Create a {@link BiPredicate} from a java {@link java.util.function.BiPredicate}. + * + * @param biPredicate the {@link java.util.function.BiPredicate} + * @param the first input type + * @param the second input type + * @return the {@link BiPredicate} + */ + static BiPredicate fromBiPredicate(java.util.function.BiPredicate biPredicate) { + return biPredicate::test; + } } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/Kleisli.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/Kleisli.java index 4fae5b021..ad66e4036 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/Kleisli.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/specialized/Kleisli.java @@ -4,11 +4,9 @@ import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.monad.Monad; -import java.util.function.Function; - /** * The Kleisli arrow of a {@link Monad}, manifest as simply an {@link Fn1}<A, MB>. This can be - * thought of as a fixed, portable {@link Monad#flatMap(Function)}. + * thought of as a fixed, portable {@link Monad#flatMap(Fn1)}. * * @param the input argument type * @param the {@link Monad} unification parameter @@ -43,14 +41,6 @@ default > Kleisli compose(Kleisli before.apply(z).flatMap(this).coerce(); } - /** - * {@inheritDoc} - */ - @Override - default Kleisli compose(Function before) { - return Fn1.super.compose(before)::apply; - } - /** * {@inheritDoc} */ @@ -63,7 +53,7 @@ default Kleisli discardR(Applicative> appB) { * {@inheritDoc} */ @Override - default Kleisli contraMap(Function fn) { + default Kleisli contraMap(Fn1 fn) { return Fn1.super.contraMap(fn)::apply; } @@ -71,7 +61,7 @@ default Kleisli contraMap(Function fn) * {@inheritDoc} */ @Override - default Kleisli diMapL(Function fn) { + default Kleisli diMapL(Fn1 fn) { return Fn1.super.diMapL(fn)::apply; } @@ -86,7 +76,7 @@ default Kleisli diMapL(Function fn) { * @return the function adapted as a {@link Kleisli} arrow */ static , MB extends Monad> Kleisli kleisli( - Function fn) { + Fn1 fn) { return fn::apply; } } \ No newline at end of file diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/Noop.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/Noop.java index 568e6ca2c..73a867626 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/Noop.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/specialized/Noop.java @@ -1,6 +1,11 @@ package com.jnape.palatable.lambda.functions.specialized; +import com.jnape.palatable.lambda.adt.Unit; import com.jnape.palatable.lambda.functions.Effect; +import com.jnape.palatable.lambda.io.IO; + +import static com.jnape.palatable.lambda.adt.Unit.UNIT; +import static com.jnape.palatable.lambda.io.IO.io; /** * As the name might suggest, this is an {@link Effect} that, *ahem*, has no effect. @@ -14,7 +19,8 @@ private Noop() { } @Override - public void checkedAccept(A a) { + public IO checkedApply(A a) throws Throwable { + return io(UNIT); } /** diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/Predicate.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/Predicate.java index 2138db821..f5e849bb4 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/Predicate.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/specialized/Predicate.java @@ -1,96 +1,114 @@ package com.jnape.palatable.lambda.functions.specialized; import com.jnape.palatable.lambda.functions.Fn1; - -import java.util.function.Function; +import com.jnape.palatable.lambda.functions.Fn2; +import com.jnape.palatable.lambda.functor.Applicative; /** * A specialized {@link Fn1} that returns a Boolean. * * @param The argument type */ -public interface Predicate extends Fn1, java.util.function.Predicate { +@FunctionalInterface +public interface Predicate extends Fn1 { /** * {@inheritDoc} */ @Override - default boolean test(A a) { - return apply(a); + default Predicate diMapL(Fn1 fn) { + return Fn1.super.diMapL(fn)::apply; } /** - * Override of {@link Function#compose(Function)}, returning an instance of Predicate for - * compatibility. Right-to-left composition. - * - * @param before the function who's return value is this predicate's argument - * @param the new argument type - * @return a new predicate of Z (the new argument type) + * {@inheritDoc} */ @Override - default Predicate compose(Function before) { - return Fn1.super.compose(before)::apply; + default Predicate contraMap(Fn1 fn) { + return Fn1.super.contraMap(fn)::apply; } /** * {@inheritDoc} */ @Override - default Predicate diMapL(Function fn) { - return Fn1.super.diMapL(fn)::apply; + default BiPredicate widen() { + return Fn1.super.widen()::checkedApply; } /** * {@inheritDoc} */ @Override - default Predicate contraMap(Function fn) { - return Fn1.super.contraMap(fn)::apply; + default Predicate discardR(Applicative> appB) { + return Fn1.super.discardR(appB)::checkedApply; + } + + /** + * {@inheritDoc} + */ + @Override + default BiPredicate compose(Fn2 before) { + return Fn1.super.compose(before)::apply; } /** - * Override of {@link java.util.function.Predicate#and(java.util.function.Predicate)}, returning an instance of - * Predicate for compatibility. Left-to-right composition. + * Left-to-right short-circuiting logical conjunction. * * @param other the predicate to test if this one succeeds * @return a predicate representing the conjunction of this predicate and other */ - @Override - default Predicate and(java.util.function.Predicate other) { - return a -> apply(a) && other.test(a); + default Predicate and(Predicate other) { + return a -> apply(a) && other.apply(a); } /** - * Override of {@link java.util.function.Predicate#or(java.util.function.Predicate)}, returning an instance of - * Predicate for compatibility. Left-to-right composition. + * Left-to-right short-circuiting logical disjunction. * * @param other the predicate to test if this one fails * @return a predicate representing the disjunction of this predicate and other */ - @Override - default Predicate or(java.util.function.Predicate other) { - return a -> apply(a) || other.test(a); + default Predicate or(Predicate other) { + return a -> apply(a) || other.apply(a); } /** - * Override of {@link java.util.function.Predicate#negate()}, returning an instance of Predicate for - * compatibility. + * Logical negation. * * @return the negation of this predicate */ - @Override default Predicate negate() { return a -> !apply(a); } /** - * Static factory method to create a predicate from a function. + * Convert this {@link Predicate} to a java {@link java.util.function.Predicate}. + * + * @return the {@link java.util.function.Predicate} + */ + default java.util.function.Predicate toPredicate() { + return this::apply; + } + + /** + * Static factory method to create a predicate from an {@link Fn1}. * - * @param predicate the function + * @param predicate the {@link Fn1} * @param the input type * @return the predicate */ - static Predicate predicate(Function predicate) { + static Predicate predicate(Fn1 predicate) { return predicate::apply; } + + /** + * Create a {@link Predicate} from a java {@link java.util.function.Predicate}. + * + * @param predicate the java {@link java.util.function.Predicate} + * @param the input type + * @return the {@link Predicate} + */ + static Predicate fromPredicate(java.util.function.Predicate predicate) { + return predicate::test; + } } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/SideEffect.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/SideEffect.java new file mode 100644 index 000000000..305fd900a --- /dev/null +++ b/src/main/java/com/jnape/palatable/lambda/functions/specialized/SideEffect.java @@ -0,0 +1,54 @@ +package com.jnape.palatable.lambda.functions.specialized; + +import com.jnape.palatable.lambda.functions.specialized.checked.Runtime; +import com.jnape.palatable.lambda.io.IO; + +/** + * An interface used to represent an effect that requires no input and produces no output, and therefore is only + * perceivable through inspection of some unreported state. Only exists because Java target-type inference requires an + * interface, or else this would all be internal, hence the inconveniently-named Ω. + *

+ * Ω should *never* be called directly. + * + * @see IO#io(SideEffect) + */ +public interface SideEffect { + + @SuppressWarnings("NonAsciiCharacters") + void Ω() throws Throwable; + + /** + * Convert this {@link SideEffect} to a java {@link Runnable}. + * + * @return the {@link Runnable} + */ + default Runnable toRunnable() { + return () -> { + try { + Ω(); + } catch (Throwable t) { + throw Runtime.throwChecked(t); + } + }; + } + + /** + * Create a {@link SideEffect} from a java {@link Runnable}. + * + * @param runnable the {@link Runnable} + * @return the {@link SideEffect} + */ + static SideEffect fromRunnable(Runnable runnable) { + return runnable::run; + } + + /** + * Static factory method to aid in inference. + * + * @param sideEffect the {@link SideEffect} + * @return the {@link SideEffect} + */ + static SideEffect sideEffect(SideEffect sideEffect) { + return sideEffect; + } +} diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedRunnable.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedRunnable.java deleted file mode 100644 index c3f1bbd51..000000000 --- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/CheckedRunnable.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.jnape.palatable.lambda.functions.specialized.checked; - -import static com.jnape.palatable.lambda.functions.specialized.checked.Runtime.throwChecked; - -/** - * Specialized {@link Runnable} that can throw any {@link Throwable}. - * - * @param The {@link Throwable} type - */ -@FunctionalInterface -public interface CheckedRunnable extends Runnable { - - /** - * A version of {@link Runnable#run()} that can throw checked exceptions. - * - * @throws T any exception that can be thrown by this method - */ - void checkedRun() throws T; - - @Override - default void run() { - try { - checkedRun(); - } catch (Throwable t) { - throw throwChecked(t); - } - } - - /** - * Convenience static factory method for constructing a {@link CheckedRunnable} without an explicit cast or type - * attribution at the call site. - * - * @param runnable the checked runnable - * @param the inferred Throwable type - * @return the checked runnable - */ - static CheckedRunnable checked(CheckedRunnable runnable) { - return runnable::run; - } - -} diff --git a/src/main/java/com/jnape/palatable/lambda/functor/Applicative.java b/src/main/java/com/jnape/palatable/lambda/functor/Applicative.java index af08c2a00..4dd634e13 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/Applicative.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/Applicative.java @@ -1,9 +1,8 @@ package com.jnape.palatable.lambda.functor; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functor.builtin.Lazy; -import java.util.function.Function; - import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id; @@ -47,7 +46,7 @@ public interface Applicative> extends Functor * @param the resulting applicative parameter type * @return the mapped applicative */ - Applicative zip(Applicative, App> appFn); + Applicative zip(Applicative, App> appFn); /** * Given a {@link Lazy lazy} instance of this applicative over a mapping function, "zip" the two instances together @@ -61,12 +60,12 @@ public interface Applicative> extends Functor * @see com.jnape.palatable.lambda.adt.Either */ default Lazy> lazyZip( - Lazy, App>> lazyAppFn) { + Lazy, App>> lazyAppFn) { return lazyAppFn.fmap(this::zip); } @Override - default Applicative fmap(Function fn) { + default Applicative fmap(Fn1 fn) { return zip(pure(fn)); } diff --git a/src/main/java/com/jnape/palatable/lambda/functor/Bifunctor.java b/src/main/java/com/jnape/palatable/lambda/functor/Bifunctor.java index abdbd7024..bfb201242 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/Bifunctor.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/Bifunctor.java @@ -1,6 +1,6 @@ package com.jnape.palatable.lambda.functor; -import java.util.function.Function; +import com.jnape.palatable.lambda.functions.Fn1; import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id; @@ -26,7 +26,7 @@ public interface Bifunctor> extends Bounded * @param fn the mapping function * @return a bifunctor over C (the new left parameter) and B (the same right parameter) */ - default Bifunctor biMapL(Function fn) { + default Bifunctor biMapL(Fn1 fn) { return biMap(fn, id()); } @@ -38,7 +38,7 @@ default Bifunctor biMapL(Function fn) { * @param fn the mapping function * @return a bifunctor over A (the same left parameter) and C (the new right parameter) */ - default Bifunctor biMapR(Function fn) { + default Bifunctor biMapR(Fn1 fn) { return biMap(id(), fn); } @@ -52,5 +52,5 @@ default Bifunctor biMapR(Function fn) { * @param rFn the right parameter mapping function * @return a bifunctor over C (the new left parameter type) and D (the new right parameter type) */ - Bifunctor biMap(Function lFn, Function rFn); + Bifunctor biMap(Fn1 lFn, Fn1 rFn); } diff --git a/src/main/java/com/jnape/palatable/lambda/functor/BoundedBifunctor.java b/src/main/java/com/jnape/palatable/lambda/functor/BoundedBifunctor.java index 8096ae1cb..057c3bd29 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/BoundedBifunctor.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/BoundedBifunctor.java @@ -1,6 +1,6 @@ package com.jnape.palatable.lambda.functor; -import java.util.function.Function; +import com.jnape.palatable.lambda.functions.Fn1; import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id; @@ -26,24 +26,22 @@ public interface BoundedBifunctor< /** * Covariantly map the left parameter into a value that is covariant to ContraA. * - * @param fn the mapping function * @param the new left parameter type + * @param fn the mapping function * @return a bifunctor of C (the new parameter type) and B (the same right parameter) */ - default BoundedBifunctor biMapL( - Function fn) { + default BoundedBifunctor biMapL(Fn1 fn) { return biMap(fn, id()); } /** * Covariantly map the right parameter into a value that is covariant to ContraB. * - * @param fn the mapping function * @param the new right parameter type + * @param fn the mapping function * @return a bifunctor of A (the same left parameter) and C (the new parameter type) */ - default BoundedBifunctor biMapR( - Function fn) { + default BoundedBifunctor biMapR(Fn1 fn) { return biMap(id(), fn); } @@ -58,6 +56,6 @@ default BoundedBifunctor biMapR( * @return a bifunctor over C (the new left parameter type) and D (the new right parameter type) */ BoundedBifunctor biMap( - Function lFn, - Function rFn); + Fn1 lFn, + Fn1 rFn); } diff --git a/src/main/java/com/jnape/palatable/lambda/functor/Cartesian.java b/src/main/java/com/jnape/palatable/lambda/functor/Cartesian.java index 97ef582b0..e3ac2783b 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/Cartesian.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/Cartesian.java @@ -1,8 +1,7 @@ package com.jnape.palatable.lambda.functor; import com.jnape.palatable.lambda.adt.hlist.Tuple2; - -import java.util.function.Function; +import com.jnape.palatable.lambda.functions.Fn1; /** * {@link Profunctor} strength in the cartesian product sense: p a b -> p (c ^ a) (c ^ b) for any type @@ -35,20 +34,20 @@ default Cartesian, P> carry() { } @Override - Cartesian diMap(Function lFn, Function rFn); + Cartesian diMap(Fn1 lFn, Fn1 rFn); @Override - default Cartesian diMapL(Function fn) { + default Cartesian diMapL(Fn1 fn) { return (Cartesian) Profunctor.super.diMapL(fn); } @Override - default Cartesian diMapR(Function fn) { + default Cartesian diMapR(Fn1 fn) { return (Cartesian) Profunctor.super.diMapR(fn); } @Override - default Cartesian contraMap(Function fn) { + default Cartesian contraMap(Fn1 fn) { return (Cartesian) Profunctor.super.contraMap(fn); } } diff --git a/src/main/java/com/jnape/palatable/lambda/functor/Cocartesian.java b/src/main/java/com/jnape/palatable/lambda/functor/Cocartesian.java index 41bea7f1c..07bfe13d4 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/Cocartesian.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/Cocartesian.java @@ -1,8 +1,7 @@ package com.jnape.palatable.lambda.functor; import com.jnape.palatable.lambda.adt.choice.Choice2; - -import java.util.function.Function; +import com.jnape.palatable.lambda.functions.Fn1; /** * {@link Profunctor} strength in the cocartesian coproduct sense: p a b -> p (c v a) (c v b) for any @@ -39,13 +38,13 @@ default Cocartesian, P> choose() { * {@inheritDoc} */ @Override - Cocartesian diMap(Function lFn, Function rFn); + Cocartesian diMap(Fn1 lFn, Fn1 rFn); /** * {@inheritDoc} */ @Override - default Cocartesian diMapL(Function fn) { + default Cocartesian diMapL(Fn1 fn) { return (Cocartesian) Profunctor.super.diMapL(fn); } @@ -53,7 +52,7 @@ default Cocartesian diMapL(Function fn) { * {@inheritDoc} */ @Override - default Cocartesian diMapR(Function fn) { + default Cocartesian diMapR(Fn1 fn) { return (Cocartesian) Profunctor.super.diMapR(fn); } @@ -61,7 +60,7 @@ default Cocartesian diMapR(Function fn) { * {@inheritDoc} */ @Override - default Cocartesian contraMap(Function fn) { + default Cocartesian contraMap(Fn1 fn) { return (Cocartesian) Profunctor.super.contraMap(fn); } } diff --git a/src/main/java/com/jnape/palatable/lambda/functor/Contravariant.java b/src/main/java/com/jnape/palatable/lambda/functor/Contravariant.java index bce1d114a..c596b36b0 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/Contravariant.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/Contravariant.java @@ -1,13 +1,14 @@ package com.jnape.palatable.lambda.functor; -import java.util.function.Function; +import com.jnape.palatable.lambda.functions.Fn1; /** * The contravariant functor (or "co-functor"); that is, a functor that maps contravariantly (A <- B) * over its parameter. * Contravariant functors are not necessarily {@link Functor}s. *

- * For more information, read about Contravariant Functors. * * @param the type of the parameter @@ -23,5 +24,5 @@ public interface Contravariant> { * @param the new parameter type * @return the mapped Contravariant functor instance */ - Contravariant contraMap(Function fn); + Contravariant contraMap(Fn1 fn); } diff --git a/src/main/java/com/jnape/palatable/lambda/functor/Functor.java b/src/main/java/com/jnape/palatable/lambda/functor/Functor.java index 49e5664cd..ec4323641 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/Functor.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/Functor.java @@ -2,8 +2,6 @@ import com.jnape.palatable.lambda.functions.Fn1; -import java.util.function.Function; - import static com.jnape.palatable.lambda.functions.builtin.fn1.Downcast.downcast; /** @@ -32,7 +30,7 @@ public interface Functor> { * @param fn the mapping function * @return a functor over B (the new parameter type) */ - Functor fmap(Function fn); + Functor fmap(Fn1 fn); /** * Convenience method for coercing this functor instance into another concrete type. Unsafe. diff --git a/src/main/java/com/jnape/palatable/lambda/functor/Profunctor.java b/src/main/java/com/jnape/palatable/lambda/functor/Profunctor.java index 2c4b45200..b9518d3e4 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/Profunctor.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/Profunctor.java @@ -2,8 +2,6 @@ import com.jnape.palatable.lambda.functions.Fn1; -import java.util.function.Function; - import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id; /** @@ -33,7 +31,7 @@ public interface Profunctor> extends Contr * @param rFn the right parameter mapping function * @return a profunctor over Z (the new left parameter type) and C (the new right parameter type) */ - Profunctor diMap(Function lFn, Function rFn); + Profunctor diMap(Fn1 lFn, Fn1 rFn); /** * Contravariantly map over the left parameter. @@ -42,7 +40,7 @@ public interface Profunctor> extends Contr * @param fn the mapping function * @return a profunctor over Z (the new left parameter type) and C (the same right parameter type) */ - default Profunctor diMapL(Function fn) { + default Profunctor diMapL(Fn1 fn) { return diMap(fn, id()); } @@ -54,7 +52,7 @@ default Profunctor diMapL(Function fn) { * @param fn the mapping function * @return a profunctor over A (the same left parameter type) and C (the new right parameter type) */ - default Profunctor diMapR(Function fn) { + default Profunctor diMapR(Fn1 fn) { return diMap(id(), fn); } @@ -62,7 +60,7 @@ default Profunctor diMapR(Function fn) { * {@inheritDoc} */ @Override - default Profunctor contraMap(Function fn) { + default Profunctor contraMap(Fn1 fn) { return diMapL(fn); } } diff --git a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Compose.java b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Compose.java index 912ca8109..a9a50eb91 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Compose.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Compose.java @@ -1,9 +1,9 @@ package com.jnape.palatable.lambda.functor.builtin; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functor.Applicative; import java.util.Objects; -import java.util.function.Function; import static com.jnape.palatable.lambda.functions.builtin.fn1.Upcast.upcast; @@ -33,7 +33,7 @@ public , FGA extends Applicative> FGA getCom * {@inheritDoc} */ @Override - public Compose fmap(Function fn) { + public Compose fmap(Fn1 fn) { return new Compose<>(fga.fmap(g -> g.fmap(fn))); } @@ -49,8 +49,8 @@ public Compose pure(B b) { * {@inheritDoc} */ @Override - public Compose zip(Applicative, Compose> appFn) { - return new Compose<>(fga.zip(appFn.>>coerce() + public Compose zip(Applicative, Compose> appFn) { + return new Compose<>(fga.zip(appFn.>>coerce() .getCompose().fmap(gFn -> g -> g.zip(gFn)))); } @@ -59,13 +59,13 @@ public Compose zip(Applicative, Co */ @Override public Lazy> lazyZip( - Lazy, Compose>> lazyAppFn) { + Lazy, Compose>> lazyAppFn) { @SuppressWarnings("RedundantTypeArguments") - Lazy, G>, F>> lazyAppFnCoerced = + Lazy, G>, F>> lazyAppFnCoerced = lazyAppFn - .>>fmap( - Applicative, Compose>::coerce) - .fmap(Compose>::getCompose); + .>>fmap( + Applicative, Compose>::coerce) + .fmap(Compose>::getCompose); return fga.>fmap(upcast()) .>lazyZip(lazyAppFnCoerced.fmap(fgf -> fgf.fmap(gf -> ga -> ga.zip(gf)))) diff --git a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Const.java b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Const.java index e857013a8..279d04595 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Const.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Const.java @@ -1,12 +1,12 @@ package com.jnape.palatable.lambda.functor.builtin; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; import java.util.Objects; -import java.util.function.Function; /** * A (surprisingly useful) functor over some phantom type B, retaining a value of type A that @@ -46,7 +46,7 @@ public A runConst() { * @return a Const over A (the same value) and C (the new phantom parameter) */ @Override - public Const fmap(Function fn) { + public Const fmap(Fn1 fn) { return Monad.super.fmap(fn).coerce(); } @@ -60,7 +60,7 @@ public Const pure(C c) { * {@inheritDoc} */ @Override - public Const zip(Applicative, Const> appFn) { + public Const zip(Applicative, Const> appFn) { return Monad.super.zip(appFn).coerce(); } @@ -69,7 +69,7 @@ public Const zip(Applicative, Const Lazy> lazyZip( - Lazy, Const>> lazyAppFn) { + Lazy, Const>> lazyAppFn) { return Monad.super.lazyZip(lazyAppFn).fmap(Monad>::coerce); } @@ -94,7 +94,7 @@ public Const discardR(Applicative> appB) { */ @Override @SuppressWarnings("unchecked") - public Const flatMap(Function>> f) { + public Const flatMap(Fn1>> f) { return (Const) this; } @@ -104,8 +104,8 @@ public Const flatMap(Function, TravB extends Traversable>, AppB extends Applicative, - AppTrav extends Applicative> AppTrav traverse(Function fn, - Function pure) { + AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + Fn1 pure) { return pure.apply(coerce()); } @@ -113,9 +113,8 @@ AppTrav extends Applicative> AppTrav traverse(Function Const biMapL(Function fn) { - return (Const) Bifunctor.super.biMapL(fn); + public Const biMapL(Fn1 fn) { + return (Const) Bifunctor.super.biMapL(fn); } /** @@ -123,7 +122,7 @@ public Const biMapL(Function fn) { */ @Override @SuppressWarnings("unchecked") - public Const biMapR(Function fn) { + public Const biMapR(Fn1 fn) { return (Const) Bifunctor.super.biMapR(fn); } @@ -131,8 +130,8 @@ public Const biMapR(Function fn) { * {@inheritDoc} */ @Override - public Const biMap(Function lFn, - Function rFn) { + public Const biMap(Fn1 lFn, + Fn1 rFn) { return new Const<>(lFn.apply(a)); } diff --git a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Exchange.java b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Exchange.java index 8d7cc82ea..f04050368 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Exchange.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Exchange.java @@ -1,10 +1,9 @@ package com.jnape.palatable.lambda.functor.builtin; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functor.Profunctor; import com.jnape.palatable.lambda.optics.Iso; -import java.util.function.Function; - /** * A profunctor used to extract the isomorphic functions an {@link Iso} is composed of. * @@ -14,10 +13,10 @@ * @param the larger viewed value of an {@link Iso} */ public final class Exchange implements Profunctor> { - private final Function sa; - private final Function bt; + private final Fn1 sa; + private final Fn1 bt; - public Exchange(Function sa, Function bt) { + public Exchange(Fn1 sa, Fn1 bt) { this.sa = sa; this.bt = bt; } @@ -25,18 +24,18 @@ public Exchange(Function sa, FunctionS -> A. * - * @return a {@link Function}<S, A> + * @return an {@link Fn1}<S, A> */ - public Function sa() { + public Fn1 sa() { return sa; } /** * Extract the mapping B -> T. * - * @return a {@link Function}<B, T> + * @return an {@link Fn1}<B, T> */ - public Function bt() { + public Fn1 bt() { return bt; } @@ -44,16 +43,16 @@ public Exchange(Function sa, Function Exchange diMap(Function lFn, - Function rFn) { - return new Exchange<>(lFn.andThen(sa), bt.andThen(rFn)); + public Exchange diMap(Fn1 lFn, + Fn1 rFn) { + return new Exchange<>(lFn.fmap(sa), bt.fmap(rFn)); } /** * {@inheritDoc} */ @Override - public Exchange diMapL(Function fn) { + public Exchange diMapL(Fn1 fn) { return (Exchange) Profunctor.super.diMapL(fn); } @@ -61,7 +60,7 @@ public Exchange diMapL(Function fn) { * {@inheritDoc} */ @Override - public Exchange diMapR(Function fn) { + public Exchange diMapR(Fn1 fn) { return (Exchange) Profunctor.super.diMapR(fn); } @@ -69,7 +68,7 @@ public Exchange diMapR(Function fn) { * {@inheritDoc} */ @Override - public Exchange contraMap(Function fn) { + public Exchange contraMap(Fn1 fn) { return (Exchange) Profunctor.super.contraMap(fn); } } diff --git a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Identity.java b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Identity.java index e17ae005f..bb298596c 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Identity.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Identity.java @@ -1,11 +1,11 @@ package com.jnape.palatable.lambda.functor.builtin; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; import java.util.Objects; -import java.util.function.Function; /** * A functor over some value of type A that can be mapped over and retrieved later. @@ -33,7 +33,7 @@ public A runIdentity() { * {@inheritDoc} */ @Override - public Identity flatMap(Function>> f) { + public Identity flatMap(Fn1>> f) { return f.apply(runIdentity()).coerce(); } @@ -41,7 +41,7 @@ public Identity flatMap(Function Identity fmap(Function fn) { + public Identity fmap(Fn1 fn) { return Monad.super.fmap(fn).coerce(); } @@ -57,8 +57,8 @@ public Identity pure(B b) { * {@inheritDoc} */ @Override - public Identity zip(Applicative, Identity> appFn) { - return new Identity<>(appFn.>>coerce().runIdentity().apply(a)); + public Identity zip(Applicative, Identity> appFn) { + return new Identity<>(appFn.>>coerce().runIdentity().apply(a)); } /** @@ -66,7 +66,7 @@ public Identity zip(Applicative, Identit */ @Override public Lazy> lazyZip( - Lazy, Identity>> lazyAppFn) { + Lazy, Identity>> lazyAppFn) { return Monad.super.lazyZip(lazyAppFn).fmap(Monad>::coerce); } @@ -93,8 +93,8 @@ public Identity discardR(Applicative> appB) { @SuppressWarnings("unchecked") public , TravB extends Traversable>, AppB extends Applicative, - AppTrav extends Applicative> AppTrav traverse(Function fn, - Function pure) { + AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + Fn1 pure) { return (AppTrav) fn.apply(runIdentity()).fmap(Identity::new); } diff --git a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Lazy.java b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Lazy.java index ea1bef9cd..c79a4c0c7 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Lazy.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Lazy.java @@ -2,17 +2,15 @@ import com.jnape.palatable.lambda.adt.hlist.Tuple2; import com.jnape.palatable.lambda.functions.Fn0; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; import java.util.LinkedList; import java.util.Objects; -import java.util.function.Function; -import java.util.function.Supplier; import static com.jnape.palatable.lambda.adt.hlist.HList.tuple; -import static com.jnape.palatable.lambda.functions.Fn0.fn0; import static com.jnape.palatable.lambda.functions.builtin.fn2.Into.into; import static com.jnape.palatable.lambda.functions.recursion.RecursiveResult.recurse; import static com.jnape.palatable.lambda.functions.recursion.RecursiveResult.terminate; @@ -39,10 +37,10 @@ private Lazy() { * {@inheritDoc} */ @Override - public Lazy flatMap(Function>> f) { + public Lazy flatMap(Fn1>> f) { @SuppressWarnings("unchecked") Lazy source = (Lazy) this; @SuppressWarnings({"unchecked", "RedundantCast"}) - Function> flatMap = (Function>) (Object) f; + Fn1> flatMap = (Fn1>) (Object) f; return new Compose<>(source, flatMap); } @@ -53,8 +51,8 @@ public Lazy flatMap(Function>> f) { @SuppressWarnings("unchecked") public , TravB extends Traversable>, AppB extends Applicative, - AppTrav extends Applicative> AppTrav traverse(Function fn, - Function pure) { + AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + Fn1 pure) { return fn.apply(value()).fmap(b -> (TravB) lazy(b)).coerce(); } @@ -70,7 +68,7 @@ public final Lazy pure(B b) { * {@inheritDoc} */ @Override - public final Lazy fmap(Function fn) { + public final Lazy fmap(Fn1 fn) { return Monad.super.fmap(fn).coerce(); } @@ -78,7 +76,7 @@ public final Lazy fmap(Function fn) { * {@inheritDoc} */ @Override - public Lazy zip(Applicative, Lazy> appFn) { + public Lazy zip(Applicative, Lazy> appFn) { return Monad.super.zip(appFn).coerce(); } @@ -127,12 +125,12 @@ public static Lazy lazy(A value) { /** * Wrap a computation in a lazy computation. * - * @param supplier the computation - * @param the value type + * @param the value type + * @param fn0 the computation * @return the new {@link Lazy} */ - public static Lazy lazy(Supplier supplier) { - return new Later<>(fn0(supplier)); + public static Lazy lazy(Fn0 fn0) { + return new Later<>(fn0); } private static final class Later extends Lazy { @@ -149,18 +147,18 @@ public A value() { } private static final class Compose extends Lazy { - private final Lazy source; - private final Function> flatMap; + private final Lazy source; + private final Fn1> flatMap; private Compose(Lazy source, - Function> flatMap) { + Fn1> flatMap) { this.source = source; this.flatMap = flatMap; } @Override public A value() { - @SuppressWarnings("unchecked") Tuple2, LinkedList>>> tuple = + @SuppressWarnings("unchecked") Tuple2, LinkedList>>> tuple = tuple((Lazy) this, new LinkedList<>()); @SuppressWarnings("unchecked") A a = (A) trampoline(into((source, flatMaps) -> { diff --git a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Market.java b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Market.java index efb2e0247..f1a4b3243 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Market.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Market.java @@ -8,8 +8,6 @@ import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.optics.Prism; -import java.util.function.Function; - import static com.jnape.palatable.lambda.adt.Either.left; import static com.jnape.palatable.lambda.adt.choice.Choice2.a; import static com.jnape.palatable.lambda.adt.choice.Choice2.b; @@ -31,7 +29,7 @@ public final class Market implements private final Fn1 bt; private final Fn1> sta; - public Market(Function bt, Function> sta) { + public Market(Fn1 bt, Fn1> sta) { this.bt = fn1(bt); this.sta = fn1(sta); } @@ -39,7 +37,7 @@ public Market(Function bt, FunctionB -> T. * - * @return a {@link Function}<B, T> + * @return a {@link Fn1}<B, T> */ public Fn1 bt() { return bt; @@ -48,7 +46,7 @@ public Market(Function bt, FunctionS -> {@link Either}<T, A>. * - * @return a {@link Function}<S, {@link Either}<T, A>> + * @return a {@link Fn1}<S, {@link Either}<T, A>> */ public Fn1> sta() { return sta; @@ -66,7 +64,7 @@ public Market pure(U u) { * {@inheritDoc} */ @Override - public Market flatMap(Function>> f) { + public Market flatMap(Fn1>> f) { return new Market<>(b -> f.apply(bt().apply(b)).>coerce().bt().apply(b), s -> sta().apply(s).invert() .flatMap(t -> f.apply(t).>coerce().sta() @@ -77,8 +75,8 @@ public Market flatMap(Function Market zip(Applicative, Market> appFn) { - Market> marketF = appFn.coerce(); + public Market zip(Applicative, Market> appFn) { + Market> marketF = appFn.coerce(); return new Market<>(b -> marketF.bt().apply(b).apply(bt().apply(b)), s -> sta().apply(s).invert().zip(marketF.sta().apply(s).invert()).invert()); } @@ -87,8 +85,8 @@ public Market zip(Applicative, * {@inheritDoc} */ @Override - public Market fmap(Function fn) { - return diMapR(fn); + public Market fmap(Fn1 fn) { + return diMapR(fn::apply); } /** @@ -105,8 +103,8 @@ public Market, Choice2> cocartesian() { * {@inheritDoc} */ @Override - public Market diMap(Function lFn, - Function rFn) { + public Market diMap(Fn1 lFn, + Fn1 rFn) { return new Market<>(bt.fmap(rFn), sta.diMapL(lFn).diMapR(c -> c.biMapL(rFn))); } @@ -114,7 +112,7 @@ public Market diMap(Function lFn, * {@inheritDoc} */ @Override - public Market diMapL(Function fn) { + public Market diMapL(Fn1 fn) { return (Market) Cocartesian.super.diMapL(fn); } @@ -122,7 +120,7 @@ public Market diMapL(Function fn) { * {@inheritDoc} */ @Override - public Market diMapR(Function fn) { + public Market diMapR(Fn1 fn) { return (Market) Cocartesian.super.diMapR(fn); } @@ -130,7 +128,7 @@ public Market diMapR(Function fn) { * {@inheritDoc} */ @Override - public Market contraMap(Function fn) { + public Market contraMap(Fn1 fn) { return (Market) Cocartesian.super.contraMap(fn); } } diff --git a/src/main/java/com/jnape/palatable/lambda/functor/builtin/State.java b/src/main/java/com/jnape/palatable/lambda/functor/builtin/State.java index 68de3685d..ed3f17470 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/builtin/State.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/builtin/State.java @@ -8,8 +8,6 @@ import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.monad.Monad; -import java.util.function.Function; - import static com.jnape.palatable.lambda.adt.Unit.UNIT; import static com.jnape.palatable.lambda.adt.hlist.HList.tuple; import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; @@ -89,7 +87,7 @@ public State withState(Fn1 fn) { * {@inheritDoc} */ @Override - public State flatMap(Function>> f) { + public State flatMap(Fn1>> f) { return state(s -> run(s).into((a, s2) -> f.apply(a).>coerce().run(s2))); } @@ -105,7 +103,7 @@ public State pure(B b) { * {@inheritDoc} */ @Override - public State fmap(Function fn) { + public State fmap(Fn1 fn) { return Monad.super.fmap(fn).coerce(); } @@ -113,7 +111,7 @@ public State fmap(Function fn) { * {@inheritDoc} */ @Override - public State zip(Applicative, State> appFn) { + public State zip(Applicative, State> appFn) { return Monad.super.zip(appFn).coerce(); } @@ -122,7 +120,7 @@ public State zip(Applicative, State Lazy> lazyZip( - Lazy, State>> lazyAppFn) { + Lazy, State>> lazyAppFn) { return Monad.super.lazyZip(lazyAppFn).fmap(Monad>::coerce); } diff --git a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Tagged.java b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Tagged.java index 3b2ea5e79..c601e6d65 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Tagged.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Tagged.java @@ -1,12 +1,11 @@ package com.jnape.palatable.lambda.functor.builtin; import com.jnape.palatable.lambda.adt.choice.Choice2; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Cocartesian; import com.jnape.palatable.lambda.monad.Monad; -import java.util.function.Function; - import static com.jnape.palatable.lambda.adt.choice.Choice2.b; /** @@ -36,7 +35,7 @@ public B unTagged() { * {@inheritDoc} */ @Override - public Tagged flatMap(Function>> f) { + public Tagged flatMap(Fn1>> f) { return f.apply(b).coerce(); } @@ -52,7 +51,7 @@ public Tagged pure(C c) { * {@inheritDoc} */ @Override - public Tagged fmap(Function fn) { + public Tagged fmap(Fn1 fn) { return Monad.super.fmap(fn).coerce(); } @@ -60,7 +59,7 @@ public Tagged fmap(Function fn) { * {@inheritDoc} */ @Override - public Tagged zip(Applicative, Tagged> appFn) { + public Tagged zip(Applicative, Tagged> appFn) { return Monad.super.zip(appFn).coerce(); } @@ -92,8 +91,7 @@ public Tagged, Choice2> cocartesian() { * {@inheritDoc} */ @Override - public Tagged diMap(Function lFn, - Function rFn) { + public Tagged diMap(Fn1 lFn, Fn1 rFn) { return new Tagged<>(rFn.apply(b)); } @@ -101,7 +99,7 @@ public Tagged diMap(Function lFn, * {@inheritDoc} */ @Override - public Tagged diMapL(Function fn) { + public Tagged diMapL(Fn1 fn) { return (Tagged) Cocartesian.super.diMapL(fn); } @@ -109,7 +107,7 @@ public Tagged diMapL(Function fn) { * {@inheritDoc} */ @Override - public Tagged diMapR(Function fn) { + public Tagged diMapR(Fn1 fn) { return (Tagged) Cocartesian.super.diMapR(fn); } @@ -117,7 +115,7 @@ public Tagged diMapR(Function fn) { * {@inheritDoc} */ @Override - public Tagged contraMap(Function fn) { + public Tagged contraMap(Fn1 fn) { return (Tagged) Cocartesian.super.contraMap(fn); } } diff --git a/src/main/java/com/jnape/palatable/lambda/io/IO.java b/src/main/java/com/jnape/palatable/lambda/io/IO.java index d2e630e20..2848da1fc 100644 --- a/src/main/java/com/jnape/palatable/lambda/io/IO.java +++ b/src/main/java/com/jnape/palatable/lambda/io/IO.java @@ -5,6 +5,8 @@ import com.jnape.palatable.lambda.adt.choice.Choice2; import com.jnape.palatable.lambda.adt.hlist.Tuple2; import com.jnape.palatable.lambda.functions.Fn0; +import com.jnape.palatable.lambda.functions.Fn1; +import com.jnape.palatable.lambda.functions.specialized.SideEffect; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; @@ -12,8 +14,8 @@ import java.util.LinkedList; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; -import java.util.function.Function; +import static com.jnape.palatable.lambda.adt.Unit.UNIT; import static com.jnape.palatable.lambda.adt.choice.Choice2.a; import static com.jnape.palatable.lambda.adt.hlist.HList.tuple; import static com.jnape.palatable.lambda.functions.Fn0.fn0; @@ -77,7 +79,7 @@ public final CompletableFuture unsafePerformAsyncIO() { * @param recoveryFn the recovery function * @return the guarded {@link IO} */ - public final IO exceptionally(Function recoveryFn) { + public final IO exceptionally(Fn1 recoveryFn) { return new IO() { @Override public A unsafePerformIO() { @@ -103,7 +105,7 @@ public final IO pure(B b) { * {@inheritDoc} */ @Override - public final IO fmap(Function fn) { + public final IO fmap(Fn1 fn) { return Monad.super.fmap(fn).coerce(); } @@ -111,11 +113,11 @@ public final IO fmap(Function fn) { * {@inheritDoc} */ @Override - public final IO zip(Applicative, IO> appFn) { + public final IO zip(Applicative, IO> appFn) { @SuppressWarnings("unchecked") IO source = (IO) this; @SuppressWarnings("unchecked") - IO> zip = (IO>) (Object) appFn; + IO> zip = (IO>) (Object) appFn; return new Compose<>(source, a(zip)); } @@ -123,7 +125,7 @@ public final IO zip(Applicative, IO> * {@inheritDoc} */ @Override - public Lazy> lazyZip(Lazy, IO>> lazyAppFn) { + public Lazy> lazyZip(Lazy, IO>> lazyAppFn) { return Monad.super.lazyZip(lazyAppFn).fmap(Monad>::coerce); } @@ -147,11 +149,11 @@ public final IO discardR(Applicative> appB) { * {@inheritDoc} */ @Override - public final IO flatMap(Function>> f) { + public final IO flatMap(Fn1>> f) { @SuppressWarnings("unchecked") IO source = (IO) this; @SuppressWarnings({"unchecked", "RedundantCast"}) - Function> flatMap = (Function>) (Object) f; + Fn1> flatMap = (Fn1>) (Object) f; return new Compose<>(source, Choice2.b(flatMap)); } @@ -187,7 +189,7 @@ public static IO io(Fn0 fn0) { return new IO() { @Override public A unsafePerformIO() { - return fn0.get(); + return fn0.apply(); } @Override @@ -198,13 +200,16 @@ public CompletableFuture unsafePerformAsyncIO(Executor executor) { } /** - * Static factory method for creating an {@link IO} that runs runnable and returns {@link Unit}. + * Static factory method for creating an {@link IO} that runs a {@link SideEffect} and returns {@link Unit}. * - * @param runnable the {@link Runnable} + * @param sideEffect the {@link SideEffect} * @return the {@link IO} */ - public static IO io(Runnable runnable) { - return io(fn0(runnable)); + public static IO io(SideEffect sideEffect) { + return io(fn0(() -> { + sideEffect.Ω(); + return UNIT; + })); } /** @@ -228,17 +233,16 @@ public A unsafePerformIO() { @Override public CompletableFuture unsafePerformAsyncIO(Executor executor) { - return supplier.get(); + return supplier.apply(); } }; } private static final class Compose extends IO { - private final IO source; - private final Choice2>, Function>> composition; + private final IO source; + private final Choice2>, Fn1>> composition; - private Compose(IO source, - Choice2>, Function>> composition) { + private Compose(IO source, Choice2>, Fn1>> composition) { this.source = source; this.composition = composition; } @@ -269,7 +273,8 @@ public CompletableFuture unsafePerformAsyncIO(Executor executor) { CompletableFuture future = (CompletableFuture) deforest(new LinkedList<>()) .into((source, compositions) -> foldLeft( (io, composition) -> composition - .match(zip -> zip.unsafePerformAsyncIO(executor).thenCompose(io::thenApply), + .match(zip -> zip.unsafePerformAsyncIO(executor) + .thenCompose(f -> io.thenApply(f.toFunction())), flatMap -> io.thenComposeAsync(obj -> flatMap.apply(obj) .unsafePerformAsyncIO(executor))), source.unsafePerformAsyncIO(executor), @@ -277,9 +282,9 @@ public CompletableFuture unsafePerformAsyncIO(Executor executor) { return future; } - private Tuple2, LinkedList>, Function>>>> - deforest(LinkedList>, Function>>> branches) { - Tuple2, LinkedList>, Function>>>> args = + private Tuple2, LinkedList>, Fn1>>>> + deforest(LinkedList>, Fn1>>> branches) { + Tuple2, LinkedList>, Fn1>>>> args = tuple(this, branches); return trampoline(into((source, compositions) -> { IO leaf = source.source; diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/ConsingIterator.java b/src/main/java/com/jnape/palatable/lambda/iteration/ConsingIterator.java index d35d92c0b..5198f66f7 100644 --- a/src/main/java/com/jnape/palatable/lambda/iteration/ConsingIterator.java +++ b/src/main/java/com/jnape/palatable/lambda/iteration/ConsingIterator.java @@ -1,15 +1,16 @@ package com.jnape.palatable.lambda.iteration; +import com.jnape.palatable.lambda.functions.Fn0; + import java.util.Iterator; import java.util.NoSuchElementException; -import java.util.function.Supplier; public final class ConsingIterator implements Iterator { - private final A head; - private final Supplier> asSupplier; - private Iterator asIterator; - private boolean iteratedHead; + private final A head; + private final Fn0> asSupplier; + private Iterator asIterator; + private boolean iteratedHead; public ConsingIterator(A head, Iterable as) { this.head = head; @@ -23,7 +24,7 @@ public boolean hasNext() { return true; if (asIterator == null) - asIterator = asSupplier.get(); + asIterator = asSupplier.apply(); return asIterator.hasNext(); } diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/FilteringIterable.java b/src/main/java/com/jnape/palatable/lambda/iteration/FilteringIterable.java index 1b9f315ff..7503e152a 100644 --- a/src/main/java/com/jnape/palatable/lambda/iteration/FilteringIterable.java +++ b/src/main/java/com/jnape/palatable/lambda/iteration/FilteringIterable.java @@ -1,19 +1,20 @@ package com.jnape.palatable.lambda.iteration; +import com.jnape.palatable.lambda.functions.Fn1; + import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import java.util.function.Function; import static com.jnape.palatable.lambda.functions.builtin.fn2.All.all; import static java.util.Collections.singletonList; public final class FilteringIterable implements Iterable { - private final List> predicates; - private final Iterable as; + private final List> predicates; + private final Iterable as; - public FilteringIterable(Function predicate, Iterable as) { - List> predicates = new ArrayList<>(singletonList(predicate)); + public FilteringIterable(Fn1 predicate, Iterable as) { + List> predicates = new ArrayList<>(singletonList(predicate)); while (as instanceof FilteringIterable) { FilteringIterable nested = (FilteringIterable) as; predicates.addAll(0, nested.predicates); @@ -25,7 +26,7 @@ public FilteringIterable(Function predicate, Itera @Override public Iterator iterator() { - Function metaPredicate = a -> all(p -> p.apply(a), predicates); + Fn1 metaPredicate = a -> all(p -> p.apply(a), predicates); return new FilteringIterator<>(metaPredicate, as.iterator()); } } diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/FilteringIterator.java b/src/main/java/com/jnape/palatable/lambda/iteration/FilteringIterator.java index 5b9358c01..d283a1129 100644 --- a/src/main/java/com/jnape/palatable/lambda/iteration/FilteringIterator.java +++ b/src/main/java/com/jnape/palatable/lambda/iteration/FilteringIterator.java @@ -1,15 +1,16 @@ package com.jnape.palatable.lambda.iteration; +import com.jnape.palatable.lambda.functions.Fn1; + import java.util.Iterator; import java.util.NoSuchElementException; -import java.util.function.Function; public final class FilteringIterator extends ImmutableIterator { - private final Function predicate; - private final RewindableIterator rewindableIterator; + private final Fn1 predicate; + private final RewindableIterator rewindableIterator; - public FilteringIterator(Function predicate, Iterator iterator) { + public FilteringIterator(Fn1 predicate, Iterator iterator) { this.predicate = predicate; rewindableIterator = new RewindableIterator<>(iterator); } diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/MappingIterable.java b/src/main/java/com/jnape/palatable/lambda/iteration/MappingIterable.java index b65510f55..4bffb3b3d 100644 --- a/src/main/java/com/jnape/palatable/lambda/iteration/MappingIterable.java +++ b/src/main/java/com/jnape/palatable/lambda/iteration/MappingIterable.java @@ -1,20 +1,21 @@ package com.jnape.palatable.lambda.iteration; +import com.jnape.palatable.lambda.functions.Fn1; + import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import java.util.function.Function; import static com.jnape.palatable.lambda.functions.builtin.fn3.FoldLeft.foldLeft; import static java.util.Collections.singletonList; public final class MappingIterable implements Iterable { - private final Iterable as; - private final List> mappers; + private final Iterable as; + private final List> mappers; @SuppressWarnings("unchecked") - public MappingIterable(Function fn, Iterable as) { - List> mappers = new ArrayList<>(singletonList(fn)); + public MappingIterable(Fn1 fn, Iterable as) { + List> mappers = new ArrayList<>(singletonList(fn)); while (as instanceof MappingIterable) { MappingIterable nested = (MappingIterable) as; as = (Iterable) nested.as; @@ -27,8 +28,8 @@ public MappingIterable(Function fn, Iterable as) { @Override @SuppressWarnings("unchecked") public Iterator iterator() { - Function fnComposedOnTheHeap = a -> foldLeft((x, fn) -> ((Function) fn).apply(x), - a, mappers); - return new MappingIterator<>((Function) fnComposedOnTheHeap, as.iterator()); + Fn1 fnComposedOnTheHeap = a -> foldLeft((x, fn) -> ((Fn1) fn).apply(x), + a, mappers); + return new MappingIterator<>((Fn1) fnComposedOnTheHeap, as.iterator()); } } diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/MappingIterator.java b/src/main/java/com/jnape/palatable/lambda/iteration/MappingIterator.java index 0d336fa89..ed13cf281 100644 --- a/src/main/java/com/jnape/palatable/lambda/iteration/MappingIterator.java +++ b/src/main/java/com/jnape/palatable/lambda/iteration/MappingIterator.java @@ -1,14 +1,15 @@ package com.jnape.palatable.lambda.iteration; +import com.jnape.palatable.lambda.functions.Fn1; + import java.util.Iterator; -import java.util.function.Function; public final class MappingIterator extends ImmutableIterator { - private final Function function; - private final Iterator iterator; + private final Fn1 function; + private final Iterator iterator; - public MappingIterator(Function function, Iterator iterator) { + public MappingIterator(Fn1 function, Iterator iterator) { this.function = function; this.iterator = iterator; } diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/PredicatedDroppingIterable.java b/src/main/java/com/jnape/palatable/lambda/iteration/PredicatedDroppingIterable.java index bd3aa87b6..591e561f5 100644 --- a/src/main/java/com/jnape/palatable/lambda/iteration/PredicatedDroppingIterable.java +++ b/src/main/java/com/jnape/palatable/lambda/iteration/PredicatedDroppingIterable.java @@ -1,20 +1,20 @@ package com.jnape.palatable.lambda.iteration; +import com.jnape.palatable.lambda.functions.Fn1; + import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import java.util.function.Function; import static com.jnape.palatable.lambda.functions.builtin.fn2.Any.any; import static java.util.Collections.singletonList; public final class PredicatedDroppingIterable implements Iterable { - private final List> predicates; - private final Iterable as; - - public PredicatedDroppingIterable(Function predicate, Iterable as) { - List> predicates = new ArrayList<>(singletonList(predicate)); + private final List> predicates; + private final Iterable as; + public PredicatedDroppingIterable(Fn1 predicate, Iterable as) { + List> predicates = new ArrayList<>(singletonList(predicate)); while (as instanceof PredicatedDroppingIterable) { PredicatedDroppingIterable nested = (PredicatedDroppingIterable) as; as = nested.as; @@ -26,7 +26,7 @@ public PredicatedDroppingIterable(Function predica @Override public Iterator iterator() { - Function metaPredicate = a -> any(p -> p.apply(a), predicates); + Fn1 metaPredicate = a -> any(p -> p.apply(a), predicates); return new PredicatedDroppingIterator<>(metaPredicate, as.iterator()); } } diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/PredicatedDroppingIterator.java b/src/main/java/com/jnape/palatable/lambda/iteration/PredicatedDroppingIterator.java index 7fe16c64b..8bbba7783 100644 --- a/src/main/java/com/jnape/palatable/lambda/iteration/PredicatedDroppingIterator.java +++ b/src/main/java/com/jnape/palatable/lambda/iteration/PredicatedDroppingIterator.java @@ -1,15 +1,16 @@ package com.jnape.palatable.lambda.iteration; +import com.jnape.palatable.lambda.functions.Fn1; + import java.util.Iterator; import java.util.NoSuchElementException; -import java.util.function.Function; public final class PredicatedDroppingIterator extends ImmutableIterator { - private final Function predicate; - private final RewindableIterator rewindableIterator; - private boolean finishedDropping; + private final Fn1 predicate; + private final RewindableIterator rewindableIterator; + private boolean finishedDropping; - public PredicatedDroppingIterator(Function predicate, Iterator asIterator) { + public PredicatedDroppingIterator(Fn1 predicate, Iterator asIterator) { this.predicate = predicate; rewindableIterator = new RewindableIterator<>(asIterator); finishedDropping = false; diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/PredicatedTakingIterable.java b/src/main/java/com/jnape/palatable/lambda/iteration/PredicatedTakingIterable.java index 14201849d..8a612fa11 100644 --- a/src/main/java/com/jnape/palatable/lambda/iteration/PredicatedTakingIterable.java +++ b/src/main/java/com/jnape/palatable/lambda/iteration/PredicatedTakingIterable.java @@ -1,19 +1,20 @@ package com.jnape.palatable.lambda.iteration; +import com.jnape.palatable.lambda.functions.Fn1; + import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import java.util.function.Function; import static com.jnape.palatable.lambda.functions.builtin.fn2.All.all; import static java.util.Collections.singletonList; public final class PredicatedTakingIterable implements Iterable { - private final List> predicates; - private final Iterable as; + private final List> predicates; + private final Iterable as; - public PredicatedTakingIterable(Function predicate, Iterable as) { - List> predicates = new ArrayList<>(singletonList(predicate)); + public PredicatedTakingIterable(Fn1 predicate, Iterable as) { + List> predicates = new ArrayList<>(singletonList(predicate)); while (as instanceof PredicatedTakingIterable) { PredicatedTakingIterable nested = (PredicatedTakingIterable) as; predicates.addAll(0, nested.predicates); @@ -25,7 +26,7 @@ public PredicatedTakingIterable(Function predicate @Override public Iterator iterator() { - Function metaPredicate = a -> all(p -> p.apply(a), predicates); + Fn1 metaPredicate = a -> all(p -> p.apply(a), predicates); return new PredicatedTakingIterator<>(metaPredicate, as.iterator()); } } diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/PredicatedTakingIterator.java b/src/main/java/com/jnape/palatable/lambda/iteration/PredicatedTakingIterator.java index 370ef1e84..6d228ae85 100644 --- a/src/main/java/com/jnape/palatable/lambda/iteration/PredicatedTakingIterator.java +++ b/src/main/java/com/jnape/palatable/lambda/iteration/PredicatedTakingIterator.java @@ -1,16 +1,16 @@ package com.jnape.palatable.lambda.iteration; +import com.jnape.palatable.lambda.functions.Fn1; + import java.util.Iterator; import java.util.NoSuchElementException; -import java.util.function.Function; public final class PredicatedTakingIterator extends ImmutableIterator { - private final Function predicate; - private final RewindableIterator rewindableIterator; - private boolean stillTaking; + private final Fn1 predicate; + private final RewindableIterator rewindableIterator; + private boolean stillTaking; - public PredicatedTakingIterator(Function predicate, - Iterator asIterator) { + public PredicatedTakingIterator(Fn1 predicate, Iterator asIterator) { this.predicate = predicate; rewindableIterator = new RewindableIterator<>(asIterator); stillTaking = true; diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/RateLimitingIterable.java b/src/main/java/com/jnape/palatable/lambda/iteration/RateLimitingIterable.java index 27427b2cb..63bb5611f 100644 --- a/src/main/java/com/jnape/palatable/lambda/iteration/RateLimitingIterable.java +++ b/src/main/java/com/jnape/palatable/lambda/iteration/RateLimitingIterable.java @@ -1,6 +1,7 @@ package com.jnape.palatable.lambda.iteration; import com.jnape.palatable.lambda.adt.hlist.Tuple3; +import com.jnape.palatable.lambda.functions.Fn0; import java.time.Duration; import java.time.Instant; @@ -10,11 +11,11 @@ import java.util.function.Supplier; public final class RateLimitingIterable implements Iterable { - private final Iterable as; - private final Set>> rateLimits; + private final Iterable as; + private final Set>> rateLimits; - public RateLimitingIterable(Iterable as, Set>> rateLimits) { - Set>> combinedRateLimits = new HashSet<>(rateLimits); + public RateLimitingIterable(Iterable as, Set>> rateLimits) { + Set>> combinedRateLimits = new HashSet<>(rateLimits); if (as instanceof RateLimitingIterable) { RateLimitingIterable inner = (RateLimitingIterable) as; combinedRateLimits.addAll(inner.rateLimits); diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/RateLimitingIterator.java b/src/main/java/com/jnape/palatable/lambda/iteration/RateLimitingIterator.java index 510c95d91..057106dd9 100644 --- a/src/main/java/com/jnape/palatable/lambda/iteration/RateLimitingIterator.java +++ b/src/main/java/com/jnape/palatable/lambda/iteration/RateLimitingIterator.java @@ -2,6 +2,7 @@ import com.jnape.palatable.lambda.adt.Try; import com.jnape.palatable.lambda.adt.hlist.Tuple3; +import com.jnape.palatable.lambda.functions.Fn0; import java.time.Duration; import java.time.Instant; @@ -12,7 +13,6 @@ import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; -import java.util.function.Supplier; import static com.jnape.palatable.lambda.adt.Try.failure; import static com.jnape.palatable.lambda.adt.Try.trying; @@ -27,11 +27,11 @@ import static java.util.Collections.emptyList; public final class RateLimitingIterator implements Iterator { - private final Iterator asIterator; - private final Set>> rateLimits; - private final Map>, List> timeSlicesByRateLimit; + private final Iterator asIterator; + private final Set>> rateLimits; + private final Map>, List> timeSlicesByRateLimit; - public RateLimitingIterator(Iterator asIterator, Set>> rateLimits) { + public RateLimitingIterator(Iterator asIterator, Set>> rateLimits) { this.asIterator = asIterator; this.rateLimits = rateLimits; timeSlicesByRateLimit = new HashMap<>(); @@ -54,12 +54,12 @@ private void awaitNextTimeSlice() { rateLimits.forEach(rateLimit -> { awaitNextTimeSliceForRateLimit(rateLimit); List timeSlicesForRateLimit = timeSlicesByRateLimit.getOrDefault(rateLimit, new ArrayList<>()); - timeSlicesForRateLimit.add(rateLimit._3().get()); + timeSlicesForRateLimit.add(rateLimit._3().apply()); timeSlicesByRateLimit.put(rateLimit, timeSlicesForRateLimit); }); } - private void awaitNextTimeSliceForRateLimit(Tuple3> rateLimit) { + private void awaitNextTimeSliceForRateLimit(Tuple3> rateLimit) { while (rateLimitExhaustedInTimeSlice(rateLimit)) { join(trying(() -> sleep(0)) .fmap(Try::success) @@ -68,12 +68,12 @@ private void awaitNextTimeSliceForRateLimit(Tuple3> rateLimit) { + private boolean rateLimitExhaustedInTimeSlice(Tuple3> rateLimit) { List timeSlicesForRateLimit = timeSlicesByRateLimit.getOrDefault(rateLimit, emptyList()); return rateLimit.into((limit, duration, instantSupplier) -> { - Instant timeSliceEnd = instantSupplier.get(); + Instant timeSliceEnd = instantSupplier.apply(); Instant previousTimeSliceEnd = timeSliceEnd.minus(duration); - timeSlicesForRateLimit.removeIf(lt(previousTimeSliceEnd)); + timeSlicesForRateLimit.removeIf(lt(previousTimeSliceEnd).toPredicate()); return max(0L, limit - size(filter(mark -> lte(mark, previousTimeSliceEnd) && gte(mark, timeSliceEnd), timeSlicesForRateLimit))) == 0; }); } diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/ScanningIterator.java b/src/main/java/com/jnape/palatable/lambda/iteration/ScanningIterator.java index d195b14b3..187982cca 100644 --- a/src/main/java/com/jnape/palatable/lambda/iteration/ScanningIterator.java +++ b/src/main/java/com/jnape/palatable/lambda/iteration/ScanningIterator.java @@ -1,16 +1,17 @@ package com.jnape.palatable.lambda.iteration; +import com.jnape.palatable.lambda.functions.Fn2; + import java.util.Iterator; import java.util.NoSuchElementException; -import java.util.function.BiFunction; public final class ScanningIterator extends ImmutableIterator { - private final BiFunction scanner; - private final Iterator asIterator; - private B b; + private final Fn2 scanner; + private final Iterator asIterator; + private B b; - public ScanningIterator(BiFunction scanner, B b, + public ScanningIterator(Fn2 scanner, B b, Iterator asIterator) { this.scanner = scanner; this.b = b; diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/UnfoldingIterator.java b/src/main/java/com/jnape/palatable/lambda/iteration/UnfoldingIterator.java index 0d014df81..146b19126 100644 --- a/src/main/java/com/jnape/palatable/lambda/iteration/UnfoldingIterator.java +++ b/src/main/java/com/jnape/palatable/lambda/iteration/UnfoldingIterator.java @@ -2,18 +2,18 @@ import com.jnape.palatable.lambda.adt.Maybe; import com.jnape.palatable.lambda.adt.hlist.Tuple2; +import com.jnape.palatable.lambda.functions.Fn1; import java.util.NoSuchElementException; -import java.util.function.Function; import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; public final class UnfoldingIterator extends ImmutableIterator { - private final Function>> function; - private B seed; - private Maybe> maybeAcc; + private final Fn1>> function; + private B seed; + private Maybe> maybeAcc; - public UnfoldingIterator(Function>> function, B seed) { + public UnfoldingIterator(Fn1>> function, B seed) { this.function = function; this.seed = seed; } @@ -31,8 +31,8 @@ public A next() { if (!hasNext()) throw new NoSuchElementException(); - Tuple2 acc = maybeAcc.orElseThrow(NoSuchElementException::new); - A next = acc._1(); + Tuple2 acc = maybeAcc.orElseThrow(NoSuchElementException::new); + A next = acc._1(); seed = acc._2(); maybeAcc = null; return next; diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/ZippingIterator.java b/src/main/java/com/jnape/palatable/lambda/iteration/ZippingIterator.java index 1b0909fd4..20175de5c 100644 --- a/src/main/java/com/jnape/palatable/lambda/iteration/ZippingIterator.java +++ b/src/main/java/com/jnape/palatable/lambda/iteration/ZippingIterator.java @@ -1,14 +1,15 @@ package com.jnape.palatable.lambda.iteration; +import com.jnape.palatable.lambda.functions.Fn2; + import java.util.Iterator; -import java.util.function.BiFunction; public final class ZippingIterator extends ImmutableIterator { - private final BiFunction zipper; - private final Iterator asIterator; - private final Iterator bsIterator; + private final Fn2 zipper; + private final Iterator asIterator; + private final Iterator bsIterator; - public ZippingIterator(BiFunction zipper, Iterator asIterator, + public ZippingIterator(Fn2 zipper, Iterator asIterator, Iterator bsIterator) { this.asIterator = asIterator; this.bsIterator = bsIterator; diff --git a/src/main/java/com/jnape/palatable/lambda/monad/Monad.java b/src/main/java/com/jnape/palatable/lambda/monad/Monad.java index 00aca101c..769218304 100644 --- a/src/main/java/com/jnape/palatable/lambda/monad/Monad.java +++ b/src/main/java/com/jnape/palatable/lambda/monad/Monad.java @@ -1,17 +1,16 @@ package com.jnape.palatable.lambda.monad; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functions.builtin.fn1.Id; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.builtin.Lazy; -import java.util.function.Function; - import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id; /** * Monads are {@link Applicative} functors that support a flattening operation to unwrap M<M<A>> * -> M<A>. This flattening operation, coupled with {@link Applicative#zip(Applicative)}, gives rise to - * {@link Monad#flatMap(Function)}, a binding operation that maps the carrier value to a new monad instance in the same + * {@link Monad#flatMap(Fn1)}, a binding operation that maps the carrier value to a new monad instance in the same * category, and then unwraps the outer layer. *

* In addition to the applicative laws, there are 3 specific monad laws that monads should obey: @@ -36,7 +35,7 @@ public interface Monad> extends Applicative { * @param the resulting monad parameter type * @return the new monad instance */ - Monad flatMap(Function> f); + Monad flatMap(Fn1> f); /** * {@inheritDoc} @@ -48,16 +47,16 @@ public interface Monad> extends Applicative { * {@inheritDoc} */ @Override - default Monad fmap(Function fn) { - return flatMap(fn.andThen(this::pure)); + default Monad fmap(Fn1 fn) { + return flatMap(fn.fmap(this::pure)); } /** * {@inheritDoc} */ @Override - default Monad zip(Applicative, M> appFn) { - return appFn., M>>coerce().flatMap(this::fmap); + default Monad zip(Applicative, M> appFn) { + return appFn., M>>coerce().flatMap(this::fmap); } /** @@ -65,7 +64,7 @@ default Monad zip(Applicative, M> app */ @Override default Lazy> lazyZip( - Lazy, M>> lazyAppFn) { + Lazy, M>> lazyAppFn) { return Applicative.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); } @@ -86,7 +85,7 @@ default Monad discardR(Applicative appB) { } /** - * Convenience static method equivalent to {@link Monad#flatMap(Function) flatMap}{@link Id#id() (id())}; + * Convenience static method equivalent to {@link Monad#flatMap(Fn1) flatMap}{@link Id#id() (id())}; * * @param mma the outer monad * @param the monad type diff --git a/src/main/java/com/jnape/palatable/lambda/monad/transformer/MonadT.java b/src/main/java/com/jnape/palatable/lambda/monad/transformer/MonadT.java index 1afb4d426..e95bdd68d 100644 --- a/src/main/java/com/jnape/palatable/lambda/monad/transformer/MonadT.java +++ b/src/main/java/com/jnape/palatable/lambda/monad/transformer/MonadT.java @@ -1,5 +1,6 @@ package com.jnape.palatable.lambda.monad.transformer; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.monad.Monad; @@ -14,9 +15,9 @@ * {@link Applicative applicatives} can be composed in general, the same is not true in general of any two * {@link Monad monads}. However, there exist {@link Monad monads} that do compose, in general, with any other * {@link Monad}, provided that they are embedded inside the other {@link Monad}. When this is the case, they can offer - * implementations of {@link Monad#pure pure} and {@link Monad#flatMap(Function) flatMap} for free, simply by relying + * implementations of {@link Monad#pure pure} and {@link Monad#flatMap(Fn1) flatMap} for free, simply by relying * on the outer {@link Monad monad's} implementation of both, as well as their own privileged knowledge about how to - * merge the nested {@link Monad#flatMap(Function) flatMap} call. + * merge the nested {@link Monad#flatMap(Fn1) flatMap} call. *

* The term "monad transformer" describes a particular encoding of monadic composition. Because this general composition * of a particular {@link Monad} with any other {@link Monad} relies on privileged knowledge about the embedded @@ -51,7 +52,7 @@ public interface MonadT, G extends Monad, A> * {@inheritDoc} */ @Override - MonadT flatMap(Function>> f); + MonadT flatMap(Fn1>> f); /** * {@inheritDoc} @@ -63,7 +64,7 @@ public interface MonadT, G extends Monad, A> * {@inheritDoc} */ @Override - default MonadT fmap(Function fn) { + default MonadT fmap(Fn1 fn) { return Monad.super.fmap(fn).coerce(); } @@ -71,7 +72,7 @@ default MonadT fmap(Function fn) { * {@inheritDoc} */ @Override - default MonadT zip(Applicative, MonadT> appFn) { + default MonadT zip(Applicative, MonadT> appFn) { return Monad.super.zip(appFn).coerce(); } @@ -80,7 +81,7 @@ default MonadT zip(Applicative, Mo */ @Override default Lazy> lazyZip( - Lazy, MonadT>> lazyAppFn) { + Lazy, MonadT>> lazyAppFn) { return Monad.super.lazyZip(lazyAppFn).fmap(Monad>::coerce); } diff --git a/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/EitherT.java b/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/EitherT.java index 3b23327d9..d8a139f39 100644 --- a/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/EitherT.java +++ b/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/EitherT.java @@ -1,6 +1,7 @@ package com.jnape.palatable.lambda.monad.transformer.builtin; import com.jnape.palatable.lambda.adt.Either; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.builtin.Compose; import com.jnape.palatable.lambda.functor.builtin.Lazy; @@ -8,7 +9,6 @@ import com.jnape.palatable.lambda.monad.transformer.MonadT; import java.util.Objects; -import java.util.function.Function; import static com.jnape.palatable.lambda.adt.Either.left; import static com.jnape.palatable.lambda.adt.Either.right; @@ -40,7 +40,7 @@ private EitherT(Monad, M> melr) { * {@inheritDoc} */ @Override - public EitherT flatMap(Function, ?>>> f) { + public EitherT flatMap(Fn1, ?>>> f) { return eitherT(melr.flatMap(lr -> lr.match(l -> melr.pure(left(l)), r -> f.apply(r).>coerce().run()))); } @@ -57,7 +57,7 @@ public EitherT pure(R2 r2) { * {@inheritDoc} */ @Override - public EitherT fmap(Function fn) { + public EitherT fmap(Fn1 fn) { return MonadT.super.fmap(fn).coerce(); } @@ -66,7 +66,7 @@ public EitherT fmap(Function fn) { */ @Override public EitherT zip( - Applicative, MonadT, ?>> appFn) { + Applicative, MonadT, ?>> appFn) { return MonadT.super.zip(appFn).coerce(); } @@ -75,12 +75,12 @@ public EitherT zip( */ @Override public Lazy> lazyZip( - Lazy, MonadT, ?>>> lazyAppFn) { + Lazy, MonadT, ?>>> lazyAppFn) { return new Compose<>(melr) .lazyZip(lazyAppFn.fmap(maybeT -> new Compose<>( - maybeT.>>coerce() - .>, - Monad>, M>>run()))) + maybeT.>>coerce() + .>, + Monad>, M>>run()))) .fmap(compose -> eitherT(compose.getCompose())); } diff --git a/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/IdentityT.java b/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/IdentityT.java index 932680c8b..26ffffb51 100644 --- a/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/IdentityT.java +++ b/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/IdentityT.java @@ -1,5 +1,6 @@ package com.jnape.palatable.lambda.monad.transformer.builtin; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.builtin.Compose; import com.jnape.palatable.lambda.functor.builtin.Identity; @@ -36,7 +37,7 @@ public >, FGA extends Monad> FGA run() { * {@inheritDoc} */ @Override - public IdentityT flatMap(Function, ?>>> f) { + public IdentityT flatMap(Fn1, ?>>> f) { return identityT(mia.flatMap(identityA -> f.apply(identityA.runIdentity()).>coerce().run())); } @@ -52,7 +53,7 @@ public IdentityT pure(B b) { * {@inheritDoc} */ @Override - public IdentityT fmap(Function fn) { + public IdentityT fmap(Fn1 fn) { return MonadT.super.fmap(fn).coerce(); } @@ -60,7 +61,7 @@ public IdentityT fmap(Function fn) { * {@inheritDoc} */ @Override - public IdentityT zip(Applicative, MonadT, ?>> appFn) { + public IdentityT zip(Applicative, MonadT, ?>> appFn) { return MonadT.super.zip(appFn).coerce(); } @@ -69,12 +70,12 @@ public IdentityT zip(Applicative, Mon */ @Override public Lazy> lazyZip( - Lazy, MonadT, ?>>> lazyAppFn) { + Lazy, MonadT, ?>>> lazyAppFn) { return new Compose<>(mia) .lazyZip(lazyAppFn.fmap(maybeT -> new Compose<>( - maybeT.>>coerce() - .>, - Monad>, M>>run()))) + maybeT.>>coerce() + .>, + Monad>, M>>run()))) .fmap(compose -> identityT(compose.getCompose())); } diff --git a/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/LazyT.java b/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/LazyT.java index fe10e8142..d35ddc215 100644 --- a/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/LazyT.java +++ b/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/LazyT.java @@ -1,5 +1,6 @@ package com.jnape.palatable.lambda.monad.transformer.builtin; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Functor; import com.jnape.palatable.lambda.functor.builtin.Compose; @@ -8,12 +9,11 @@ import com.jnape.palatable.lambda.monad.transformer.MonadT; import java.util.Objects; -import java.util.function.Function; import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; /** - * A {@link MonadT monad transformer} for {@link Lazy}. Note that {@link LazyT#flatMap(Function)} must force its value. + * A {@link MonadT monad transformer} for {@link Lazy}. Note that {@link LazyT#flatMap(Fn1)} must force its value. * * @param the outer {@link Monad} * @param the carrier type @@ -38,7 +38,7 @@ public >, FGA extends Monad> FGA run() { * {@inheritDoc} */ @Override - public LazyT flatMap(Function, ?>>> f) { + public LazyT flatMap(Fn1, ?>>> f) { return new LazyT<>(mla.flatMap(lazyA -> f.apply(lazyA.value())., B>>coerce().run())); } @@ -54,7 +54,7 @@ public LazyT pure(B b) { * {@inheritDoc} */ @Override - public LazyT fmap(Function fn) { + public LazyT fmap(Fn1 fn) { return MonadT.super.fmap(fn).coerce(); } @@ -62,7 +62,7 @@ public LazyT fmap(Function fn) { * {@inheritDoc} */ @Override - public LazyT zip(Applicative, MonadT, ?>> appFn) { + public LazyT zip(Applicative, MonadT, ?>> appFn) { return MonadT.super.zip(appFn).coerce(); } @@ -71,12 +71,12 @@ public LazyT zip(Applicative, MonadT< */ @Override public Lazy> lazyZip( - Lazy, MonadT, ?>>> lazyAppFn) { + Lazy, MonadT, ?>>> lazyAppFn) { return new Compose<>(mla) .lazyZip(lazyAppFn.fmap(lazyT -> new Compose<>( - lazyT.>>coerce() - .>, - Monad>, M>>run()))) + lazyT.>>coerce() + .>, + Monad>, M>>run()))) .fmap(compose -> lazyT(compose.getCompose())); } diff --git a/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/MaybeT.java b/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/MaybeT.java index f7d72406a..7f1cf151f 100644 --- a/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/MaybeT.java +++ b/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/MaybeT.java @@ -1,6 +1,7 @@ package com.jnape.palatable.lambda.monad.transformer.builtin; import com.jnape.palatable.lambda.adt.Maybe; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.builtin.Compose; import com.jnape.palatable.lambda.functor.builtin.Lazy; @@ -8,7 +9,6 @@ import com.jnape.palatable.lambda.monad.transformer.MonadT; import java.util.Objects; -import java.util.function.Function; import static com.jnape.palatable.lambda.adt.Maybe.just; import static com.jnape.palatable.lambda.adt.Maybe.nothing; @@ -40,7 +40,7 @@ public >, FGA extends Monad> FGA run() { * {@inheritDoc} */ @Override - public MaybeT fmap(Function fn) { + public MaybeT fmap(Fn1 fn) { return MonadT.super.fmap(fn).coerce(); } @@ -56,7 +56,7 @@ public MaybeT pure(B b) { * {@inheritDoc} */ @Override - public MaybeT zip(Applicative, MonadT, ?>> appFn) { + public MaybeT zip(Applicative, MonadT, ?>> appFn) { return MonadT.super.zip(appFn).coerce(); } @@ -65,10 +65,11 @@ public MaybeT zip(Applicative, MonadT */ @Override public Lazy> lazyZip( - Lazy, MonadT, ?>>> lazyAppFn) { + Lazy, MonadT, ?>>> lazyAppFn) { return new Compose<>(mma) .lazyZip(lazyAppFn.fmap(maybeT -> new Compose<>( - maybeT.>>coerce().>, Monad>, M>>run()))) + maybeT.>>coerce() + .>, Monad>, M>>run()))) .fmap(compose -> maybeT(compose.getCompose())); } @@ -76,7 +77,7 @@ public Lazy> lazyZip( * {@inheritDoc} */ @Override - public MaybeT flatMap(Function, ?>>> f) { + public MaybeT flatMap(Fn1, ?>>> f) { return maybeT(mma.flatMap(ma -> ma .match(constantly(mma.pure(nothing())), a -> f.apply(a).>coerce().run()))); diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/Monoid.java b/src/main/java/com/jnape/palatable/lambda/monoid/Monoid.java index 3ff2d3e0b..8ecf83775 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/Monoid.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/Monoid.java @@ -1,5 +1,7 @@ package com.jnape.palatable.lambda.monoid; +import com.jnape.palatable.lambda.functions.Fn0; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functions.builtin.fn2.Map; import com.jnape.palatable.lambda.functions.builtin.fn2.ReduceLeft; import com.jnape.palatable.lambda.functions.builtin.fn2.ReduceRight; @@ -7,9 +9,6 @@ import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.semigroup.Semigroup; -import java.util.function.Function; -import java.util.function.Supplier; - import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id; import static com.jnape.palatable.lambda.functions.builtin.fn1.Reverse.reverse; import static com.jnape.palatable.lambda.functions.builtin.fn2.Cons.cons; @@ -59,15 +58,15 @@ default A reduceRight(Iterable as) { * Iterable<A> (that is, an Iterable of elements this monoid is formed over), then * reduce the result from left to right. Under algebraic data types, this is isomorphic to a flatMap. * + * @param the input Iterable element type * @param fn the mapping function from A to B * @param bs the Iterable of Bs - * @param the input Iterable element type * @return the folded result under this Monoid * @see Map * @see Monoid#reduceLeft(Iterable) */ - default A foldMap(Function fn, Iterable bs) { - return FoldLeft.foldLeft(this.toBiFunction(), identity(), map(fn, bs)); + default A foldMap(Fn1 fn, Iterable bs) { + return FoldLeft.foldLeft(this, identity(), map(fn, bs)); } /** @@ -116,11 +115,11 @@ public A checkedApply(A x, A y) { }; } - static Monoid monoid(Semigroup semigroup, Supplier identitySupplier) { + static Monoid monoid(Semigroup semigroup, Fn0 identityFn0) { return new Monoid() { @Override public A identity() { - return identitySupplier.get(); + return identityFn0.apply(); } @Override diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/AddAll.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/AddAll.java index 383116e6d..219763fd3 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/AddAll.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/AddAll.java @@ -1,13 +1,12 @@ package com.jnape.palatable.lambda.monoid.builtin; +import com.jnape.palatable.lambda.functions.Fn0; import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functions.builtin.fn3.FoldLeft; import com.jnape.palatable.lambda.functions.specialized.MonoidFactory; import com.jnape.palatable.lambda.monoid.Monoid; import java.util.Collection; -import java.util.function.Function; -import java.util.function.Supplier; import static com.jnape.palatable.lambda.functions.builtin.fn2.Map.map; @@ -19,7 +18,7 @@ * * @see Monoid */ -public final class AddAll> implements MonoidFactory, C> { +public final class AddAll> implements MonoidFactory, C> { private static final AddAll INSTANCE = new AddAll<>(); @@ -27,11 +26,11 @@ private AddAll() { } @Override - public Monoid checkedApply(Supplier cSupplier) { + public Monoid checkedApply(Fn0 cFn0) { return new Monoid() { @Override public C identity() { - return cSupplier.get(); + return cFn0.apply(); } @Override @@ -43,7 +42,7 @@ public C checkedApply(C xs, C ys) { } @Override - public C foldMap(Function fn, Iterable bs) { + public C foldMap(Fn1 fn, Iterable bs) { return FoldLeft.foldLeft((x, y) -> { x.addAll(y); return x; @@ -57,15 +56,15 @@ public static > AddAll addAll() { return (AddAll) INSTANCE; } - public static > Monoid addAll(Supplier collectionSupplier) { - return AddAll.addAll().apply(collectionSupplier); + public static > Monoid addAll(Fn0 collectionFn0) { + return AddAll.addAll().apply(collectionFn0); } - public static > Fn1 addAll(Supplier collectionSupplier, C xs) { - return addAll(collectionSupplier).apply(xs); + public static > Fn1 addAll(Fn0 collectionFn0, C xs) { + return addAll(collectionFn0).apply(xs); } - public static > C addAll(Supplier collectionSupplier, C xs, C ys) { - return addAll(collectionSupplier, xs).apply(ys); + public static > C addAll(Fn0 collectionFn0, C xs, C ys) { + return addAll(collectionFn0, xs).apply(ys); } } diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/And.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/And.java index e47e67df4..2ce32994c 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/And.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/And.java @@ -4,8 +4,6 @@ import com.jnape.palatable.lambda.functions.specialized.BiPredicate; import com.jnape.palatable.lambda.monoid.Monoid; -import java.util.function.Function; - import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; import static com.jnape.palatable.lambda.functions.builtin.fn1.Not.not; import static com.jnape.palatable.lambda.functions.builtin.fn2.Find.find; @@ -34,15 +32,10 @@ public Boolean checkedApply(Boolean x, Boolean y) { } @Override - public Boolean foldMap(Function fn, Iterable bs) { + public Boolean foldMap(Fn1 fn, Iterable bs) { return find(not(fn), bs).fmap(constantly(false)).orElse(true); } - @Override - public boolean test(Boolean x, Boolean y) { - return apply(x, y); - } - @Override public And flip() { return this; diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Compose.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Compose.java index f9c53ed27..dbffbe748 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Compose.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Compose.java @@ -6,8 +6,8 @@ import com.jnape.palatable.lambda.semigroup.Semigroup; import java.util.concurrent.CompletableFuture; -import java.util.function.Supplier; +import static com.jnape.palatable.lambda.functions.Fn0.fn0; import static com.jnape.palatable.lambda.monoid.Monoid.monoid; import static java.util.concurrent.CompletableFuture.completedFuture; @@ -32,7 +32,7 @@ private Compose() { @Override public Monoid> checkedApply(Monoid aMonoid) { return monoid(com.jnape.palatable.lambda.semigroup.builtin.Compose.compose(aMonoid), - (Supplier>) () -> completedFuture(aMonoid.identity())); + fn0(() -> completedFuture(aMonoid.identity()))); } @SuppressWarnings("unchecked") diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Concat.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Concat.java index c02c09586..002834bd1 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Concat.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Concat.java @@ -5,7 +5,6 @@ import com.jnape.palatable.lambda.monoid.Monoid; import java.util.Collections; -import java.util.function.Function; import static com.jnape.palatable.lambda.functions.builtin.fn1.Flatten.flatten; import static com.jnape.palatable.lambda.functions.builtin.fn2.Map.map; @@ -33,7 +32,7 @@ public Iterable checkedApply(Iterable xs, Iterable ys) { } @Override - public Iterable foldMap(Function> fn, Iterable bs) { + public Iterable foldMap(Fn1> fn, Iterable bs) { return flatten(map(fn, bs)); } diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/First.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/First.java index 69b1e356c..9c44abca9 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/First.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/First.java @@ -4,8 +4,6 @@ import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.monoid.Monoid; -import java.util.function.Function; - import static com.jnape.palatable.lambda.adt.Maybe.nothing; import static com.jnape.palatable.lambda.functions.builtin.fn1.CatMaybes.catMaybes; import static com.jnape.palatable.lambda.functions.builtin.fn1.Head.head; @@ -39,7 +37,7 @@ public Maybe checkedApply(Maybe x, Maybe y) { } @Override - public Maybe foldMap(Function> fn, Iterable bs) { + public Maybe foldMap(Fn1> fn, Iterable bs) { return head(catMaybes(map(fn, bs))); } diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/MergeMaps.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/MergeMaps.java index 9f594df75..0f5c5fcc9 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/MergeMaps.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/MergeMaps.java @@ -1,5 +1,6 @@ package com.jnape.palatable.lambda.monoid.builtin; +import com.jnape.palatable.lambda.functions.Fn0; import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functions.specialized.BiMonoidFactory; import com.jnape.palatable.lambda.functions.specialized.MonoidFactory; @@ -8,7 +9,6 @@ import java.util.Map; import java.util.function.BiFunction; -import java.util.function.Supplier; /** * A {@link Monoid} instance formed by {@link java.util.Map#merge(Object, Object, BiFunction)} and a semigroup over @@ -19,7 +19,7 @@ * @see Monoid * @see java.util.Map */ -public final class MergeMaps implements BiMonoidFactory>, Semigroup, Map> { +public final class MergeMaps implements BiMonoidFactory>, Semigroup, Map> { private static final MergeMaps INSTANCE = new MergeMaps<>(); @@ -27,13 +27,13 @@ private MergeMaps() { } @Override - public Monoid> checkedApply(Supplier> mSupplier, Semigroup semigroup) { + public Monoid> checkedApply(Fn0> mFn0, Semigroup semigroup) { return Monoid.>monoid((x, y) -> { - Map copy = mSupplier.get(); + Map copy = mFn0.apply(); copy.putAll(x); y.forEach((k, v) -> copy.merge(k, v, semigroup.toBiFunction())); return copy; - }, mSupplier); + }, mFn0); } @SuppressWarnings("unchecked") @@ -41,21 +41,21 @@ public static MergeMaps mergeMaps() { return (MergeMaps) INSTANCE; } - public static MonoidFactory, Map> mergeMaps(Supplier> mSupplier) { - return MergeMaps.mergeMaps().apply(mSupplier); + public static MonoidFactory, Map> mergeMaps(Fn0> mFn0) { + return MergeMaps.mergeMaps().apply(mFn0); } - public static Monoid> mergeMaps(Supplier> mSupplier, Semigroup semigroup) { - return mergeMaps(mSupplier).apply(semigroup); + public static Monoid> mergeMaps(Fn0> mFn0, Semigroup semigroup) { + return mergeMaps(mFn0).apply(semigroup); } - public static Fn1, Map> mergeMaps(Supplier> mSupplier, Semigroup semigroup, + public static Fn1, Map> mergeMaps(Fn0> mFn0, Semigroup semigroup, Map x) { - return mergeMaps(mSupplier, semigroup).apply(x); + return mergeMaps(mFn0, semigroup).apply(x); } - public static Map mergeMaps(Supplier> mSupplier, Semigroup semigroup, Map x, + public static Map mergeMaps(Fn0> mFn0, Semigroup semigroup, Map x, Map y) { - return mergeMaps(mSupplier, semigroup, x).apply(y); + return mergeMaps(mFn0, semigroup, x).apply(y); } } diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Or.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Or.java index 90e57807d..84c45f5f4 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Or.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Or.java @@ -4,8 +4,6 @@ import com.jnape.palatable.lambda.functions.specialized.BiPredicate; import com.jnape.palatable.lambda.monoid.Monoid; -import java.util.function.Function; - import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; import static com.jnape.palatable.lambda.functions.builtin.fn2.Find.find; @@ -33,12 +31,7 @@ public Boolean checkedApply(Boolean x, Boolean y) { } @Override - public boolean test(Boolean x, Boolean y) { - return apply(x, y); - } - - @Override - public Boolean foldMap(Function fn, Iterable bs) { + public Boolean foldMap(Fn1 fn, Iterable bs) { return find(fn, bs).fmap(constantly(true)).orElse(false); } diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Xor.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Xor.java index 4e17c6e97..8ed724ad6 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Xor.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Xor.java @@ -30,11 +30,6 @@ public Boolean checkedApply(Boolean x, Boolean y) { return x ^ y; } - @Override - public boolean test(Boolean x, Boolean y) { - return apply(x, y); - } - @Override public Xor flip() { return this; diff --git a/src/main/java/com/jnape/palatable/lambda/optics/Iso.java b/src/main/java/com/jnape/palatable/lambda/optics/Iso.java index bcb0775d5..11fdd4345 100644 --- a/src/main/java/com/jnape/palatable/lambda/optics/Iso.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/Iso.java @@ -13,8 +13,6 @@ import com.jnape.palatable.lambda.optics.functions.Set; import com.jnape.palatable.lambda.optics.functions.View; -import java.util.function.Function; - import static com.jnape.palatable.lambda.functions.Fn1.fn1; import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id; @@ -97,7 +95,7 @@ default Iso mirror() { * {@inheritDoc} */ @Override - default Iso fmap(Function fn) { + default Iso fmap(Fn1 fn) { return Monad.super.fmap(fn).coerce(); } @@ -113,7 +111,7 @@ default Iso pure(U u) { * {@inheritDoc} */ @Override - default Iso zip(Applicative, Iso> appFn) { + default Iso zip(Applicative, Iso> appFn) { return Monad.super.zip(appFn).coerce(); } @@ -137,13 +135,13 @@ default Iso discardR(Applicative> appB) { * {@inheritDoc} */ @Override - default Iso flatMap(Function>> fn) { + default Iso flatMap(Fn1>> fn) { //noinspection RedundantTypeArguments return unIso().fmap(bt -> Fn2.fn2( - fn1(bt.andThen(fn.>andThen(Monad>::coerce)) - .andThen(Iso::unIso) - .andThen(Tuple2::_2) - .andThen(Fn1::fn1)))) + fn1(bt.fmap(fn.>fmap(Monad>::coerce)) + .fmap(Iso::unIso) + .fmap(Tuple2::_2) + .fmap(Fn1::fn1)))) .fmap(Fn2::uncurry) .fmap(bbu -> bbu.diMapL(Tuple2::fill)) .into(Iso::iso); @@ -153,7 +151,7 @@ default Iso flatMap(Function Iso diMapL(Function fn) { + default Iso diMapL(Fn1 fn) { return (Iso) Profunctor.super.diMapL(fn); } @@ -161,7 +159,7 @@ default Iso diMapL(Function fn) { * {@inheritDoc} */ @Override - default Iso diMapR(Function fn) { + default Iso diMapR(Fn1 fn) { return (Iso) Profunctor.super.diMapR(fn); } @@ -169,8 +167,8 @@ default Iso diMapR(Function fn) { * {@inheritDoc} */ @Override - default Iso diMap(Function lFn, - Function rFn) { + default Iso diMap(Fn1 lFn, + Fn1 rFn) { return this.mapS(lFn).mapT(rFn); } @@ -178,7 +176,7 @@ default Iso diMap(Function lFn, * {@inheritDoc} */ @Override - default Iso contraMap(Function fn) { + default Iso contraMap(Fn1 fn) { return (Iso) Profunctor.super.contraMap(fn); } @@ -186,7 +184,7 @@ default Iso contraMap(Function fn) { * {@inheritDoc} */ @Override - default Iso mapS(Function fn) { + default Iso mapS(Fn1 fn) { return iso(Optic.super.mapS(fn)); } @@ -194,7 +192,7 @@ default Iso mapS(Function fn) { * {@inheritDoc} */ @Override - default Iso mapT(Function fn) { + default Iso mapT(Fn1 fn) { return iso(Optic.super.mapT(fn)); } @@ -202,7 +200,7 @@ default Iso mapT(Function fn) { * {@inheritDoc} */ @Override - default Iso mapA(Function fn) { + default Iso mapA(Fn1 fn) { return iso(Optic.super.mapA(fn)); } @@ -210,7 +208,7 @@ default Iso mapA(Function fn) { * {@inheritDoc} */ @Override - default Iso mapB(Function fn) { + default Iso mapB(Fn1 fn) { return iso(Optic.super.mapB(fn)); } @@ -241,8 +239,7 @@ default Iso compose(Optic, ? supe * @param the smaller type for mirrored focusing * @return the iso */ - static Iso iso(Function f, - Function g) { + static Iso iso(Fn1 f, Fn1 g) { return iso(optic(pafb -> pafb.diMap(f, fb -> fb.fmap(g)))); } @@ -278,7 +275,7 @@ static Iso iso( * @param the other side of the isomorphism * @return the simple iso */ - static Iso.Simple simpleIso(Function f, Function g) { + static Iso.Simple simpleIso(Fn1 f, Fn1 g) { return adapt(iso(f, g)); } diff --git a/src/main/java/com/jnape/palatable/lambda/optics/Lens.java b/src/main/java/com/jnape/palatable/lambda/optics/Lens.java index 8b5746c75..48e16495c 100644 --- a/src/main/java/com/jnape/palatable/lambda/optics/Lens.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/Lens.java @@ -2,15 +2,13 @@ import com.jnape.palatable.lambda.adt.hlist.Tuple2; import com.jnape.palatable.lambda.functions.Fn1; +import com.jnape.palatable.lambda.functions.Fn2; import com.jnape.palatable.lambda.functions.builtin.fn2.Both; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Functor; import com.jnape.palatable.lambda.functor.Profunctor; import com.jnape.palatable.lambda.monad.Monad; -import java.util.function.BiFunction; -import java.util.function.Function; - import static com.jnape.palatable.lambda.optics.Iso.iso; import static com.jnape.palatable.lambda.optics.Lens.Simple.adapt; import static com.jnape.palatable.lambda.optics.functions.Set.set; @@ -148,7 +146,7 @@ public interface Lens extends * {@inheritDoc} */ @Override - default Lens fmap(Function fn) { + default Lens fmap(Fn1 fn) { return Monad.super.fmap(fn).coerce(); } @@ -164,7 +162,7 @@ default Lens pure(U u) { * {@inheritDoc} */ @Override - default Lens zip(Applicative, Lens> appFn) { + default Lens zip(Applicative, Lens> appFn) { return Monad.super.zip(appFn).coerce(); } @@ -188,7 +186,7 @@ default Lens discardR(Applicative> appB) { * {@inheritDoc} */ @Override - default Lens flatMap(Function>> f) { + default Lens flatMap(Fn1>> f) { return lens(view(this), (s, b) -> set(f.apply(set(this, b, s)).>coerce(), b, s)); } @@ -197,7 +195,7 @@ default Lens flatMap(Function Lens diMapL(Function fn) { + default Lens diMapL(Fn1 fn) { return (Lens) Profunctor.super.diMapL(fn); } @@ -205,7 +203,7 @@ default Lens diMapL(Function fn) { * {@inheritDoc} */ @Override - default Lens diMapR(Function fn) { + default Lens diMapR(Fn1 fn) { return (Lens) Profunctor.super.diMapR(fn); } @@ -213,8 +211,7 @@ default Lens diMapR(Function fn) { * {@inheritDoc} */ @Override - default Lens diMap(Function lFn, - Function rFn) { + default Lens diMap(Fn1 lFn, Fn1 rFn) { return this.mapS(lFn).mapT(rFn); } @@ -222,7 +219,7 @@ default Lens diMap(Function lFn, * {@inheritDoc} */ @Override - default Lens contraMap(Function fn) { + default Lens contraMap(Fn1 fn) { return (Lens) Profunctor.super.contraMap(fn); } @@ -230,7 +227,7 @@ default Lens contraMap(Function fn) { * {@inheritDoc} */ @Override - default Lens mapS(Function fn) { + default Lens mapS(Fn1 fn) { return lens(Optic.super.mapS(fn)); } @@ -238,7 +235,7 @@ default Lens mapS(Function fn) { * {@inheritDoc} */ @Override - default Lens mapT(Function fn) { + default Lens mapT(Fn1 fn) { return lens(Optic.super.mapT(fn)); } @@ -246,7 +243,7 @@ default Lens mapT(Function fn) { * {@inheritDoc} */ @Override - default Lens mapA(Function fn) { + default Lens mapA(Fn1 fn) { return lens(Optic.super.mapA(fn)); } @@ -254,7 +251,7 @@ default Lens mapA(Function fn) { * {@inheritDoc} */ @Override - default Lens mapB(Function fn) { + default Lens mapB(Fn1 fn) { return lens(Optic.super.mapB(fn)); } @@ -295,8 +292,8 @@ default Lens compose(Optic, ? super Functor * @param the type of the "smaller" update value * @return the lens */ - static Lens lens(Function getter, - BiFunction setter) { + static Lens lens(Fn1 getter, + Fn2 setter) { return lens(Optic., Functor, S, T, A, B, Functor>, @@ -337,8 +334,8 @@ static Lens lens(Optic, ? super Funct * @param the type of both "smaller" values * @return the lens */ - static Lens.Simple simpleLens(Function getter, - BiFunction setter) { + static Lens.Simple simpleLens(Fn1 getter, + Fn2 setter) { return adapt(lens(getter, setter)); } @@ -356,7 +353,7 @@ static Lens.Simple simpleLens(Function gett * @return the dual-focus lens */ static Lens, Tuple2> both(Lens f, Lens g) { - return lens(Both.both(view(f), view(g)), (s, cd) -> cd.biMap(set(f), set(g)).into(Fn1::compose).apply(s)); + return lens(Both.both(view(f), view(g)), (s, cd) -> cd.biMap(set(f), set(g)).into(Fn1::contraMap).apply(s)); } /** diff --git a/src/main/java/com/jnape/palatable/lambda/optics/Optic.java b/src/main/java/com/jnape/palatable/lambda/optics/Optic.java index 4eeac4f75..be518ad7a 100644 --- a/src/main/java/com/jnape/palatable/lambda/optics/Optic.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/Optic.java @@ -4,8 +4,6 @@ import com.jnape.palatable.lambda.functor.Functor; import com.jnape.palatable.lambda.functor.Profunctor; -import java.util.function.Function; - /** * A generic supertype representation for profunctor optics. *

@@ -107,7 +105,7 @@ PRFU apply(PAFB pafb) { * @param the new left side of the output profunctor * @return the new optic */ - default Optic mapS(Function fn) { + default Optic mapS(Fn1 fn) { return optic(pafb -> { Profunctor, ? extends P> psft = apply(pafb); return psft.diMapL(fn); @@ -121,7 +119,7 @@ default Optic mapS(Function fn) { * @param the new right side's functor embedding of the output profunctor * @return the new optic */ - default Optic mapT(Function fn) { + default Optic mapT(Fn1 fn) { return optic(pafb -> { Profunctor, ? extends P> psft = apply(pafb); return psft.diMapR(ft -> ft.fmap(fn)); @@ -135,7 +133,7 @@ default Optic mapT(Function fn) { * @param the new left side of the input profunctor * @return the new optic */ - default Optic mapA(Function fn) { + default Optic mapA(Fn1 fn) { return optic(pcfb -> { @SuppressWarnings("UnnecessaryLocalVariable") Profunctor, ? extends P> psft = apply(pcfb.diMapL(fn)); @@ -146,11 +144,11 @@ default Optic mapA(Function fn) { /** * Contravariantly map B to Z, yielding a new optic. * - * @param fn the mapping function * @param the new right side's functor embedding of the input profunctor + * @param fn the mapping function * @return the new optic */ - default Optic mapB(Function fn) { + default Optic mapB(Fn1 fn) { return optic(pafz -> apply(pafz.diMapR(fz -> fz.fmap(fn)))); } @@ -176,8 +174,7 @@ default Optic mapB(Function fn) { FB extends Functor, FT extends Functor, PAFB extends Profunctor, - PSFT extends Profunctor> Optic optic( - Function fn) { + PSFT extends Profunctor> Optic optic(Fn1 fn) { return new Optic() { @Override @SuppressWarnings("unchecked") diff --git a/src/main/java/com/jnape/palatable/lambda/optics/Prism.java b/src/main/java/com/jnape/palatable/lambda/optics/Prism.java index bf2afb487..b52f67fd0 100644 --- a/src/main/java/com/jnape/palatable/lambda/optics/Prism.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/Prism.java @@ -5,6 +5,7 @@ import com.jnape.palatable.lambda.adt.choice.Choice2; import com.jnape.palatable.lambda.adt.coproduct.CoProduct2; import com.jnape.palatable.lambda.adt.hlist.Tuple2; +import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functions.specialized.Pure; import com.jnape.palatable.lambda.functor.Cocartesian; import com.jnape.palatable.lambda.functor.Functor; @@ -16,8 +17,6 @@ import com.jnape.palatable.lambda.optics.functions.Re; import com.jnape.palatable.lambda.optics.functions.View; -import java.util.function.Function; - /** * Prisms are {@link Iso Isos} that can fail in one direction. Example: *

@@ -63,7 +62,7 @@ public interface Prism extends
      *
      * @return a {@link Tuple2 tuple} of the two mappings encapsulated by this {@link Prism}
      */
-    default Tuple2, Function>> unPrism() {
+    default Tuple2, Fn1>> unPrism() {
         return Tuple2.fill(this., Identity, Identity, Identity,
                 Market>, Market>>apply(
                 new Market<>(Identity::new, Either::right)).fmap(Identity::runIdentity))
@@ -82,8 +81,8 @@ public interface Prism extends
      * @param  the input that guarantees its output
      * @return the {@link Prism}
      */
-    static  Prism prism(Function> sta,
-                                                Function bt) {
+    static  Prism prism(Fn1> sta,
+                                                Fn1 bt) {
         return new Prism() {
             @Override
             public > Optic, F, S, T, A, B> toOptic(
@@ -156,8 +155,8 @@ static  Prism prism(
      *                direction
      * @return the {@link Simple simple prism}
      */
-    static  Prism.Simple simplePrism(Function> sMaybeA,
-                                                 Function as) {
+    static  Prism.Simple simplePrism(Fn1> sMaybeA,
+                                                 Fn1 as) {
         return Prism.prism(s -> sMaybeA.apply(s).toEither(() -> s), as)::toOptic;
     }
 
diff --git a/src/main/java/com/jnape/palatable/lambda/optics/functions/Over.java b/src/main/java/com/jnape/palatable/lambda/optics/functions/Over.java
index d15c8bfae..1e76ec4ce 100644
--- a/src/main/java/com/jnape/palatable/lambda/optics/functions/Over.java
+++ b/src/main/java/com/jnape/palatable/lambda/optics/functions/Over.java
@@ -6,8 +6,6 @@
 import com.jnape.palatable.lambda.functor.builtin.Identity;
 import com.jnape.palatable.lambda.optics.Optic;
 
-import java.util.function.Function;
-
 /**
  * Given an {@link Optic}, a function from A to B, and a "larger" value S,
  * produce a T by retrieving the A from the S, applying the function, and
@@ -24,7 +22,7 @@
  * @see View
  */
 public final class Over implements
-        Fn3, ? super Identity, S, T, A, B>, Function, S, T> {
+        Fn3, ? super Identity, S, T, A, B>, Fn1, S, T> {
 
     private static final Over INSTANCE = new Over<>();
 
@@ -33,7 +31,7 @@ private Over() {
 
     @Override
     public T checkedApply(Optic, ? super Identity, S, T, A, B> optic,
-                          Function fn,
+                          Fn1 fn,
                           S s) {
         return optic., Identity, Identity, Identity, Fn1>, Fn1>>apply(
                 a -> new Identity<>(fn.apply(a))).apply(s).runIdentity();
@@ -44,18 +42,18 @@ public static  Over over() {
         return (Over) INSTANCE;
     }
 
-    public static  Fn2, S, T> over(
+    public static  Fn2, S, T> over(
             Optic, ? super Identity, S, T, A, B> optic) {
         return Over.over().apply(optic);
     }
 
     public static  Fn1 over(Optic, ? super Identity, S, T, A, B> optic,
-                                              Function fn) {
+                                              Fn1 fn) {
         return over(optic).apply(fn);
     }
 
     public static  T over(Optic, ? super Identity, S, T, A, B> optic,
-                                      Function fn, S s) {
+                                      Fn1 fn, S s) {
         return over(optic, fn).apply(s);
     }
 }
diff --git a/src/main/java/com/jnape/palatable/lambda/optics/functions/Under.java b/src/main/java/com/jnape/palatable/lambda/optics/functions/Under.java
index ce63ea01a..81b915867 100644
--- a/src/main/java/com/jnape/palatable/lambda/optics/functions/Under.java
+++ b/src/main/java/com/jnape/palatable/lambda/optics/functions/Under.java
@@ -8,8 +8,6 @@
 import com.jnape.palatable.lambda.optics.Iso;
 import com.jnape.palatable.lambda.optics.Optic;
 
-import java.util.function.Function;
-
 import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id;
 
 /**
@@ -22,7 +20,9 @@
  * @param  the smaller type for focusing
  * @param  the smaller type for mirrored focusing
  */
-public final class Under implements Fn3, ? super Identity, S, T, A, B>, Function, B, A> {
+public final class Under implements
+        Fn3, ? super Identity, S, T, A, B>,
+                Fn1, B, A> {
 
     private static final Under INSTANCE = new Under<>();
 
@@ -31,7 +31,7 @@ private Under() {
 
     @Override
     public A checkedApply(Optic, ? super Identity, S, T, A, B> optic,
-                          Function fn,
+                          Fn1 fn,
                           B b) {
         Exchange> exchange = optic.apply(new Exchange<>(id(), Identity::new));
         return exchange.sa().apply(fn.apply(exchange.bt().apply(b).runIdentity()));
@@ -42,19 +42,19 @@ public static  Under under() {
         return (Under) INSTANCE;
     }
 
-    public static  Fn2, B, A> under(
+    public static  Fn2, B, A> under(
             Optic, ? super Identity, S, T, A, B> optic) {
         return Under.under().apply(optic);
     }
 
     public static  Fn1 under(
             Optic, ? super Identity, S, T, A, B> optic,
-            Function fn) {
+            Fn1 fn) {
         return under(optic).apply(fn);
     }
 
     public static  A under(Optic, ? super Identity, S, T, A, B> optic,
-                                       Function fn, B b) {
+                                       Fn1 fn, B b) {
         return under(optic, fn).apply(b);
     }
 }
diff --git a/src/main/java/com/jnape/palatable/lambda/optics/lenses/CollectionLens.java b/src/main/java/com/jnape/palatable/lambda/optics/lenses/CollectionLens.java
index 9a8a8ee29..18ccd9faa 100644
--- a/src/main/java/com/jnape/palatable/lambda/optics/lenses/CollectionLens.java
+++ b/src/main/java/com/jnape/palatable/lambda/optics/lenses/CollectionLens.java
@@ -1,11 +1,11 @@
 package com.jnape.palatable.lambda.optics.lenses;
 
+import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.optics.Lens;
 
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Set;
-import java.util.function.Function;
 import java.util.stream.Stream;
 
 import static com.jnape.palatable.lambda.optics.Lens.simpleLens;
@@ -27,7 +27,7 @@ private CollectionLens() {
      * @param    the type of the collection
      * @return a lens that focuses on a copy of CX
      */
-    public static > Lens.Simple asCopy(Function copyFn) {
+    public static > Lens.Simple asCopy(Fn1 copyFn) {
         return simpleLens(copyFn, (__, copy) -> copy);
     }
 
@@ -40,8 +40,7 @@ public static > Lens.Simple asCopy(Function<
      * @param    the type of the collection
      * @return a lens that focuses on a Collection as a Set
      */
-    public static > Lens.Simple> asSet(
-            Function copyFn) {
+    public static > Lens.Simple> asSet(Fn1 copyFn) {
         return simpleLens(HashSet::new, (xsL, xsS) -> {
             Set missing = new HashSet<>(xsS);
             missing.removeAll(xsL);
@@ -65,7 +64,7 @@ public static > Lens.Simple> asSet(
      */
     @SuppressWarnings("RedundantTypeArguments")
     public static > Lens.Simple> asStream(
-            Function copyFn) {
+            Fn1 copyFn) {
         return simpleLens(Collection::stream, (xsL, xsS) -> {
             CX updated = copyFn.apply(xsL);
             updated.clear();
diff --git a/src/main/java/com/jnape/palatable/lambda/optics/lenses/IterableLens.java b/src/main/java/com/jnape/palatable/lambda/optics/lenses/IterableLens.java
index 3bab7f98c..b0bd8e810 100644
--- a/src/main/java/com/jnape/palatable/lambda/optics/lenses/IterableLens.java
+++ b/src/main/java/com/jnape/palatable/lambda/optics/lenses/IterableLens.java
@@ -45,7 +45,7 @@ public static  Lens.Simple, Maybe> head() {
      * @return a lens focusing on the tail of an {@link Iterable}
      */
     public static  Lens.Simple, Iterable> tail() {
-        return simpleLens(Tail::tail, fn2(Head.head().andThen(o -> o.fmap(cons()).orElse(id()))).toBiFunction());
+        return simpleLens(Tail::tail, fn2(Head.head().fmap(o -> o.fmap(cons()).orElse(id()))));
     }
 
     /**
diff --git a/src/main/java/com/jnape/palatable/lambda/optics/lenses/MapLens.java b/src/main/java/com/jnape/palatable/lambda/optics/lenses/MapLens.java
index 63fb09016..7016716e7 100644
--- a/src/main/java/com/jnape/palatable/lambda/optics/lenses/MapLens.java
+++ b/src/main/java/com/jnape/palatable/lambda/optics/lenses/MapLens.java
@@ -14,13 +14,15 @@
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
-import java.util.function.Function;
 
 import static com.jnape.palatable.lambda.adt.Maybe.maybe;
+import static com.jnape.palatable.lambda.functions.Effect.effect;
 import static com.jnape.palatable.lambda.functions.builtin.fn2.Alter.alter;
 import static com.jnape.palatable.lambda.functions.builtin.fn2.Map.map;
 import static com.jnape.palatable.lambda.functions.builtin.fn2.ToCollection.toCollection;
 import static com.jnape.palatable.lambda.functions.builtin.fn2.ToMap.toMap;
+import static com.jnape.palatable.lambda.functions.specialized.SideEffect.sideEffect;
+import static com.jnape.palatable.lambda.io.IO.io;
 import static com.jnape.palatable.lambda.optics.Lens.Simple.adapt;
 import static com.jnape.palatable.lambda.optics.Lens.lens;
 import static com.jnape.palatable.lambda.optics.Lens.simpleLens;
@@ -47,7 +49,7 @@ private MapLens() {
      * @return a lens that focuses on copies of maps as a specific subtype
      */
     public static , K, V> Lens, M, M, M> asCopy(
-            Function, ? extends M> copyFn) {
+            Fn1, ? extends M> copyFn) {
         return lens(copyFn, (__, copy) -> copy);
     }
 
@@ -74,10 +76,10 @@ public static  Lens.Simple, Map> asCopy() {
      * @return a lens that focuses on the value at key, as a {@link Maybe}
      */
     public static , K, V> Lens, M, Maybe, Maybe> valueAt(
-            Function, ? extends M> copyFn, K k) {
+            Fn1, ? extends M> copyFn, K k) {
         return lens(m -> maybe(m.get(k)), (m, maybeV) -> maybeV
-                .>>fmap(v -> alter(updated -> updated.put(k, v)))
-                .orElse(alter(updated -> updated.remove(k)))
+                .>>fmap(v -> alter(effect(updated -> io(() -> updated.put(k, v)))))
+                .orElse(alter(updated -> io(sideEffect(() -> updated.remove(k)))))
                 .apply(copyFn.apply(m))
                 .unsafePerformIO());
     }
@@ -119,9 +121,9 @@ public static  Lens.Simple, V> valueAt(K k, V defaultValue) {
      */
     public static  Lens.Simple, Set> keys() {
         return simpleLens(m -> new HashSet<>(m.keySet()), (m, ks) -> {
-            HashSet ksCopy = new HashSet<>(ks);
-            Map updated = new HashMap<>(m);
-            Set keys = updated.keySet();
+            HashSet ksCopy  = new HashSet<>(ks);
+            Map  updated = new HashMap<>(m);
+            Set     keys    = updated.keySet();
             keys.retainAll(ksCopy);
             ksCopy.removeAll(keys);
             ksCopy.forEach(k -> updated.put(k, null));
@@ -142,11 +144,11 @@ public static  Lens.Simple, Set> keys() {
      */
     public static  Lens.Simple, Collection> values() {
         return simpleLens(m -> new ArrayList<>(m.values()), (m, vs) -> {
-            Map updated = new HashMap<>(m);
-            Set valueSet = new HashSet<>(vs);
+            Map updated  = new HashMap<>(m);
+            Set    valueSet = new HashSet<>(vs);
             Set matchingKeys = Filter.>filter(kv -> valueSet.contains(kv.getValue()))
-                    .andThen(map(Map.Entry::getKey))
-                    .andThen(toCollection(HashSet::new))
+                    .fmap(map(Map.Entry::getKey))
+                    .fmap(toCollection(HashSet::new))
                     .apply(updated.entrySet());
             updated.keySet().retainAll(matchingKeys);
             return updated;
diff --git a/src/main/java/com/jnape/palatable/lambda/optics/lenses/SetLens.java b/src/main/java/com/jnape/palatable/lambda/optics/lenses/SetLens.java
index a96e9eb46..3c2790d53 100644
--- a/src/main/java/com/jnape/palatable/lambda/optics/lenses/SetLens.java
+++ b/src/main/java/com/jnape/palatable/lambda/optics/lenses/SetLens.java
@@ -1,12 +1,14 @@
 package com.jnape.palatable.lambda.optics.lenses;
 
+import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.optics.Lens;
 
+import java.util.Collection;
 import java.util.HashSet;
 import java.util.Set;
-import java.util.function.Function;
 
 import static com.jnape.palatable.lambda.optics.Lens.simpleLens;
+import static java.util.Collections.singleton;
 
 /**
  * Lenses that operate on {@link Set}s.
@@ -16,6 +18,45 @@ public final class SetLens {
     private SetLens() {
     }
 
+    /**
+     * A lens that focuses on whether a {@link Set} contains all values in as. Note that
+     * copyFn is used to avoid mutating the {@link Set} in question.
+     *
+     * @param copyFn the copy function
+     * @param as     the values in question
+     * @param     the value type
+     * @param  the set to focus on
+     * @return a lens that focuses on the inclusion of a {@link Collection} of values in a given {@link Set}
+     */
+    public static > Lens.Simple intersection(
+            Fn1 copyFn,
+            Set as) {
+        return simpleLens(setA -> {
+                              SetA intersection = copyFn.apply(setA);
+                              intersection.retainAll(as);
+                              return intersection;
+                          },
+                          (setA, setB) -> {
+                              SetA copy = copyFn.apply(setA);
+                              copy.retainAll(setB);
+                              copy.retainAll(as);
+                              return copy;
+                          });
+    }
+
+    /**
+     * A lens that focuses on whether a {@link Set} contains some value a. Like
+     * {@link #intersection(Fn1, Set)} )} but with an implicit copy function that produces
+     * {@link HashSet}s.
+     *
+     * @param as  the values in question
+     * @param  the value type
+     * @return a lens that focuses on the inclusion of a {@link Collection} of values in a given {@link Set}
+     */
+    public static  Lens.Simple, Set> intersection(Set as) {
+        return intersection(HashSet::new, as);
+    }
+
     /**
      * A lens that focuses on whether a {@link Set} contains some value a. Note that copyFn is
      * used to avoid mutating the {@link Set} in question.
@@ -26,8 +67,8 @@ private SetLens() {
      * @param  the set to focus on
      * @return a lens that focuses on a value's inclusion in a given {@link Set}
      */
-    public static > Lens.Simple contains(
-            Function copyFn, A a) {
+    public static > Lens.Simple contains(Fn1 copyFn,
+                                                                               A a) {
         return simpleLens(setA -> setA.contains(a),
                           (setA, include) -> {
                               SetA copy = copyFn.apply(setA);
@@ -38,8 +79,8 @@ public static > Lens.Simple contains(
     }
 
     /**
-     * A lens that focuses on whether a {@link Set} contains some value a. Like {@link #contains(Function,
-     * Object)} but with an implicit copy function that produces {@link HashSet}s.
+     * A lens that focuses on whether a {@link Set} contains some value a. Like
+     * {@link #contains(Fn1, Object)} but with an implicit copy function that produces {@link HashSet}s.
      *
      * @param a   the value in question
      * @param  the value type
diff --git a/src/main/java/com/jnape/palatable/lambda/semigroup/Semigroup.java b/src/main/java/com/jnape/palatable/lambda/semigroup/Semigroup.java
index 10d15de15..a061328ce 100644
--- a/src/main/java/com/jnape/palatable/lambda/semigroup/Semigroup.java
+++ b/src/main/java/com/jnape/palatable/lambda/semigroup/Semigroup.java
@@ -26,7 +26,7 @@ public interface Semigroup extends Fn2 {
      * @see FoldLeft
      */
     default A foldLeft(A a, Iterable as) {
-        return FoldLeft.foldLeft(toBiFunction(), a, as);
+        return FoldLeft.foldLeft(this, a, as);
     }
 
     /**
diff --git a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Absent.java b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Absent.java
index 97ccfa54a..f39fd05cd 100644
--- a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Absent.java
+++ b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Absent.java
@@ -32,7 +32,7 @@ private Absent() {
 
     @Override
     public Semigroup> checkedApply(Semigroup aSemigroup) {
-        return LiftA2., Maybe, Maybe, Maybe>liftA2(aSemigroup.toBiFunction())::apply;
+        return LiftA2., Maybe, Maybe, Maybe>liftA2(aSemigroup)::apply;
     }
 
     @SuppressWarnings("unchecked")
diff --git a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/MaxBy.java b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/MaxBy.java
index bc97f7d9c..78d361ba8 100644
--- a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/MaxBy.java
+++ b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/MaxBy.java
@@ -4,8 +4,6 @@
 import com.jnape.palatable.lambda.functions.specialized.SemigroupFactory;
 import com.jnape.palatable.lambda.semigroup.Semigroup;
 
-import java.util.function.Function;
-
 import static com.jnape.palatable.lambda.functions.builtin.fn3.LTBy.ltBy;
 
 /**
@@ -22,7 +20,7 @@
  * @see Max
  * @see MinBy
  */
-public final class MaxBy> implements SemigroupFactory, A> {
+public final class MaxBy> implements SemigroupFactory, A> {
 
     private static final MaxBy INSTANCE = new MaxBy<>();
 
@@ -30,7 +28,7 @@ private MaxBy() {
     }
 
     @Override
-    public Semigroup checkedApply(Function compareFn) {
+    public Semigroup checkedApply(Fn1 compareFn) {
         return (x, y) -> ltBy(compareFn, y, x) ? y : x;
     }
 
@@ -39,16 +37,15 @@ public static > MaxBy maxBy() {
         return (MaxBy) INSTANCE;
     }
 
-    public static > Semigroup maxBy(
-            Function compareFn) {
+    public static > Semigroup maxBy(Fn1 compareFn) {
         return MaxBy.maxBy().apply(compareFn);
     }
 
-    public static > Fn1 maxBy(Function compareFn, A x) {
+    public static > Fn1 maxBy(Fn1 compareFn, A x) {
         return MaxBy.maxBy(compareFn).apply(x);
     }
 
-    public static > A maxBy(Function compareFn, A x, A y) {
+    public static > A maxBy(Fn1 compareFn, A x, A y) {
         return maxBy(compareFn, x).apply(y);
     }
 }
diff --git a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/MinBy.java b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/MinBy.java
index c425c5121..07ee12999 100644
--- a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/MinBy.java
+++ b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/MinBy.java
@@ -4,8 +4,6 @@
 import com.jnape.palatable.lambda.functions.specialized.SemigroupFactory;
 import com.jnape.palatable.lambda.semigroup.Semigroup;
 
-import java.util.function.Function;
-
 import static com.jnape.palatable.lambda.functions.builtin.fn3.GTBy.gtBy;
 
 /**
@@ -22,7 +20,7 @@
  * @see Min
  * @see MaxBy
  */
-public final class MinBy> implements SemigroupFactory, A> {
+public final class MinBy> implements SemigroupFactory, A> {
 
     private static final MinBy INSTANCE = new MinBy<>();
 
@@ -30,7 +28,7 @@ private MinBy() {
     }
 
     @Override
-    public Semigroup checkedApply(Function compareFn) {
+    public Semigroup checkedApply(Fn1 compareFn) {
         return (x, y) -> gtBy(compareFn, y, x) ? y : x;
     }
 
@@ -39,16 +37,15 @@ public static > MinBy minBy() {
         return (MinBy) INSTANCE;
     }
 
-    public static > Semigroup minBy(
-            Function compareFn) {
+    public static > Semigroup minBy(Fn1 compareFn) {
         return MinBy.minBy().apply(compareFn);
     }
 
-    public static > Fn1 minBy(Function compareFn, A x) {
+    public static > Fn1 minBy(Fn1 compareFn, A x) {
         return MinBy.minBy(compareFn).apply(x);
     }
 
-    public static > A minBy(Function compareFn, A x, A y) {
+    public static > A minBy(Fn1 compareFn, A x, A y) {
         return minBy(compareFn, x).apply(y);
     }
 }
diff --git a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/RightAny.java b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/RightAny.java
index 264fad155..8dcc439a3 100644
--- a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/RightAny.java
+++ b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/RightAny.java
@@ -39,7 +39,7 @@ private RightAny() {
     public Semigroup> checkedApply(Semigroup rSemigroup) {
         return (x, y) -> x.match(constantly(y),
                                  xR -> y.match(constantly(right(xR)),
-                                               rSemigroup.apply(xR).andThen(Either::right)));
+                                               rSemigroup.apply(xR).fmap(Either::right)));
     }
 
     @SuppressWarnings("unchecked")
diff --git a/src/main/java/com/jnape/palatable/lambda/traversable/LambdaIterable.java b/src/main/java/com/jnape/palatable/lambda/traversable/LambdaIterable.java
index 09222e719..b59ccfcc4 100644
--- a/src/main/java/com/jnape/palatable/lambda/traversable/LambdaIterable.java
+++ b/src/main/java/com/jnape/palatable/lambda/traversable/LambdaIterable.java
@@ -1,5 +1,6 @@
 package com.jnape.palatable.lambda.traversable;
 
+import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functions.builtin.fn1.Empty;
 import com.jnape.palatable.lambda.functions.builtin.fn3.FoldRight;
 import com.jnape.palatable.lambda.functor.Applicative;
@@ -8,7 +9,6 @@
 
 import java.util.Iterator;
 import java.util.Objects;
-import java.util.function.Function;
 
 import static com.jnape.palatable.lambda.functions.builtin.fn1.Flatten.flatten;
 import static com.jnape.palatable.lambda.functions.builtin.fn2.Cons.cons;
@@ -44,7 +44,7 @@ public Iterable unwrap() {
      * {@inheritDoc}
      */
     @Override
-    public  LambdaIterable fmap(Function fn) {
+    public  LambdaIterable fmap(Fn1 fn) {
         return wrap(map(fn, as));
     }
 
@@ -67,7 +67,7 @@ public  LambdaIterable pure(B b) {
      * @return the zipped LambdaIterable
      */
     @Override
-    public  LambdaIterable zip(Applicative, LambdaIterable> appFn) {
+    public  LambdaIterable zip(Applicative, LambdaIterable> appFn) {
         return Monad.super.zip(appFn).coerce();
     }
 
@@ -76,7 +76,7 @@ public  LambdaIterable zip(Applicative, L
      */
     @Override
     public  Lazy> lazyZip(
-            Lazy, LambdaIterable>> lazyAppFn) {
+            Lazy, LambdaIterable>> lazyAppFn) {
         return Empty.empty(as)
                ? lazy(LambdaIterable.empty())
                : Monad.super.lazyZip(lazyAppFn).fmap(Monad>::coerce);
@@ -102,7 +102,7 @@ public  LambdaIterable discardR(Applicative> appB) {
      * {@inheritDoc}
      */
     @Override
-    public  LambdaIterable flatMap(Function>> f) {
+    public  LambdaIterable flatMap(Fn1>> f) {
         return wrap(flatten(map(a -> f.apply(a).>coerce().unwrap(), as)));
     }
 
@@ -113,11 +113,11 @@ public  LambdaIterable flatMap(Function, TravB extends Traversable>,
             AppB extends Applicative,
-            AppTrav extends Applicative> AppTrav traverse(Function fn,
-                                                                      Function pure) {
+            AppTrav extends Applicative> AppTrav traverse(Fn1 fn,
+                                                                      Fn1 pure) {
         return FoldRight.foldRight(
                 (a, lglb) -> fn.apply(a)
-                        .lazyZip(lglb., App>>fmap(appTrav -> appTrav
+                        .lazyZip(lglb., App>>fmap(appTrav -> appTrav
                                 .fmap(travB -> b -> (TravB) wrap(cons(b, ((LambdaIterable) travB).unwrap())))))
                         .fmap(appTrav -> (AppTrav) appTrav),
                 lazy(pure.apply((TravB) empty())),
diff --git a/src/main/java/com/jnape/palatable/lambda/traversable/LambdaMap.java b/src/main/java/com/jnape/palatable/lambda/traversable/LambdaMap.java
index 9c9152f87..94a2e2e7c 100644
--- a/src/main/java/com/jnape/palatable/lambda/traversable/LambdaMap.java
+++ b/src/main/java/com/jnape/palatable/lambda/traversable/LambdaMap.java
@@ -1,6 +1,6 @@
 package com.jnape.palatable.lambda.traversable;
 
-import com.jnape.palatable.lambda.functions.Fn2;
+import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functor.Applicative;
 import com.jnape.palatable.lambda.functor.Functor;
 
@@ -8,9 +8,9 @@
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Objects;
-import java.util.function.Function;
 
 import static com.jnape.palatable.lambda.adt.hlist.HList.tuple;
+import static com.jnape.palatable.lambda.functions.Fn2.fn2;
 import static com.jnape.palatable.lambda.functions.builtin.fn2.Into.into;
 import static com.jnape.palatable.lambda.functions.builtin.fn2.Map.map;
 import static com.jnape.palatable.lambda.functions.builtin.fn2.ToMap.toMap;
@@ -40,7 +40,7 @@ public Map unwrap() {
     }
 
     @Override
-    public  LambdaMap fmap(Function fn) {
+    public  LambdaMap fmap(Fn1 fn) {
         return wrap(toMap(HashMap::new, map(entry -> tuple(entry.getKey(), fn.apply(entry.getValue())), map.entrySet())));
     }
 
@@ -48,13 +48,12 @@ public  LambdaMap fmap(Function fn) {
     @SuppressWarnings("unchecked")
     public , TravC extends Traversable>,
             AppC extends Applicative,
-            AppTrav extends Applicative> AppTrav traverse(Function fn,
-                                                                      Function pure) {
-        return foldLeft(Fn2., AppTrav>fn2(
-                appTrav -> into((k, appV) -> (AppTrav) appTrav.zip(appV.fmap(v -> m -> {
-                    ((LambdaMap) m).unwrap().put(k, v);
-                    return m;
-                })))).toBiFunction(),
+            AppTrav extends Applicative> AppTrav traverse(Fn1 fn,
+                                                                      Fn1 pure) {
+        return foldLeft(fn2(appTrav -> into((k, appV) -> (AppTrav) appTrav.zip(appV.fmap(v -> m -> {
+                            ((LambdaMap) m).unwrap().put(k, v);
+                            return m;
+                        })))),
                         pure.apply((TravC) LambdaMap.wrap(new HashMap<>())),
                         this.fmap(fn).unwrap().entrySet());
     }
diff --git a/src/main/java/com/jnape/palatable/lambda/traversable/Traversable.java b/src/main/java/com/jnape/palatable/lambda/traversable/Traversable.java
index ec52e4e51..91d0a66c6 100644
--- a/src/main/java/com/jnape/palatable/lambda/traversable/Traversable.java
+++ b/src/main/java/com/jnape/palatable/lambda/traversable/Traversable.java
@@ -1,11 +1,10 @@
 package com.jnape.palatable.lambda.traversable;
 
+import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functor.Applicative;
 import com.jnape.palatable.lambda.functor.Functor;
 import com.jnape.palatable.lambda.functor.builtin.Identity;
 
-import java.util.function.Function;
-
 /**
  * An interface for a class of data structures that can be "traversed from left to right" in a structure-preserving
  * way, successively applying some applicative computation to each element and collapsing the results into a single
@@ -36,21 +35,21 @@ public interface Traversable> extends Functorfn to each element of this traversable from left to right, and collapse the results into
      * a single resulting applicative, potentially with the assistance of the applicative's pure function.
      *
-     * @param fn        the function to apply
-     * @param pure      the applicative pure function
      * @param        the resulting element type
      * @param      the result applicative type
      * @param    this Traversable instance over B
      * @param     the result applicative instance over B
      * @param  the full inferred resulting type from the traversal
+     * @param fn        the function to apply
+     * @param pure      the applicative pure function
      * @return the traversed Traversable, wrapped inside an applicative
      */
     , TravB extends Traversable, AppB extends Applicative,
             AppTrav extends Applicative> AppTrav traverse(
-            Function fn, Function pure);
+            Fn1 fn, Fn1 pure);
 
     @Override
-    default  Traversable fmap(Function fn) {
+    default  Traversable fmap(Fn1 fn) {
         return traverse(a -> new Identity(fn.apply(a)), Identity::new).runIdentity();
     }
 }
diff --git a/src/test/java/com/jnape/palatable/lambda/adt/EitherTest.java b/src/test/java/com/jnape/palatable/lambda/adt/EitherTest.java
index 833447905..37371ead6 100644
--- a/src/test/java/com/jnape/palatable/lambda/adt/EitherTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/adt/EitherTest.java
@@ -1,5 +1,6 @@
 package com.jnape.palatable.lambda.adt;
 
+import com.jnape.palatable.lambda.functions.Fn2;
 import com.jnape.palatable.traitor.annotations.TestTraits;
 import com.jnape.palatable.traitor.framework.Subjects;
 import com.jnape.palatable.traitor.runners.Traits;
@@ -15,7 +16,6 @@
 
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
-import java.util.function.BiFunction;
 
 import static com.jnape.palatable.lambda.adt.Either.fromMaybe;
 import static com.jnape.palatable.lambda.adt.Either.left;
@@ -23,6 +23,7 @@
 import static com.jnape.palatable.lambda.adt.Maybe.just;
 import static com.jnape.palatable.lambda.adt.Maybe.nothing;
 import static com.jnape.palatable.lambda.adt.Unit.UNIT;
+import static com.jnape.palatable.lambda.functions.Effect.fromConsumer;
 import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy;
 import static com.jnape.palatable.traitor.framework.Subjects.subjects;
 import static org.hamcrest.core.Is.is;
@@ -42,7 +43,7 @@ public Subjects> testSubjects() {
 
     @Test
     public void recoverLiftsLeftAndFlattensRight() {
-        Either left = left("foo");
+        Either left  = left("foo");
         Either right = right(1);
 
         assertThat(left.recover(l -> -1), is(-1));
@@ -51,7 +52,7 @@ public void recoverLiftsLeftAndFlattensRight() {
 
     @Test
     public void forfeitLiftsRightAndFlattensLeft() {
-        Either left = left("foo");
+        Either left  = left("foo");
         Either right = right(1);
 
         assertThat(left.forfeit(r -> "bar"), is("foo"));
@@ -60,7 +61,7 @@ public void forfeitLiftsRightAndFlattensLeft() {
 
     @Test
     public void orReplacesLeftAndFlattensRight() {
-        Either left = left("foo");
+        Either left  = left("foo");
         Either right = right(1);
 
         assertThat(left.or(-1), is(-1));
@@ -69,7 +70,7 @@ public void orReplacesLeftAndFlattensRight() {
 
     @Test
     public void orThrowFlattensRightOrThrowsException() {
-        Either left = left("foo");
+        Either left  = left("foo");
         Either right = right(1);
 
         assertThat(right.orThrow(IllegalStateException::new), is(1));
@@ -82,7 +83,7 @@ public void orThrowFlattensRightOrThrowsException() {
 
     @Test
     public void filterLiftsRight() {
-        Either left = left("foo");
+        Either left  = left("foo");
         Either right = right(1);
 
         assertThat(left.filter(x -> true, () -> "bar"), is(left));
@@ -93,7 +94,7 @@ public void filterLiftsRight() {
 
     @Test
     public void filterSupportsFunctionFromRToL() {
-        Either left = left("foo");
+        Either left  = left("foo");
         Either right = right(1);
 
         assertThat(left.filter(x -> true, Object::toString), is(left));
@@ -104,7 +105,7 @@ public void filterSupportsFunctionFromRToL() {
 
     @Test
     public void monadicFlatMapLiftsRightAndFlattensBackToEither() {
-        Either left = left("foo");
+        Either left  = left("foo");
         Either right = right(1);
 
         assertThat(left.flatMap(r -> right(r + 1)), is(left("foo")));
@@ -113,14 +114,14 @@ public void monadicFlatMapLiftsRightAndFlattensBackToEither() {
 
     @Test
     public void mergeDuallyLiftsAndCombinesBiasingLeft() {
-        Either left1 = left("foo");
+        Either left1  = left("foo");
         Either right1 = right(1);
 
-        Either left2 = left("bar");
+        Either left2  = left("bar");
         Either right2 = right(2);
 
-        BiFunction concat = String::concat;
-        BiFunction add = (r1, r2) -> r1 + r2;
+        Fn2    concat = String::concat;
+        Fn2 add    = Integer::sum;
 
         assertThat(left1.merge(concat, add, left2), is(left("foobar")));
         assertThat(left1.merge(concat, add, right2), is(left1));
@@ -130,7 +131,7 @@ public void mergeDuallyLiftsAndCombinesBiasingLeft() {
 
     @Test
     public void matchDuallyLiftsAndFlattens() {
-        Either left = left("foo");
+        Either left  = left("foo");
         Either right = right(1);
 
         assertThat(left.match(l -> l + "bar", r -> r + 1), is("foobar"));
@@ -145,7 +146,7 @@ public void toMaybeMapsEitherToOptional() {
 
     @Test
     public void fromMaybeMapsMaybeToEither() {
-        Maybe just = just(1);
+        Maybe just    = just(1);
         Maybe nothing = nothing();
 
         assertThat(fromMaybe(just, () -> "fail"), is(right(1)));
@@ -154,8 +155,8 @@ public void fromMaybeMapsMaybeToEither() {
 
     @Test
     public void fromMaybeDoesNotEvaluateLeftFnForRight() {
-        Maybe just = just(1);
-        AtomicInteger atomicInteger = new AtomicInteger(0);
+        Maybe just          = just(1);
+        AtomicInteger  atomicInteger = new AtomicInteger(0);
         fromMaybe(just, atomicInteger::incrementAndGet);
 
         assertThat(atomicInteger.get(), is(0));
@@ -196,31 +197,31 @@ public void monadTryingWithRunnable() {
 
     @Test
     public void monadicPeekLiftsIOToTheRight() {
-        Either left = left("foo");
+        Either left  = left("foo");
         Either right = right(1);
 
         AtomicInteger intRef = new AtomicInteger();
 
-        left.peek(intRef::set);
+        left.peek(fromConsumer(intRef::set));
         assertEquals(0, intRef.get());
 
-        right.peek(intRef::set);
+        right.peek(fromConsumer(intRef::set));
         assertEquals(1, intRef.get());
     }
 
     @Test
     public void dyadicPeekDuallyLiftsIO() {
-        Either left = left("foo");
+        Either left  = left("foo");
         Either right = right(1);
 
         AtomicReference stringRef = new AtomicReference<>();
-        AtomicInteger intRef = new AtomicInteger();
+        AtomicInteger           intRef    = new AtomicInteger();
 
-        left.peek(stringRef::set, intRef::set);
+        left.peek(fromConsumer(stringRef::set), fromConsumer(intRef::set));
         assertEquals("foo", stringRef.get());
         assertEquals(0, intRef.get());
 
-        right.peek(stringRef::set, intRef::set);
+        right.peek(fromConsumer(stringRef::set), fromConsumer(intRef::set));
         assertEquals("foo", stringRef.get());
         assertEquals(1, intRef.get());
     }
diff --git a/src/test/java/com/jnape/palatable/lambda/adt/MaybeTest.java b/src/test/java/com/jnape/palatable/lambda/adt/MaybeTest.java
index fc21833dc..281f00cf8 100644
--- a/src/test/java/com/jnape/palatable/lambda/adt/MaybeTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/adt/MaybeTest.java
@@ -21,6 +21,7 @@
 import static com.jnape.palatable.lambda.adt.Maybe.nothing;
 import static com.jnape.palatable.lambda.adt.Unit.UNIT;
 import static com.jnape.palatable.lambda.adt.hlist.HList.tuple;
+import static com.jnape.palatable.lambda.functions.Effect.fromConsumer;
 import static com.jnape.palatable.lambda.functions.builtin.fn2.Eq.eq;
 import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy;
 import static com.jnape.palatable.traitor.framework.Subjects.subjects;
@@ -97,10 +98,10 @@ public void fromEither() {
     @Test
     public void peek() {
         AtomicInteger ref = new AtomicInteger(0);
-        assertEquals(just(1), just(1).peek(__ -> ref.incrementAndGet()));
+        assertEquals(just(1), just(1).peek(fromConsumer(__ -> ref.incrementAndGet())));
         assertEquals(1, ref.get());
 
-        assertEquals(nothing(), nothing().peek(__ -> ref.incrementAndGet()));
+        assertEquals(nothing(), nothing().peek(fromConsumer(__ -> ref.incrementAndGet())));
         assertEquals(1, ref.get());
     }
 
diff --git a/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice6Test.java b/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice6Test.java
index 0606c892d..f818d4fd7 100644
--- a/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice6Test.java
+++ b/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice6Test.java
@@ -1,6 +1,7 @@
 package com.jnape.palatable.lambda.adt.choice;
 
 import com.jnape.palatable.lambda.adt.coproduct.CoProduct5;
+import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.traitor.annotations.TestTraits;
 import com.jnape.palatable.traitor.framework.Subjects;
 import com.jnape.palatable.traitor.runners.Traits;
@@ -13,8 +14,6 @@
 import testsupport.traits.MonadLaws;
 import testsupport.traits.TraversableLaws;
 
-import java.util.function.Function;
-
 import static com.jnape.palatable.lambda.adt.choice.Choice6.a;
 import static com.jnape.palatable.lambda.adt.choice.Choice6.b;
 import static com.jnape.palatable.lambda.adt.choice.Choice6.c;
@@ -52,7 +51,7 @@ public Subjects> test
 
     @Test
     public void convergeStaysInChoice() {
-        Function> convergenceFn = f -> Choice5.b(f.toString());
+        Fn1> convergenceFn = f -> Choice5.b(f.toString());
 
         assertEquals(Choice5.a(1), a.converge(convergenceFn));
         assertEquals(Choice5.b("two"), b.converge(convergenceFn));
diff --git a/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice7Test.java b/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice7Test.java
index 5bec8a5b4..62f2e52d0 100644
--- a/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice7Test.java
+++ b/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice7Test.java
@@ -1,6 +1,7 @@
 package com.jnape.palatable.lambda.adt.choice;
 
 import com.jnape.palatable.lambda.adt.coproduct.CoProduct6;
+import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.traitor.annotations.TestTraits;
 import com.jnape.palatable.traitor.framework.Subjects;
 import com.jnape.palatable.traitor.runners.Traits;
@@ -13,8 +14,6 @@
 import testsupport.traits.MonadLaws;
 import testsupport.traits.TraversableLaws;
 
-import java.util.function.Function;
-
 import static com.jnape.palatable.lambda.adt.choice.Choice7.a;
 import static com.jnape.palatable.lambda.adt.choice.Choice7.b;
 import static com.jnape.palatable.lambda.adt.choice.Choice7.c;
@@ -55,7 +54,7 @@ public Subjects> convergenceFn = g -> Choice6.b(g.toString());
+        Fn1> convergenceFn = g -> Choice6.b(g.toString());
 
         assertEquals(Choice6.a(1), a.converge(convergenceFn));
         assertEquals(Choice6.b("two"), b.converge(convergenceFn));
diff --git a/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice8Test.java b/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice8Test.java
index d71e3228d..2b3d4dbe7 100644
--- a/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice8Test.java
+++ b/src/test/java/com/jnape/palatable/lambda/adt/choice/Choice8Test.java
@@ -1,6 +1,7 @@
 package com.jnape.palatable.lambda.adt.choice;
 
 import com.jnape.palatable.lambda.adt.coproduct.CoProduct7;
+import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.traitor.annotations.TestTraits;
 import com.jnape.palatable.traitor.framework.Subjects;
 import com.jnape.palatable.traitor.runners.Traits;
@@ -13,8 +14,6 @@
 import testsupport.traits.MonadLaws;
 import testsupport.traits.TraversableLaws;
 
-import java.util.function.Function;
-
 import static com.jnape.palatable.lambda.adt.choice.Choice8.a;
 import static com.jnape.palatable.lambda.adt.choice.Choice8.b;
 import static com.jnape.palatable.lambda.adt.choice.Choice8.c;
@@ -58,7 +57,8 @@ public Subjects> convergenceFn = h -> Choice7.b(h.toString());
+        Fn1> convergenceFn =
+                h -> Choice7.b(h.toString());
 
         assertEquals(Choice7.a(1), a.converge(convergenceFn));
         assertEquals(Choice7.b("two"), b.converge(convergenceFn));
diff --git a/src/test/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct2Test.java b/src/test/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct2Test.java
index 8b3d8f978..d5a07cca6 100644
--- a/src/test/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct2Test.java
+++ b/src/test/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct2Test.java
@@ -1,11 +1,10 @@
 package com.jnape.palatable.lambda.adt.coproduct;
 
 import com.jnape.palatable.lambda.adt.Maybe;
+import com.jnape.palatable.lambda.functions.Fn1;
 import org.junit.Before;
 import org.junit.Test;
 
-import java.util.function.Function;
-
 import static com.jnape.palatable.lambda.adt.Maybe.just;
 import static com.jnape.palatable.lambda.adt.Maybe.nothing;
 import static com.jnape.palatable.lambda.adt.hlist.HList.tuple;
@@ -21,13 +20,13 @@ public class CoProduct2Test {
     public void setUp() {
         a = new CoProduct2>() {
             @Override
-            public  R match(Function aFn, Function bFn) {
+            public  R match(Fn1 aFn, Fn1 bFn) {
                 return aFn.apply(1);
             }
         };
         b = new CoProduct2>() {
             @Override
-            public  R match(Function aFn, Function bFn) {
+            public  R match(Fn1 aFn, Fn1 bFn) {
                 return bFn.apply(true);
             }
         };
diff --git a/src/test/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct3Test.java b/src/test/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct3Test.java
index 49af8665c..c80a50be2 100644
--- a/src/test/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct3Test.java
+++ b/src/test/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct3Test.java
@@ -3,11 +3,10 @@
 import com.jnape.palatable.lambda.adt.Maybe;
 import com.jnape.palatable.lambda.adt.choice.Choice2;
 import com.jnape.palatable.lambda.adt.choice.Choice3;
+import com.jnape.palatable.lambda.functions.Fn1;
 import org.junit.Before;
 import org.junit.Test;
 
-import java.util.function.Function;
-
 import static com.jnape.palatable.lambda.adt.Maybe.just;
 import static com.jnape.palatable.lambda.adt.Maybe.nothing;
 import static com.jnape.palatable.lambda.adt.hlist.HList.tuple;
@@ -24,22 +23,22 @@ public class CoProduct3Test {
     public void setUp() {
         a = new CoProduct3>() {
             @Override
-            public  R match(Function aFn, Function bFn,
-                               Function cFn) {
+            public  R match(Fn1 aFn, Fn1 bFn,
+                               Fn1 cFn) {
                 return aFn.apply(1);
             }
         };
         b = new CoProduct3>() {
             @Override
-            public  R match(Function aFn, Function bFn,
-                               Function cFn) {
+            public  R match(Fn1 aFn, Fn1 bFn,
+                               Fn1 cFn) {
                 return bFn.apply("two");
             }
         };
         c = new CoProduct3>() {
             @Override
-            public  R match(Function aFn, Function bFn,
-                               Function cFn) {
+            public  R match(Fn1 aFn, Fn1 bFn,
+                               Fn1 cFn) {
                 return cFn.apply(true);
             }
         };
@@ -61,7 +60,7 @@ public void diverge() {
 
     @Test
     public void converge() {
-        Function> convergenceFn = x -> x ? Choice2.a(-1) : Choice2.b("false");
+        Fn1> convergenceFn = x -> x ? Choice2.a(-1) : Choice2.b("false");
         assertEquals(1, a.converge(convergenceFn).match(id(), id()));
         assertEquals("two", b.converge(convergenceFn).match(id(), id()));
         assertEquals(-1, c.converge(convergenceFn).match(id(), id()));
diff --git a/src/test/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct4Test.java b/src/test/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct4Test.java
index 840416088..810a1781c 100644
--- a/src/test/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct4Test.java
+++ b/src/test/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct4Test.java
@@ -3,11 +3,10 @@
 import com.jnape.palatable.lambda.adt.Maybe;
 import com.jnape.palatable.lambda.adt.choice.Choice3;
 import com.jnape.palatable.lambda.adt.choice.Choice4;
+import com.jnape.palatable.lambda.functions.Fn1;
 import org.junit.Before;
 import org.junit.Test;
 
-import java.util.function.Function;
-
 import static com.jnape.palatable.lambda.adt.Maybe.just;
 import static com.jnape.palatable.lambda.adt.Maybe.nothing;
 import static com.jnape.palatable.lambda.adt.hlist.HList.tuple;
@@ -25,29 +24,29 @@ public class CoProduct4Test {
     public void setUp() {
         a = new CoProduct4>() {
             @Override
-            public  R match(Function aFn, Function bFn,
-                               Function cFn, Function dFn) {
+            public  R match(Fn1 aFn, Fn1 bFn,
+                               Fn1 cFn, Fn1 dFn) {
                 return aFn.apply(1);
             }
         };
         b = new CoProduct4>() {
             @Override
-            public  R match(Function aFn, Function bFn,
-                               Function cFn, Function dFn) {
+            public  R match(Fn1 aFn, Fn1 bFn,
+                               Fn1 cFn, Fn1 dFn) {
                 return bFn.apply("two");
             }
         };
         c = new CoProduct4>() {
             @Override
-            public  R match(Function aFn, Function bFn,
-                               Function cFn, Function dFn) {
+            public  R match(Fn1 aFn, Fn1 bFn,
+                               Fn1 cFn, Fn1 dFn) {
                 return cFn.apply(true);
             }
         };
         d = new CoProduct4>() {
             @Override
-            public  R match(Function aFn, Function bFn,
-                               Function cFn, Function dFn) {
+            public  R match(Fn1 aFn, Fn1 bFn,
+                               Fn1 cFn, Fn1 dFn) {
                 return dFn.apply(4D);
             }
         };
@@ -71,11 +70,12 @@ public void diverge() {
 
     @Test
     public void converge() {
-        Function> convergenceFn = x -> x.equals(1d)
-                                                                                       ? Choice3.a(1)
-                                                                                       : x.equals(2d)
-                                                                                         ? Choice3.b("b")
-                                                                                         : Choice3.c(false);
+        Fn1> convergenceFn = x ->
+                x.equals(1d)
+                ? Choice3.a(1)
+                : x.equals(2d)
+                  ? Choice3.b("b")
+                  : Choice3.c(false);
         assertEquals(1, a.converge(convergenceFn).match(id(), id(), id()));
         assertEquals("two", b.converge(convergenceFn).match(id(), id(), id()));
         assertEquals(true, c.converge(convergenceFn).match(id(), id(), id()));
diff --git a/src/test/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct5Test.java b/src/test/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct5Test.java
index 14cccc369..bd986dea1 100644
--- a/src/test/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct5Test.java
+++ b/src/test/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct5Test.java
@@ -3,11 +3,10 @@
 import com.jnape.palatable.lambda.adt.Maybe;
 import com.jnape.palatable.lambda.adt.choice.Choice4;
 import com.jnape.palatable.lambda.adt.choice.Choice5;
+import com.jnape.palatable.lambda.functions.Fn1;
 import org.junit.Before;
 import org.junit.Test;
 
-import java.util.function.Function;
-
 import static com.jnape.palatable.lambda.adt.Maybe.just;
 import static com.jnape.palatable.lambda.adt.Maybe.nothing;
 import static com.jnape.palatable.lambda.adt.hlist.HList.tuple;
@@ -26,41 +25,41 @@ public class CoProduct5Test {
     public void setUp() {
         a = new CoProduct5>() {
             @Override
-            public  R match(Function aFn, Function bFn,
-                               Function cFn, Function dFn,
-                               Function eFn) {
+            public  R match(Fn1 aFn, Fn1 bFn,
+                               Fn1 cFn, Fn1 dFn,
+                               Fn1 eFn) {
                 return aFn.apply(1);
             }
         };
         b = new CoProduct5>() {
             @Override
-            public  R match(Function aFn, Function bFn,
-                               Function cFn, Function dFn,
-                               Function eFn) {
+            public  R match(Fn1 aFn, Fn1 bFn,
+                               Fn1 cFn, Fn1 dFn,
+                               Fn1 eFn) {
                 return bFn.apply("two");
             }
         };
         c = new CoProduct5>() {
             @Override
-            public  R match(Function aFn, Function bFn,
-                               Function cFn, Function dFn,
-                               Function eFn) {
+            public  R match(Fn1 aFn, Fn1 bFn,
+                               Fn1 cFn, Fn1 dFn,
+                               Fn1 eFn) {
                 return cFn.apply(true);
             }
         };
         d = new CoProduct5>() {
             @Override
-            public  R match(Function aFn, Function bFn,
-                               Function cFn, Function dFn,
-                               Function eFn) {
+            public  R match(Fn1 aFn, Fn1 bFn,
+                               Fn1 cFn, Fn1 dFn,
+                               Fn1 eFn) {
                 return dFn.apply(4d);
             }
         };
         e = new CoProduct5>() {
             @Override
-            public  R match(Function aFn, Function bFn,
-                               Function cFn, Function dFn,
-                               Function eFn) {
+            public  R match(Fn1 aFn, Fn1 bFn,
+                               Fn1 cFn, Fn1 dFn,
+                               Fn1 eFn) {
                 return eFn.apply('z');
             }
         };
@@ -86,13 +85,13 @@ public void diverge() {
 
     @Test
     public void converge() {
-        Function> convergenceFn = x -> x.equals('a')
-                                                                                                  ? Choice4.a(1)
-                                                                                                  : x.equals('b')
-                                                                                                    ? Choice4.b("b")
-                                                                                                    : x.equals('c')
-                                                                                                      ? Choice4.c(false)
-                                                                                                      : Choice4.d(1D);
+        Fn1> convergenceFn = x -> x.equals('a')
+                                                                                             ? Choice4.a(1)
+                                                                                             : x.equals('b')
+                                                                                               ? Choice4.b("b")
+                                                                                               : x.equals('c')
+                                                                                                 ? Choice4.c(false)
+                                                                                                 : Choice4.d(1D);
         assertEquals(1, a.converge(convergenceFn).match(id(), id(), id(), id()));
         assertEquals("two", b.converge(convergenceFn).match(id(), id(), id(), id()));
         assertEquals(true, c.converge(convergenceFn).match(id(), id(), id(), id()));
diff --git a/src/test/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct6Test.java b/src/test/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct6Test.java
index 8c38290e7..924e0507f 100644
--- a/src/test/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct6Test.java
+++ b/src/test/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct6Test.java
@@ -3,11 +3,10 @@
 import com.jnape.palatable.lambda.adt.Maybe;
 import com.jnape.palatable.lambda.adt.choice.Choice5;
 import com.jnape.palatable.lambda.adt.choice.Choice6;
+import com.jnape.palatable.lambda.functions.Fn1;
 import org.junit.Before;
 import org.junit.Test;
 
-import java.util.function.Function;
-
 import static com.jnape.palatable.lambda.adt.Maybe.just;
 import static com.jnape.palatable.lambda.adt.Maybe.nothing;
 import static com.jnape.palatable.lambda.adt.hlist.HList.tuple;
@@ -27,49 +26,49 @@ public class CoProduct6Test {
     public void setUp() {
         a = new CoProduct6>() {
             @Override
-            public  R match(Function aFn, Function bFn,
-                               Function cFn, Function dFn,
-                               Function eFn, Function fFn) {
+            public  R match(Fn1 aFn, Fn1 bFn,
+                               Fn1 cFn, Fn1 dFn,
+                               Fn1 eFn, Fn1 fFn) {
                 return aFn.apply(1);
             }
         };
         b = new CoProduct6>() {
             @Override
-            public  R match(Function aFn, Function bFn,
-                               Function cFn, Function dFn,
-                               Function eFn, Function fFn) {
+            public  R match(Fn1 aFn, Fn1 bFn,
+                               Fn1 cFn, Fn1 dFn,
+                               Fn1 eFn, Fn1 fFn) {
                 return bFn.apply("two");
             }
         };
         c = new CoProduct6>() {
             @Override
-            public  R match(Function aFn, Function bFn,
-                               Function cFn, Function dFn,
-                               Function eFn, Function fFn) {
+            public  R match(Fn1 aFn, Fn1 bFn,
+                               Fn1 cFn, Fn1 dFn,
+                               Fn1 eFn, Fn1 fFn) {
                 return cFn.apply(true);
             }
         };
         d = new CoProduct6>() {
             @Override
-            public  R match(Function aFn, Function bFn,
-                               Function cFn, Function dFn,
-                               Function eFn, Function fFn) {
+            public  R match(Fn1 aFn, Fn1 bFn,
+                               Fn1 cFn, Fn1 dFn,
+                               Fn1 eFn, Fn1 fFn) {
                 return dFn.apply(4D);
             }
         };
         e = new CoProduct6>() {
             @Override
-            public  R match(Function aFn, Function bFn,
-                               Function cFn, Function dFn,
-                               Function eFn, Function fFn) {
+            public  R match(Fn1 aFn, Fn1 bFn,
+                               Fn1 cFn, Fn1 dFn,
+                               Fn1 eFn, Fn1 fFn) {
                 return eFn.apply('z');
             }
         };
         f = new CoProduct6>() {
             @Override
-            public  R match(Function aFn, Function bFn,
-                               Function cFn, Function dFn,
-                               Function eFn, Function fFn) {
+            public  R match(Fn1 aFn, Fn1 bFn,
+                               Fn1 cFn, Fn1 dFn,
+                               Fn1 eFn, Fn1 fFn) {
                 return fFn.apply(5L);
             }
         };
@@ -97,7 +96,7 @@ public void diverge() {
 
     @Test
     public void converge() {
-        Function> convergenceFn = x ->
+        Fn1> convergenceFn = x ->
                 x.equals(1L)
                 ? Choice5.a(1)
                 : x.equals(2L)
diff --git a/src/test/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct7Test.java b/src/test/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct7Test.java
index 1ae73c596..84999f677 100644
--- a/src/test/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct7Test.java
+++ b/src/test/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct7Test.java
@@ -3,11 +3,10 @@
 import com.jnape.palatable.lambda.adt.Maybe;
 import com.jnape.palatable.lambda.adt.choice.Choice6;
 import com.jnape.palatable.lambda.adt.choice.Choice7;
+import com.jnape.palatable.lambda.functions.Fn1;
 import org.junit.Before;
 import org.junit.Test;
 
-import java.util.function.Function;
-
 import static com.jnape.palatable.lambda.adt.Maybe.just;
 import static com.jnape.palatable.lambda.adt.Maybe.nothing;
 import static com.jnape.palatable.lambda.adt.hlist.HList.tuple;
@@ -28,64 +27,64 @@ public class CoProduct7Test {
     public void setUp() {
         a = new CoProduct7>() {
             @Override
-            public  R match(Function aFn, Function bFn,
-                               Function cFn, Function dFn,
-                               Function eFn, Function fFn,
-                               Function gFn) {
+            public  R match(Fn1 aFn, Fn1 bFn,
+                               Fn1 cFn, Fn1 dFn,
+                               Fn1 eFn, Fn1 fFn,
+                               Fn1 gFn) {
                 return aFn.apply(1);
             }
         };
         b = new CoProduct7>() {
             @Override
-            public  R match(Function aFn, Function bFn,
-                               Function cFn, Function dFn,
-                               Function eFn, Function fFn,
-                               Function gFn) {
+            public  R match(Fn1 aFn, Fn1 bFn,
+                               Fn1 cFn, Fn1 dFn,
+                               Fn1 eFn, Fn1 fFn,
+                               Fn1 gFn) {
                 return bFn.apply("two");
             }
         };
         c = new CoProduct7>() {
             @Override
-            public  R match(Function aFn, Function bFn,
-                               Function cFn, Function dFn,
-                               Function eFn, Function fFn,
-                               Function gFn) {
+            public  R match(Fn1 aFn, Fn1 bFn,
+                               Fn1 cFn, Fn1 dFn,
+                               Fn1 eFn, Fn1 fFn,
+                               Fn1 gFn) {
                 return cFn.apply(true);
             }
         };
         d = new CoProduct7>() {
             @Override
-            public  R match(Function aFn, Function bFn,
-                               Function cFn, Function dFn,
-                               Function eFn, Function fFn,
-                               Function gFn) {
+            public  R match(Fn1 aFn, Fn1 bFn,
+                               Fn1 cFn, Fn1 dFn,
+                               Fn1 eFn, Fn1 fFn,
+                               Fn1 gFn) {
                 return dFn.apply(4D);
             }
         };
         e = new CoProduct7>() {
             @Override
-            public  R match(Function aFn, Function bFn,
-                               Function cFn, Function dFn,
-                               Function eFn, Function fFn,
-                               Function gFn) {
+            public  R match(Fn1 aFn, Fn1 bFn,
+                               Fn1 cFn, Fn1 dFn,
+                               Fn1 eFn, Fn1 fFn,
+                               Fn1 gFn) {
                 return eFn.apply('z');
             }
         };
         f = new CoProduct7>() {
             @Override
-            public  R match(Function aFn, Function bFn,
-                               Function cFn, Function dFn,
-                               Function eFn, Function fFn,
-                               Function gFn) {
+            public  R match(Fn1 aFn, Fn1 bFn,
+                               Fn1 cFn, Fn1 dFn,
+                               Fn1 eFn, Fn1 fFn,
+                               Fn1 gFn) {
                 return fFn.apply(5L);
             }
         };
         g = new CoProduct7>() {
             @Override
-            public  R match(Function aFn, Function bFn,
-                               Function cFn, Function dFn,
-                               Function eFn, Function fFn,
-                               Function gFn) {
+            public  R match(Fn1 aFn, Fn1 bFn,
+                               Fn1 cFn, Fn1 dFn,
+                               Fn1 eFn, Fn1 fFn,
+                               Fn1 gFn) {
                 return gFn.apply(6f);
             }
         };
@@ -115,7 +114,7 @@ public void diverge() {
 
     @Test
     public void converge() {
-        Function> convergenceFn = x ->
+        Fn1> convergenceFn = x ->
                 x.equals(1f)
                 ? Choice6.a(1)
                 : x.equals(2f)
diff --git a/src/test/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct8Test.java b/src/test/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct8Test.java
index e85f3152a..e5620b3c0 100644
--- a/src/test/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct8Test.java
+++ b/src/test/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct8Test.java
@@ -3,11 +3,10 @@
 import com.jnape.palatable.lambda.adt.Maybe;
 import com.jnape.palatable.lambda.adt.choice.Choice7;
 import com.jnape.palatable.lambda.adt.choice.Choice8;
+import com.jnape.palatable.lambda.functions.Fn1;
 import org.junit.Before;
 import org.junit.Test;
 
-import java.util.function.Function;
-
 import static com.jnape.palatable.lambda.adt.Maybe.just;
 import static com.jnape.palatable.lambda.adt.Maybe.nothing;
 import static com.jnape.palatable.lambda.adt.hlist.HList.tuple;
@@ -29,73 +28,73 @@ public class CoProduct8Test {
     public void setUp() {
         a = new CoProduct8>() {
             @Override
-            public  R match(Function aFn, Function bFn,
-                               Function cFn, Function dFn,
-                               Function eFn, Function fFn,
-                               Function gFn, Function hFn) {
+            public  R match(Fn1 aFn, Fn1 bFn,
+                               Fn1 cFn, Fn1 dFn,
+                               Fn1 eFn, Fn1 fFn,
+                               Fn1 gFn, Fn1 hFn) {
                 return aFn.apply(1);
             }
         };
         b = new CoProduct8>() {
             @Override
-            public  R match(Function aFn, Function bFn,
-                               Function cFn, Function dFn,
-                               Function eFn, Function fFn,
-                               Function gFn, Function hFn) {
+            public  R match(Fn1 aFn, Fn1 bFn,
+                               Fn1 cFn, Fn1 dFn,
+                               Fn1 eFn, Fn1 fFn,
+                               Fn1 gFn, Fn1 hFn) {
                 return bFn.apply("two");
             }
         };
         c = new CoProduct8>() {
             @Override
-            public  R match(Function aFn, Function bFn,
-                               Function cFn, Function dFn,
-                               Function eFn, Function fFn,
-                               Function gFn, Function hFn) {
+            public  R match(Fn1 aFn, Fn1 bFn,
+                               Fn1 cFn, Fn1 dFn,
+                               Fn1 eFn, Fn1 fFn,
+                               Fn1 gFn, Fn1 hFn) {
                 return cFn.apply(true);
             }
         };
         d = new CoProduct8>() {
             @Override
-            public  R match(Function aFn, Function bFn,
-                               Function cFn, Function dFn,
-                               Function eFn, Function fFn,
-                               Function gFn, Function hFn) {
+            public  R match(Fn1 aFn, Fn1 bFn,
+                               Fn1 cFn, Fn1 dFn,
+                               Fn1 eFn, Fn1 fFn,
+                               Fn1 gFn, Fn1 hFn) {
                 return dFn.apply(4D);
             }
         };
         e = new CoProduct8>() {
             @Override
-            public  R match(Function aFn, Function bFn,
-                               Function cFn, Function dFn,
-                               Function eFn, Function fFn,
-                               Function gFn, Function hFn) {
+            public  R match(Fn1 aFn, Fn1 bFn,
+                               Fn1 cFn, Fn1 dFn,
+                               Fn1 eFn, Fn1 fFn,
+                               Fn1 gFn, Fn1 hFn) {
                 return eFn.apply('z');
             }
         };
         f = new CoProduct8>() {
             @Override
-            public  R match(Function aFn, Function bFn,
-                               Function cFn, Function dFn,
-                               Function eFn, Function fFn,
-                               Function gFn, Function hFn) {
+            public  R match(Fn1 aFn, Fn1 bFn,
+                               Fn1 cFn, Fn1 dFn,
+                               Fn1 eFn, Fn1 fFn,
+                               Fn1 gFn, Fn1 hFn) {
                 return fFn.apply(5L);
             }
         };
         g = new CoProduct8>() {
             @Override
-            public  R match(Function aFn, Function bFn,
-                               Function cFn, Function dFn,
-                               Function eFn, Function fFn,
-                               Function gFn, Function hFn) {
+            public  R match(Fn1 aFn, Fn1 bFn,
+                               Fn1 cFn, Fn1 dFn,
+                               Fn1 eFn, Fn1 fFn,
+                               Fn1 gFn, Fn1 hFn) {
                 return gFn.apply(6f);
             }
         };
         h = new CoProduct8>() {
             @Override
-            public  R match(Function aFn, Function bFn,
-                               Function cFn, Function dFn,
-                               Function eFn, Function fFn,
-                               Function gFn, Function hFn) {
+            public  R match(Fn1 aFn, Fn1 bFn,
+                               Fn1 cFn, Fn1 dFn,
+                               Fn1 eFn, Fn1 fFn,
+                               Fn1 gFn, Fn1 hFn) {
                 return hFn.apply((short) 7);
             }
         };
@@ -115,7 +114,7 @@ public void match() {
 
     @Test
     public void converge() {
-        Function> convergenceFn = x ->
+        Fn1> convergenceFn = x ->
                 x.equals((short) 1)
                 ? Choice7.a(1)
                 : x.equals((short) 2)
diff --git a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple2Test.java b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple2Test.java
index a72f4843a..e4a4ee0bb 100644
--- a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple2Test.java
+++ b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple2Test.java
@@ -1,5 +1,6 @@
 package com.jnape.palatable.lambda.adt.hlist;
 
+import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.traitor.annotations.TestTraits;
 import com.jnape.palatable.traitor.runners.Traits;
 import org.junit.Before;
@@ -62,7 +63,7 @@ public void accessors() {
     @Test
     public void randomAccess() {
         SingletonHList spiedTail = spy(singletonHList("second"));
-        Tuple2 tuple2 = new Tuple2<>("first", spiedTail);
+        Tuple2 tuple2    = new Tuple2<>("first", spiedTail);
 
         verify(spiedTail, only()).head();
         tuple2._1();
@@ -104,15 +105,15 @@ public void staticFactoryMethodFromMapEntry() {
 
     @Test
     public void zipPrecedence() {
-        Tuple2 a = tuple("foo", 1);
-        Tuple2> b = tuple("bar", x -> x + 1);
+        Tuple2                                 a = tuple("foo", 1);
+        Tuple2> b = tuple("bar", x -> x + 1);
         assertEquals(tuple("bar", 2), a.zip(b));
     }
 
     @Test
     public void flatMapPrecedence() {
-        Tuple2 a = tuple("foo", 1);
-        Function> b = x -> tuple("bar", x + 1);
+        Tuple2               a = tuple("foo", 1);
+        Fn1> b = x -> tuple("bar", x + 1);
         assertEquals(tuple("foo", 2), a.flatMap(b));
     }
 }
\ No newline at end of file
diff --git a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple3Test.java b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple3Test.java
index 8ca30d9af..4a086c5f4 100644
--- a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple3Test.java
+++ b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple3Test.java
@@ -1,5 +1,6 @@
 package com.jnape.palatable.lambda.adt.hlist;
 
+import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.traitor.annotations.TestTraits;
 import com.jnape.palatable.traitor.runners.Traits;
 import org.junit.Before;
@@ -83,15 +84,15 @@ public void fill() {
 
     @Test
     public void zipPrecedence() {
-        Tuple3 a = tuple("foo", 1, 2);
-        Tuple3> b = tuple("bar", 2, x -> x + 1);
+        Tuple3                                 a = tuple("foo", 1, 2);
+        Tuple3> b = tuple("bar", 2, x -> x + 1);
         assertEquals(tuple("foo", 1, 3), a.zip(b));
     }
 
     @Test
     public void flatMapPrecedence() {
-        Tuple3 a = tuple("foo", 1, 2);
-        Function> b = x -> tuple("bar", 2, x + 1);
+        Tuple3               a = tuple("foo", 1, 2);
+        Fn1> b = x -> tuple("bar", 2, x + 1);
         assertEquals(tuple("foo", 1, 3), a.flatMap(b));
     }
 }
diff --git a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple4Test.java b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple4Test.java
index 7eff60484..59280ec53 100644
--- a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple4Test.java
+++ b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple4Test.java
@@ -1,5 +1,6 @@
 package com.jnape.palatable.lambda.adt.hlist;
 
+import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.traitor.annotations.TestTraits;
 import com.jnape.palatable.traitor.runners.Traits;
 import org.junit.Before;
@@ -60,8 +61,8 @@ public void accessors() {
 
     @Test
     public void randomAccess() {
-        Tuple3 spiedTail = spy(tuple("second", "third", "fourth"));
-        Tuple4 tuple4 = new Tuple4<>("first", spiedTail);
+        Tuple3         spiedTail = spy(tuple("second", "third", "fourth"));
+        Tuple4 tuple4    = new Tuple4<>("first", spiedTail);
 
         verify(spiedTail, times(1))._1();
         verify(spiedTail, times(1))._2();
@@ -86,15 +87,15 @@ public void fill() {
 
     @Test
     public void zipPrecedence() {
-        Tuple4 a = tuple("foo", 1, 2, 3);
-        Tuple4> b = tuple("foo", 1, 2, x -> x + 1);
+        Tuple4                                 a = tuple("foo", 1, 2, 3);
+        Tuple4> b = tuple("foo", 1, 2, x -> x + 1);
         assertEquals(tuple("foo", 1, 2, 4), a.zip(b));
     }
 
     @Test
     public void flatMapPrecedence() {
-        Tuple4 a = tuple("foo", 1, 2, 3);
-        Function> b = x -> tuple("bar", 2, 3, x + 1);
+        Tuple4               a = tuple("foo", 1, 2, 3);
+        Fn1> b = x -> tuple("bar", 2, 3, x + 1);
         assertEquals(tuple("foo", 1, 2, 4), a.flatMap(b));
     }
 }
\ No newline at end of file
diff --git a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple5Test.java b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple5Test.java
index 22d30223d..970ee1c62 100644
--- a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple5Test.java
+++ b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple5Test.java
@@ -1,6 +1,7 @@
 package com.jnape.palatable.lambda.adt.hlist;
 
 import com.jnape.palatable.lambda.adt.hlist.HList.HCons;
+import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.traitor.annotations.TestTraits;
 import com.jnape.palatable.traitor.runners.Traits;
 import org.junit.Before;
@@ -62,8 +63,8 @@ public void accessors() {
 
     @Test
     public void randomAccess() {
-        Tuple4 spiedTail = spy(tuple("second", "third", "fourth", "fifth"));
-        Tuple5 tuple5 = new Tuple5<>("first", spiedTail);
+        Tuple4         spiedTail = spy(tuple("second", "third", "fourth", "fifth"));
+        Tuple5 tuple5    = new Tuple5<>("first", spiedTail);
 
         verify(spiedTail, times(1))._1();
         verify(spiedTail, times(1))._2();
@@ -90,15 +91,17 @@ public void fill() {
 
     @Test
     public void zipPrecedence() {
-        Tuple5 a = tuple("foo", 1, 2, 3, 4);
-        Tuple5> b = tuple("bar", 2, 3, 4, x -> x + 1);
+        Tuple5 a =
+                tuple("foo", 1, 2, 3, 4);
+        Tuple5> b =
+                tuple("bar", 2, 3, 4, x -> x + 1);
         assertEquals(tuple("bar", 2, 3, 4, 5), a.zip(b));
     }
 
     @Test
     public void flatMapPrecedence() {
-        Tuple5 a = tuple("foo", 1, 2, 3, 4);
-        Function> b = x -> tuple("bar", 2, 3, 4, x + 1);
+        Tuple5               a = tuple("foo", 1, 2, 3, 4);
+        Fn1> b = x -> tuple("bar", 2, 3, 4, x + 1);
         assertEquals(tuple("foo", 1, 2, 3, 5), a.flatMap(b));
     }
 }
\ No newline at end of file
diff --git a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple6Test.java b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple6Test.java
index af12149e6..796ed4752 100644
--- a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple6Test.java
+++ b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple6Test.java
@@ -1,6 +1,7 @@
 package com.jnape.palatable.lambda.adt.hlist;
 
 import com.jnape.palatable.lambda.adt.hlist.HList.HCons;
+import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.traitor.annotations.TestTraits;
 import com.jnape.palatable.traitor.runners.Traits;
 import org.junit.Before;
@@ -64,8 +65,8 @@ public void accessors() {
 
     @Test
     public void randomAccess() {
-        Tuple5 spiedTail = spy(tuple("second", "third", "fourth", "fifth", "sixth"));
-        Tuple6 tuple6 = new Tuple6<>("first", spiedTail);
+        Tuple5         spiedTail = spy(tuple("second", "third", "fourth", "fifth", "sixth"));
+        Tuple6 tuple6    = new Tuple6<>("first", spiedTail);
 
         verify(spiedTail, times(1))._1();
         verify(spiedTail, times(1))._2();
@@ -94,15 +95,17 @@ public void fill() {
 
     @Test
     public void zipPrecedence() {
-        Tuple6 a = tuple("foo", 1, 2, 3, 4, 5);
-        Tuple6> b = tuple("bar", 2, 3, 4, 5, x -> x + 1);
+        Tuple6 a =
+                tuple("foo", 1, 2, 3, 4, 5);
+        Tuple6> b =
+                tuple("bar", 2, 3, 4, 5, x -> x + 1);
         assertEquals(tuple("bar", 2, 3, 4, 5, 6), a.zip(b));
     }
 
     @Test
     public void flatMapPrecedence() {
-        Tuple6 a = tuple("foo", 1, 2, 3, 4, 5);
-        Function> b = x -> tuple("bar", 2, 3, 4, 5, x + 1);
+        Tuple6               a = tuple("foo", 1, 2, 3, 4, 5);
+        Fn1> b = x -> tuple("bar", 2, 3, 4, 5, x + 1);
         assertEquals(tuple("foo", 1, 2, 3, 4, 6), a.flatMap(b));
     }
 }
\ No newline at end of file
diff --git a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple7Test.java b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple7Test.java
index f4fd5442e..b8c07e3db 100644
--- a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple7Test.java
+++ b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple7Test.java
@@ -1,6 +1,7 @@
 package com.jnape.palatable.lambda.adt.hlist;
 
 import com.jnape.palatable.lambda.adt.hlist.HList.HCons;
+import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.traitor.annotations.TestTraits;
 import com.jnape.palatable.traitor.runners.Traits;
 import org.junit.Before;
@@ -65,8 +66,8 @@ public void accessors() {
 
     @Test
     public void randomAccess() {
-        Tuple6 spiedTail = spy(tuple("second", "third", "fourth", "fifth", "sixth", "seventh"));
-        Tuple7 tuple7 = new Tuple7<>("first", spiedTail);
+        Tuple6         spiedTail = spy(tuple("second", "third", "fourth", "fifth", "sixth", "seventh"));
+        Tuple7 tuple7    = new Tuple7<>("first", spiedTail);
 
         verify(spiedTail, times(1))._1();
         verify(spiedTail, times(1))._2();
@@ -97,15 +98,17 @@ public void into() {
 
     @Test
     public void zipPrecedence() {
-        Tuple7 a = tuple("foo", 1, 2, 3, 4, 5, 6);
-        Tuple7> b = tuple("bar", 2, 3, 4, 5, 6, x -> x + 1);
+        Tuple7 a =
+                tuple("foo", 1, 2, 3, 4, 5, 6);
+        Tuple7> b =
+                tuple("bar", 2, 3, 4, 5, 6, x -> x + 1);
         assertEquals(tuple("bar", 2, 3, 4, 5, 6, 7), a.zip(b));
     }
 
     @Test
     public void flatMapPrecedence() {
-        Tuple7 a = tuple("foo", 1, 2, 3, 4, 5, 6);
-        Function> b = x -> tuple("bar", 2, 3, 4, 5, 6, x + 1);
+        Tuple7               a = tuple("foo", 1, 2, 3, 4, 5, 6);
+        Fn1> b = x -> tuple("bar", 2, 3, 4, 5, 6, x + 1);
         assertEquals(tuple("foo", 1, 2, 3, 4, 5, 7), a.flatMap(b));
     }
 }
\ No newline at end of file
diff --git a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple8Test.java b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple8Test.java
index 327fb8fe3..6c788a83d 100644
--- a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple8Test.java
+++ b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple8Test.java
@@ -1,6 +1,7 @@
 package com.jnape.palatable.lambda.adt.hlist;
 
 import com.jnape.palatable.lambda.adt.hlist.HList.HCons;
+import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.traitor.annotations.TestTraits;
 import com.jnape.palatable.traitor.runners.Traits;
 import org.junit.Before;
@@ -12,8 +13,6 @@
 import testsupport.traits.MonadLaws;
 import testsupport.traits.TraversableLaws;
 
-import java.util.function.Function;
-
 import static com.jnape.palatable.lambda.adt.hlist.HList.tuple;
 import static org.junit.Assert.assertEquals;
 import static org.mockito.Mockito.spy;
@@ -66,8 +65,8 @@ public void accessors() {
 
     @Test
     public void randomAccess() {
-        Tuple7 spiedTail = spy(tuple("second", "third", "fourth", "fifth", "sixth", "seventh", "eighth"));
-        Tuple8 tuple8 = new Tuple8<>("first", spiedTail);
+        Tuple7         spiedTail = spy(tuple("second", "third", "fourth", "fifth", "sixth", "seventh", "eighth"));
+        Tuple8 tuple8    = new Tuple8<>("first", spiedTail);
 
         verify(spiedTail, times(1))._1();
         verify(spiedTail, times(1))._2();
@@ -100,15 +99,19 @@ public void into() {
 
     @Test
     public void zipPrecedence() {
-        Tuple8 a = tuple("foo", 1, 2, 3, 4, 5, 6, 7);
-        Tuple8> b = tuple("bar", 2, 3, 4, 5, 6, 7, x -> x + 1);
+        Tuple8 a
+                = tuple("foo", 1, 2, 3, 4, 5, 6, 7);
+        Tuple8> b
+                = tuple("bar", 2, 3, 4, 5, 6, 7, x -> x + 1);
         assertEquals(tuple("bar", 2, 3, 4, 5, 6, 7, 8), a.zip(b));
     }
 
     @Test
     public void flatMapPrecedence() {
-        Tuple8 a = tuple("foo", 1, 2, 3, 4, 5, 6, 7);
-        Function> b = x -> tuple("bar", 2, 3, 4, 5, 6, 7, x + 1);
+        Tuple8 a =
+                tuple("foo", 1, 2, 3, 4, 5, 6, 7);
+        Fn1> b =
+                x -> tuple("bar", 2, 3, 4, 5, 6, 7, x + 1);
         assertEquals(tuple("foo", 1, 2, 3, 4, 5, 6, 8), a.flatMap(b));
     }
 }
\ No newline at end of file
diff --git a/src/test/java/com/jnape/palatable/lambda/functions/EffectTest.java b/src/test/java/com/jnape/palatable/lambda/functions/EffectTest.java
index ca3505a0e..c0a442762 100644
--- a/src/test/java/com/jnape/palatable/lambda/functions/EffectTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/functions/EffectTest.java
@@ -1,16 +1,20 @@
 package com.jnape.palatable.lambda.functions;
 
 import com.jnape.palatable.lambda.adt.Unit;
+import com.jnape.palatable.lambda.io.IO;
 import org.junit.Test;
 
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Consumer;
 
 import static com.jnape.palatable.lambda.adt.Unit.UNIT;
 import static com.jnape.palatable.lambda.functions.Effect.effect;
+import static com.jnape.palatable.lambda.functions.Effect.fromConsumer;
 import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly;
 import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
 import static org.junit.Assert.assertEquals;
 
 public class EffectTest {
@@ -19,21 +23,17 @@ public class EffectTest {
     public void covariantReturns() {
         List results = new ArrayList<>();
 
-        Effect effect       = results::add;
+        Effect effect       = fromConsumer(results::add);
         Effect diMapL       = effect.diMapL(Object::toString);
         Effect contraMap    = effect.contraMap(Object::toString);
-        Effect compose      = effect.compose(Object::toString);
         Effect stringEffect = effect.discardR(constantly("1"));
-        Effect andThen      = effect.andThen(effect);
 
-        effect.accept("1");
-        diMapL.accept("2");
-        contraMap.accept("3");
-        compose.accept("4");
-        stringEffect.accept("5");
-        andThen.accept("6");
+        effect.apply("1").unsafePerformIO();
+        diMapL.apply("2").unsafePerformIO();
+        contraMap.apply("3").unsafePerformIO();
+        stringEffect.apply("4").unsafePerformIO();
 
-        assertEquals(asList("1", "2", "3", "4", "5", "6", "6"), results);
+        assertEquals(asList("1", "2", "3", "4"), results);
     }
 
     @Test
@@ -44,8 +44,17 @@ public void staticFactoryMethods() {
         runnableEffect.apply(UNIT).unsafePerformIO();
         assertEquals(1, counter.get());
 
-        Effect fnEffect = effect(AtomicInteger::incrementAndGet);
+        Effect fnEffect = Effect.fromConsumer(AtomicInteger::incrementAndGet);
         fnEffect.apply(counter).unsafePerformIO();
         assertEquals(2, counter.get());
     }
+
+    @Test
+    public void toConsumer() {
+        @SuppressWarnings("RedundantTypeArguments") Effect> addFoo   = l -> IO.io(() -> l.add("foo"));
+        Consumer>                                           consumer = addFoo.toConsumer();
+        ArrayList                                                list     = new ArrayList<>();
+        consumer.accept(list);
+        assertEquals(singletonList("foo"), list);
+    }
 }
\ No newline at end of file
diff --git a/src/test/java/com/jnape/palatable/lambda/functions/Fn0Test.java b/src/test/java/com/jnape/palatable/lambda/functions/Fn0Test.java
new file mode 100644
index 000000000..87af14209
--- /dev/null
+++ b/src/test/java/com/jnape/palatable/lambda/functions/Fn0Test.java
@@ -0,0 +1,39 @@
+package com.jnape.palatable.lambda.functions;
+
+import org.junit.Test;
+
+import java.util.concurrent.Callable;
+import java.util.function.Supplier;
+
+import static org.junit.Assert.assertEquals;
+
+public class Fn0Test {
+
+    @Test
+    public void fromSupplier() {
+        Supplier supplier = () -> 1;
+        Fn0      fn0      = Fn0.fromSupplier(supplier);
+        assertEquals((Integer) 1, fn0.apply());
+    }
+
+    @Test
+    public void fromCallable() {
+        Callable callable = () -> 1;
+        Fn0      fn0      = Fn0.fromCallable(callable);
+        assertEquals((Integer) 1, fn0.apply());
+    }
+
+    @Test
+    public void toSupplier() {
+        Fn0      fn0      = () -> 1;
+        Supplier supplier = fn0.toSupplier();
+        assertEquals((Integer) 1, supplier.get());
+    }
+
+    @Test
+    public void toCallable() throws Exception {
+        Fn0      fn0      = () -> 1;
+        Callable callable = fn0.toCallable();
+        assertEquals((Integer) 1, callable.call());
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/com/jnape/palatable/lambda/functions/Fn1Test.java b/src/test/java/com/jnape/palatable/lambda/functions/Fn1Test.java
index a61b5b752..85db3d418 100644
--- a/src/test/java/com/jnape/palatable/lambda/functions/Fn1Test.java
+++ b/src/test/java/com/jnape/palatable/lambda/functions/Fn1Test.java
@@ -16,6 +16,7 @@
 import static com.jnape.palatable.lambda.adt.choice.Choice2.b;
 import static com.jnape.palatable.lambda.adt.hlist.HList.tuple;
 import static com.jnape.palatable.lambda.functions.Fn1.fn1;
+import static com.jnape.palatable.lambda.functions.Fn1.fromFunction;
 import static com.jnape.palatable.lambda.functions.builtin.fn2.ReduceLeft.reduceLeft;
 import static java.util.Arrays.asList;
 import static org.junit.Assert.assertEquals;
@@ -38,9 +39,11 @@ public void profunctorProperties() {
     }
 
     @Test
-    public void staticFactoryMethods() {
-        Function parseInt = Integer::parseInt;
-        assertEquals((Integer) 1, fn1(parseInt).apply("1"));
+    public void staticFactoryMethod() {
+        assertEquals((Integer) 1, Fn1.fn1(Integer::parseInt).apply("1"));
+        Function function = Integer::parseInt;
+        Fn1      fn1      = fromFunction(function);
+        assertEquals((Integer) 1, fn1.apply("1"));
     }
 
     @Test
@@ -52,7 +55,7 @@ public void thunk() {
     @Test
     public void widen() {
         Fn1 addOne = x -> x + 1;
-        assertEquals(just(4), reduceLeft(addOne.widen().toBiFunction(), asList(1, 2, 3)));
+        assertEquals(just(4), reduceLeft(addOne.widen(), asList(1, 2, 3)));
     }
 
     @Test
@@ -80,4 +83,11 @@ public void choose() {
         assertEquals(b(123), add1.choose().apply("123"));
         assertEquals(a("foo"), add1.choose().apply("foo"));
     }
+
+    @Test
+    public void toFunction() {
+        Fn1      add1     = x -> x + 1;
+        Function function = add1.toFunction();
+        assertEquals((Integer) 2, function.apply(1));
+    }
 }
diff --git a/src/test/java/com/jnape/palatable/lambda/functions/Fn2Test.java b/src/test/java/com/jnape/palatable/lambda/functions/Fn2Test.java
index 89cf70a03..b5c9413b3 100644
--- a/src/test/java/com/jnape/palatable/lambda/functions/Fn2Test.java
+++ b/src/test/java/com/jnape/palatable/lambda/functions/Fn2Test.java
@@ -30,12 +30,6 @@ public void uncurries() {
         assertThat(CHECK_LENGTH.uncurry().apply(tuple("abc", 3)), is(true));
     }
 
-    @Test
-    @SuppressWarnings("ConstantConditions")
-    public void composePreservesTypeSpecificity() {
-        assertTrue(CHECK_LENGTH.compose(Object::toString) instanceof Fn2);
-    }
-
     @Test
     public void toBiFunction() {
         BiFunction biFunction = CHECK_LENGTH.toBiFunction();
@@ -44,10 +38,13 @@ public void toBiFunction() {
 
     @Test
     public void fn2() {
-        BiFunction biFunction = String::format;
-        assertEquals("foo bar", Fn2.fn2(biFunction).apply("foo %s", "bar"));
-
         Fn1> curriedFn1 = (x) -> (y) -> String.format(x, y);
         assertEquals("foo bar", Fn2.fn2(curriedFn1).apply("foo %s", "bar"));
     }
+
+    @Test
+    public void fromBiFunction() {
+        BiFunction biFunction = String::format;
+        assertEquals("foo bar", Fn2.fromBiFunction(biFunction).apply("foo %s", "bar"));
+    }
 }
diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/FlattenTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/FlattenTest.java
index d1889525b..8138aaed0 100644
--- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/FlattenTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/FlattenTest.java
@@ -28,7 +28,7 @@ public class FlattenTest {
 
     @TestTraits({Laziness.class, InfiniteIterableSupport.class, EmptyIterableSupport.class, FiniteIteration.class})
     public Fn1, Iterable> testSubject() {
-        return Flatten.flatten().compose(Map.>map(Collections::singletonList));
+        return Flatten.flatten().contraMap(Map.>map(Collections::singletonList));
     }
 
     @Test
diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/AllTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/AllTest.java
index c266a4bfb..376295e5b 100644
--- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/AllTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/AllTest.java
@@ -7,8 +7,6 @@
 import org.junit.runner.RunWith;
 import testsupport.traits.EmptyIterableSupport;
 
-import java.util.function.Function;
-
 import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly;
 import static com.jnape.palatable.lambda.functions.builtin.fn1.Repeat.repeat;
 import static com.jnape.palatable.lambda.functions.builtin.fn2.All.all;
@@ -19,7 +17,7 @@
 @RunWith(Traits.class)
 public class AllTest {
 
-    private static final Function EVEN = x -> x.doubleValue() % 2 == 0;
+    private static final Fn1 EVEN = x -> x.doubleValue() % 2 == 0;
 
     @TestTraits({EmptyIterableSupport.class})
     public Fn1, ? extends Boolean> createTestSubject() {
diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/AlterTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/AlterTest.java
index 73e11e800..9bff92fa4 100644
--- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/AlterTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/AlterTest.java
@@ -4,6 +4,7 @@
 
 import java.util.ArrayList;
 
+import static com.jnape.palatable.lambda.functions.Effect.fromConsumer;
 import static com.jnape.palatable.lambda.functions.builtin.fn2.Alter.alter;
 import static java.util.Collections.singletonList;
 import static org.junit.Assert.assertEquals;
@@ -14,7 +15,7 @@ public class AlterTest {
     @Test
     public void altersInput() {
         ArrayList input = new ArrayList<>();
-        assertSame(input, alter(xs -> xs.add("foo"), input).unsafePerformIO());
+        assertSame(input, alter(fromConsumer(xs -> xs.add("foo")), input).unsafePerformIO());
         assertEquals(singletonList("foo"), input);
     }
 }
\ No newline at end of file
diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/AnyTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/AnyTest.java
index ff632730b..ccf0451cd 100644
--- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/AnyTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/AnyTest.java
@@ -7,8 +7,6 @@
 import org.junit.runner.RunWith;
 import testsupport.traits.EmptyIterableSupport;
 
-import java.util.function.Function;
-
 import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly;
 import static com.jnape.palatable.lambda.functions.builtin.fn1.Repeat.repeat;
 import static com.jnape.palatable.lambda.functions.builtin.fn2.Any.any;
@@ -19,7 +17,7 @@
 @RunWith(Traits.class)
 public class AnyTest {
 
-    public static final Function EVEN = x -> x % 2 == 0;
+    public static final Fn1 EVEN = x -> x % 2 == 0;
 
     @TestTraits({EmptyIterableSupport.class})
     public Fn1, Boolean> createTestSubject() {
diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/MagnetizeByTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/MagnetizeByTest.java
index 1995332f2..25b0723eb 100644
--- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/MagnetizeByTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/MagnetizeByTest.java
@@ -11,11 +11,10 @@
 import testsupport.traits.InfiniteIterableSupport;
 import testsupport.traits.Laziness;
 
-import java.util.function.BiFunction;
-
 import static com.jnape.palatable.lambda.functions.builtin.fn1.Last.last;
 import static com.jnape.palatable.lambda.functions.builtin.fn1.Repeat.repeat;
 import static com.jnape.palatable.lambda.functions.builtin.fn2.Eq.eq;
+import static com.jnape.palatable.lambda.functions.builtin.fn2.GTE.gte;
 import static com.jnape.palatable.lambda.functions.builtin.fn2.MagnetizeBy.magnetizeBy;
 import static com.jnape.palatable.lambda.functions.builtin.fn2.Take.take;
 import static java.util.Arrays.asList;
@@ -31,16 +30,15 @@ public class MagnetizeByTest {
 
     @TestTraits({EmptyIterableSupport.class, InfiniteIterableSupport.class, FiniteIteration.class, ImmutableIteration.class, Laziness.class})
     public Fn1, Iterable>> testSubject() {
-        return magnetizeBy(eq().toBiFunction());
+        return magnetizeBy(eq());
     }
 
     @Test
     @SuppressWarnings("unchecked")
     public void magnetizesElementsByPredicateOutcome() {
-        BiFunction lte = (x, y) -> x <= y;
-        assertThat(magnetizeBy(lte, emptyList()), isEmpty());
-        assertThat(magnetizeBy(lte, singletonList(1)), contains(iterates(1)));
-        assertThat(magnetizeBy(lte, asList(1, 2, 3, 2, 2, 3, 2, 1)),
+        assertThat(magnetizeBy(GTE.gte(), emptyList()), isEmpty());
+        assertThat(magnetizeBy(gte(), singletonList(1)), contains(iterates(1)));
+        assertThat(magnetizeBy(gte(), asList(1, 2, 3, 2, 2, 3, 2, 1)),
                    contains(iterates(1, 2, 3),
                             iterates(2, 2, 3),
                             iterates(2),
diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partial2Test.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partial2Test.java
deleted file mode 100644
index 81598f331..000000000
--- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partial2Test.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.jnape.palatable.lambda.functions.builtin.fn2;
-
-import org.junit.Test;
-
-import java.util.function.BiFunction;
-
-import static com.jnape.palatable.lambda.functions.builtin.fn2.Partial2.partial2;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
-
-public class Partial2Test {
-
-    @Test
-    public void partiallyAppliesFunction() {
-        BiFunction subtract = (minuend, subtrahend) -> minuend - subtrahend;
-        assertThat(partial2(subtract, 3).apply(2), is(1));
-    }
-}
diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partial3Test.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partial3Test.java
deleted file mode 100644
index f939c68eb..000000000
--- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partial3Test.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.jnape.palatable.lambda.functions.builtin.fn2;
-
-import com.jnape.palatable.lambda.functions.Fn3;
-import org.junit.Test;
-
-import static com.jnape.palatable.lambda.functions.builtin.fn2.Partial3.partial3;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
-
-public class Partial3Test {
-
-    @Test
-    public void partiallyAppliesFunction() {
-        Fn3 concat = (s1, s2, s3) -> s1 + s2 + s3;
-
-        assertThat(partial3(concat, "foo").apply(" bar", " baz"), is("foo bar baz"));
-    }
-}
diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/PartitionTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/PartitionTest.java
index 8aad38db7..ed75f2568 100644
--- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/PartitionTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/PartitionTest.java
@@ -30,8 +30,8 @@ public class PartitionTest {
 
     @TestTraits({Laziness.class, EmptyIterableSupport.class, FiniteIteration.class, ImmutableIteration.class})
     public Subjects, ?>> createTraitsTestSubject() {
-        return subjects(partition(constantly(a(1))).andThen(Tuple2::_1),
-                        partition(constantly(b(1))).andThen(Tuple2::_2));
+        return subjects(partition(constantly(a(1))).fmap(Tuple2::_1),
+                        partition(constantly(b(1))).fmap(Tuple2::_2));
     }
 
     @Test
diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek2Test.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek2Test.java
index af16097b3..3b0860b22 100644
--- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek2Test.java
+++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek2Test.java
@@ -8,6 +8,7 @@
 
 import static com.jnape.palatable.lambda.adt.Either.right;
 import static com.jnape.palatable.lambda.adt.hlist.HList.tuple;
+import static com.jnape.palatable.lambda.functions.Effect.fromConsumer;
 import static com.jnape.palatable.lambda.functions.builtin.fn2.Peek2.peek2;
 import static org.junit.Assert.assertEquals;
 
@@ -15,17 +16,18 @@ public class Peek2Test {
 
     @Test
     public void peeksAtBothBifunctorValues() {
-        AtomicInteger counter = new AtomicInteger(0);
-        Tuple2 tuple = tuple(1, 2);
-        assertEquals(tuple, peek2(__ -> counter.incrementAndGet(), __ -> counter.incrementAndGet(), tuple));
+        AtomicInteger            counter = new AtomicInteger(0);
+        Tuple2 tuple   = tuple(1, 2);
+        assertEquals(tuple, peek2(fromConsumer(__ -> counter.incrementAndGet()),
+                                  fromConsumer(__ -> counter.incrementAndGet()), tuple));
         assertEquals(2, counter.get());
     }
 
     @Test
     public void followsSameConventionsAsBimap() {
-        AtomicInteger counter = new AtomicInteger(0);
-        Either either = right(1);
-        peek2(__ -> counter.incrementAndGet(), __ -> counter.incrementAndGet(), either);
+        AtomicInteger           counter = new AtomicInteger(0);
+        Either either  = right(1);
+        peek2(fromConsumer(__ -> counter.incrementAndGet()), fromConsumer(__ -> counter.incrementAndGet()), either);
         assertEquals(1, counter.get());
     }
 }
\ No newline at end of file
diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/PeekTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/PeekTest.java
index 337899584..5ab1fba4f 100644
--- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/PeekTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/PeekTest.java
@@ -6,6 +6,7 @@
 import java.util.concurrent.atomic.AtomicInteger;
 
 import static com.jnape.palatable.lambda.adt.Maybe.just;
+import static com.jnape.palatable.lambda.functions.Effect.fromConsumer;
 import static com.jnape.palatable.lambda.functions.builtin.fn2.Peek.peek;
 import static org.junit.Assert.assertEquals;
 
@@ -13,9 +14,9 @@ public class PeekTest {
 
     @Test
     public void appliesConsumerToCarrierValue() {
-        AtomicInteger counter = new AtomicInteger(0);
+        AtomicInteger counter     = new AtomicInteger(0);
         Maybe maybeString = just("foo");
-        assertEquals(maybeString, peek(x -> counter.incrementAndGet(), maybeString));
+        assertEquals(maybeString, peek(fromConsumer(x -> counter.incrementAndGet()), maybeString));
         assertEquals(1, counter.get());
     }
 
diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/SequenceTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/SequenceTest.java
index e51dfbaa1..b2e65864e 100644
--- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/SequenceTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/SequenceTest.java
@@ -2,12 +2,11 @@
 
 import com.jnape.palatable.lambda.adt.Either;
 import com.jnape.palatable.lambda.adt.Maybe;
+import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functor.builtin.Compose;
 import com.jnape.palatable.lambda.functor.builtin.Identity;
 import org.junit.Test;
 
-import java.util.function.Function;
-
 import static com.jnape.palatable.lambda.adt.Either.right;
 import static com.jnape.palatable.lambda.adt.Maybe.just;
 import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id;
@@ -22,8 +21,8 @@ public class SequenceTest {
 
     @Test
     public void naturality() {
-        Function, Either> t = id -> right(id.runIdentity());
-        Either> traversable = right(new Identity<>(1));
+        Fn1, Either> t           = id -> right(id.runIdentity());
+        Either>        traversable = right(new Identity<>(1));
 
         assertEquals(t.apply(sequence(traversable, Identity::new).fmap(id())),
                      sequence(traversable.fmap(t), Either::right));
diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToCollectionTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToCollectionTest.java
index 584dd876d..6188c6765 100644
--- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToCollectionTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToCollectionTest.java
@@ -3,8 +3,6 @@
 import org.junit.Test;
 
 import java.util.ArrayList;
-import java.util.Collection;
-import java.util.function.Supplier;
 
 import static com.jnape.palatable.lambda.functions.builtin.fn2.ToCollection.toCollection;
 import static java.util.Arrays.asList;
@@ -14,7 +12,6 @@ public class ToCollectionTest {
 
     @Test
     public void convertsIterablesToCollectionInstance() {
-        Supplier> listFactory = ArrayList::new;
-        assertEquals(asList(1, 2, 3), toCollection(listFactory, asList(1, 2, 3)));
+        assertEquals(asList(1, 2, 3), toCollection(ArrayList::new, asList(1, 2, 3)));
     }
 }
\ No newline at end of file
diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn3/LiftA2Test.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn3/LiftA2Test.java
index 1e575879d..f775e60ec 100644
--- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn3/LiftA2Test.java
+++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn3/LiftA2Test.java
@@ -2,10 +2,9 @@
 
 import com.jnape.palatable.lambda.adt.Either;
 import com.jnape.palatable.lambda.adt.Maybe;
+import com.jnape.palatable.lambda.functions.Fn2;
 import org.junit.Test;
 
-import java.util.function.BiFunction;
-
 import static com.jnape.palatable.lambda.adt.Either.left;
 import static com.jnape.palatable.lambda.adt.Either.right;
 import static com.jnape.palatable.lambda.adt.Maybe.just;
@@ -17,7 +16,7 @@ public class LiftA2Test {
 
     @Test
     public void inference() {
-        BiFunction add = (x, y) -> x + y;
+        Fn2 add = Integer::sum;
 
         Maybe a = liftA2(add, just(1), just(2));
         assertEquals(just(3), a);
@@ -31,7 +30,7 @@ public void inference() {
         Maybe d = liftA2(add, nothing(), nothing());
         assertEquals(nothing(), d);
 
-        Either e = liftA2(add, Either.right(1), right(2));
+        Either e = liftA2(add, Either.right(1), right(2));
         assertEquals(right(3), e);
 
         Either f = liftA2(add, left("error"), right(2));
diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn3/ZipWithTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn3/ZipWithTest.java
index ee1408417..034fe1b9a 100644
--- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn3/ZipWithTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn3/ZipWithTest.java
@@ -10,8 +10,6 @@
 import testsupport.traits.ImmutableIteration;
 import testsupport.traits.Laziness;
 
-import java.util.function.BiFunction;
-
 import static com.jnape.palatable.lambda.adt.hlist.HList.tuple;
 import static com.jnape.palatable.lambda.functions.builtin.fn2.Zip.zip;
 import static com.jnape.palatable.lambda.functions.builtin.fn3.ZipWith.zipWith;
@@ -30,18 +28,16 @@ public Fn1, Iterable> createTestSubject() {
     @Test
     public void zipsTwoIterablesTogetherWithFunction() {
         Iterable oneThroughFive = asList(1, 2, 3, 4, 5);
-        Iterable sixThroughTen = asList(6, 7, 8, 9, 10);
+        Iterable sixThroughTen  = asList(6, 7, 8, 9, 10);
 
-        BiFunction add = (a, b) -> a + b;
-        Iterable sums = ZipWith.zipWith(add, oneThroughFive, sixThroughTen);
+        Iterable sums = zipWith(Integer::sum, oneThroughFive, sixThroughTen);
 
         assertThat(sums, iterates(7, 9, 11, 13, 15));
     }
 
     @Test
-    @SuppressWarnings("unchecked")
     public void zipsAsymmetricallySizedIterables() {
-        Iterable men = asList("Jack", "Sonny");
+        Iterable men   = asList("Jack", "Sonny");
         Iterable women = asList("Jill", "Cher", "Madonna");
 
         Iterable> couples = zip(men, women);
diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn4/RateLimitTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn4/RateLimitTest.java
index b37527919..a03305b74 100644
--- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn4/RateLimitTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn4/RateLimitTest.java
@@ -1,6 +1,7 @@
 package com.jnape.palatable.lambda.functions.builtin.fn4;
 
 import com.jnape.palatable.lambda.functions.Fn1;
+import com.jnape.palatable.lambda.functions.specialized.SideEffect;
 import com.jnape.palatable.lambda.iteration.IterationInterruptedException;
 import com.jnape.palatable.traitor.annotations.TestTraits;
 import com.jnape.palatable.traitor.runners.Traits;
@@ -19,7 +20,7 @@
 import static com.jnape.palatable.lambda.adt.Try.trying;
 import static com.jnape.palatable.lambda.functions.builtin.fn1.Repeat.repeat;
 import static com.jnape.palatable.lambda.functions.builtin.fn4.RateLimit.rateLimit;
-import static com.jnape.palatable.lambda.functions.specialized.checked.CheckedRunnable.checked;
+import static com.jnape.palatable.lambda.functions.specialized.SideEffect.sideEffect;
 import static java.time.Clock.systemUTC;
 import static java.time.Duration.ZERO;
 import static java.util.Arrays.asList;
@@ -66,7 +67,7 @@ public void rateLimitingDelayIsInterruptible() throws InterruptedException {
         Thread         testThread = Thread.currentThread();
         CountDownLatch latch      = new CountDownLatch(1);
         new Thread(() -> {
-            trying(checked(latch::await)).orThrow();
+            trying(sideEffect(latch::await)).orThrow();
             testThread.interrupt();
         }) {{
             start();
diff --git a/src/test/java/com/jnape/palatable/lambda/functions/recursion/TrampolineTest.java b/src/test/java/com/jnape/palatable/lambda/functions/recursion/TrampolineTest.java
index 035358e6a..5104aa824 100644
--- a/src/test/java/com/jnape/palatable/lambda/functions/recursion/TrampolineTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/functions/recursion/TrampolineTest.java
@@ -1,11 +1,11 @@
 package com.jnape.palatable.lambda.functions.recursion;
 
 import com.jnape.palatable.lambda.adt.hlist.Tuple2;
+import com.jnape.palatable.lambda.functions.Fn1;
 import org.junit.Test;
 
 import java.math.BigInteger;
 import java.util.Map;
-import java.util.function.Function;
 
 import static com.jnape.palatable.lambda.adt.hlist.HList.tuple;
 import static com.jnape.palatable.lambda.functions.builtin.fn2.Into.into;
@@ -17,7 +17,8 @@
 
 public class TrampolineTest {
 
-    private static final Function, RecursiveResult, BigInteger>> FACTORIAL =
+    private static final
+    Fn1, RecursiveResult, BigInteger>> FACTORIAL =
             into((x, acc) -> x.compareTo(ONE) > 0 ? recurse(tuple(x.subtract(ONE), x.multiply(acc))) : terminate(acc));
 
     @Test
diff --git a/src/test/java/com/jnape/palatable/lambda/functions/specialized/BiPredicateTest.java b/src/test/java/com/jnape/palatable/lambda/functions/specialized/BiPredicateTest.java
index 4a19bbba8..9f472f37c 100644
--- a/src/test/java/com/jnape/palatable/lambda/functions/specialized/BiPredicateTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/functions/specialized/BiPredicateTest.java
@@ -13,44 +13,44 @@ public class BiPredicateTest {
     public void jufBiPredicateTest() {
         BiPredicate equals = String::equals;
 
-        assertTrue(equals.test("abc", "abc"));
-        assertFalse(equals.test("abc", ""));
-        assertFalse(equals.test("", "abc"));
+        assertTrue(equals.apply("abc", "abc"));
+        assertFalse(equals.apply("abc", ""));
+        assertFalse(equals.apply("", "abc"));
     }
 
     @Test
     public void jufBiPredicateAnd() {
-        BiPredicate bothOdd = (x, y) -> x % 2 == 1 && y % 2 == 1;
+        BiPredicate bothOdd     = (x, y) -> x % 2 == 1 && y % 2 == 1;
         BiPredicate greaterThan = (x, y) -> x.compareTo(y) > 0;
 
         BiPredicate conjunction = bothOdd.and(greaterThan);
 
-        assertTrue(conjunction.test(3, 1));
-        assertFalse(conjunction.test(3, 2));
-        assertFalse(conjunction.test(3, 5));
-        assertFalse(conjunction.test(4, 1));
+        assertTrue(conjunction.apply(3, 1));
+        assertFalse(conjunction.apply(3, 2));
+        assertFalse(conjunction.apply(3, 5));
+        assertFalse(conjunction.apply(4, 1));
     }
 
     @Test
     public void jufBiPredicateOr() {
-        BiPredicate bothOdd = (x, y) -> x % 2 == 1 && y % 2 == 1;
+        BiPredicate bothOdd     = (x, y) -> x % 2 == 1 && y % 2 == 1;
         BiPredicate greaterThan = (x, y) -> x.compareTo(y) > 0;
 
         BiPredicate disjunction = bothOdd.or(greaterThan);
 
-        assertTrue(disjunction.test(3, 2));
-        assertTrue(disjunction.test(1, 3));
-        assertFalse(disjunction.test(1, 2));
+        assertTrue(disjunction.apply(3, 2));
+        assertTrue(disjunction.apply(1, 3));
+        assertFalse(disjunction.apply(1, 2));
     }
 
     @Test
     public void jufBiPredicateNegate() {
         BiPredicate equals = String::equals;
 
-        assertTrue(equals.test("a", "a"));
-        assertFalse(equals.test("b", "a"));
-        assertFalse(equals.negate().test("a", "a"));
-        assertTrue(equals.negate().test("b", "a"));
+        assertTrue(equals.apply("a", "a"));
+        assertFalse(equals.apply("b", "a"));
+        assertFalse(equals.negate().apply("a", "a"));
+        assertTrue(equals.negate().apply("b", "a"));
     }
 
     @Test
@@ -58,4 +58,18 @@ public void flip() {
         BiPredicate equals = String::equals;
         assertThat(equals.flip(), instanceOf(BiPredicate.class));
     }
+
+    @Test
+    public void fromPredicate() {
+        java.util.function.BiPredicate jufBiPredicate = Object::equals;
+        BiPredicate                    biPredicate    = BiPredicate.fromBiPredicate(jufBiPredicate);
+        assertTrue(biPredicate.apply("a", "a"));
+    }
+
+    @Test
+    public void toPredicate() {
+        BiPredicate                    biPredicate    = Object::equals;
+        java.util.function.BiPredicate jufBiPredicate = biPredicate.toBiPredicate();
+        assertTrue(jufBiPredicate.test("a", "a"));
+    }
 }
\ No newline at end of file
diff --git a/src/test/java/com/jnape/palatable/lambda/functions/specialized/PredicateTest.java b/src/test/java/com/jnape/palatable/lambda/functions/specialized/PredicateTest.java
index b7c8be809..67ec6fe6a 100644
--- a/src/test/java/com/jnape/palatable/lambda/functions/specialized/PredicateTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/functions/specialized/PredicateTest.java
@@ -8,47 +8,61 @@
 public class PredicateTest {
 
     @Test
-    public void jufPredicateTest() {
+    public void happyPath() {
         Predicate notEmpty = s -> !(s == null || s.length() == 0);
 
-        assertTrue(notEmpty.test("foo"));
-        assertFalse(notEmpty.test(""));
-        assertFalse(notEmpty.test(null));
+        assertTrue(notEmpty.apply("foo"));
+        assertFalse(notEmpty.apply(""));
+        assertFalse(notEmpty.apply(null));
     }
 
     @Test
-    public void jufPredicateAnd() {
-        Predicate notEmpty = s -> !(s == null || s.length() == 0);
+    public void and() {
+        Predicate notEmpty  = s -> !(s == null || s.length() == 0);
         Predicate lengthGt1 = s -> s.length() > 1;
 
         Predicate conjunction = notEmpty.and(lengthGt1);
 
-        assertTrue(conjunction.test("fo"));
-        assertFalse(conjunction.test("f"));
-        assertFalse(conjunction.test(""));
-        assertFalse(conjunction.test(null));
+        assertTrue(conjunction.apply("fo"));
+        assertFalse(conjunction.apply("f"));
+        assertFalse(conjunction.apply(""));
+        assertFalse(conjunction.apply(null));
     }
 
     @Test
-    public void jufPredicateOr() {
-        Predicate notEmpty = s -> !(s == null || s.length() == 0);
+    public void or() {
+        Predicate notEmpty  = s -> !(s == null || s.length() == 0);
         Predicate lengthGt1 = s -> s != null && s.length() > 1;
 
         Predicate disjunction = lengthGt1.or(notEmpty);
 
-        assertTrue(disjunction.test("fo"));
-        assertTrue(disjunction.test("f"));
-        assertFalse(disjunction.test(""));
-        assertFalse(disjunction.test(null));
+        assertTrue(disjunction.apply("fo"));
+        assertTrue(disjunction.apply("f"));
+        assertFalse(disjunction.apply(""));
+        assertFalse(disjunction.apply(null));
     }
 
     @Test
-    public void jufPredicateNegate() {
+    public void negate() {
         Predicate isTrue = x -> x;
 
-        assertTrue(isTrue.test(true));
-        assertFalse(isTrue.test(false));
-        assertFalse(isTrue.negate().test(true));
-        assertTrue(isTrue.negate().test(false));
+        assertTrue(isTrue.apply(true));
+        assertFalse(isTrue.apply(false));
+        assertFalse(isTrue.negate().apply(true));
+        assertTrue(isTrue.negate().apply(false));
+    }
+
+    @Test
+    public void fromPredicate() {
+        java.util.function.Predicate jufPredicate = String::isEmpty;
+        Predicate                    predicate    = Predicate.fromPredicate(jufPredicate);
+        assertFalse(predicate.apply("123"));
+    }
+
+    @Test
+    public void toPredicate() {
+        Predicate                    predicate    = String::isEmpty;
+        java.util.function.Predicate jufPredicate = predicate.toPredicate();
+        assertFalse(jufPredicate.test("123"));
     }
 }
\ No newline at end of file
diff --git a/src/test/java/com/jnape/palatable/lambda/functions/specialized/SideEffectTest.java b/src/test/java/com/jnape/palatable/lambda/functions/specialized/SideEffectTest.java
new file mode 100644
index 000000000..64eecfd3b
--- /dev/null
+++ b/src/test/java/com/jnape/palatable/lambda/functions/specialized/SideEffectTest.java
@@ -0,0 +1,28 @@
+package com.jnape.palatable.lambda.functions.specialized;
+
+import org.junit.Test;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.junit.Assert.assertEquals;
+
+public class SideEffectTest {
+
+    @Test
+    public void fromRunnable() throws Throwable {
+        AtomicInteger counter    = new AtomicInteger(0);
+        Runnable      runnable   = counter::incrementAndGet;
+        SideEffect    sideEffect = SideEffect.fromRunnable(runnable);
+        sideEffect.Ω();
+        assertEquals(1, counter.get());
+    }
+
+    @Test
+    public void toRunnable() {
+        AtomicInteger counter    = new AtomicInteger(0);
+        SideEffect    sideEffect = counter::incrementAndGet;
+        Runnable      runnable   = sideEffect.toRunnable();
+        runnable.run();
+        assertEquals(1, counter.get());
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/com/jnape/palatable/lambda/functor/BifunctorTest.java b/src/test/java/com/jnape/palatable/lambda/functor/BifunctorTest.java
index bef359ebc..88e027a8a 100644
--- a/src/test/java/com/jnape/palatable/lambda/functor/BifunctorTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/functor/BifunctorTest.java
@@ -1,10 +1,10 @@
 package com.jnape.palatable.lambda.functor;
 
+import com.jnape.palatable.lambda.functions.Fn1;
 import org.junit.Test;
 import testsupport.applicatives.InvocationRecordingBifunctor;
 
 import java.util.concurrent.atomic.AtomicReference;
-import java.util.function.Function;
 
 import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id;
 import static org.hamcrest.CoreMatchers.is;
@@ -14,7 +14,7 @@ public class BifunctorTest {
 
     @Test
     public void biMapLUsesIdentityForRightBiMapFunction() {
-        AtomicReference> rightInvocation = new AtomicReference<>();
+        AtomicReference> rightInvocation = new AtomicReference<>();
         Bifunctor> bifunctor =
                 new InvocationRecordingBifunctor<>(new AtomicReference<>(), rightInvocation);
         bifunctor.biMapL(String::toUpperCase);
@@ -23,7 +23,7 @@ public void biMapLUsesIdentityForRightBiMapFunction() {
 
     @Test
     public void biMapRUsesIdentityForLeftBiMapFunction() {
-        AtomicReference> leftInvocation = new AtomicReference<>();
+        AtomicReference> leftInvocation = new AtomicReference<>();
         Bifunctor> bifunctor =
                 new InvocationRecordingBifunctor<>(leftInvocation, new AtomicReference<>());
         bifunctor.biMapR(String::valueOf);
diff --git a/src/test/java/com/jnape/palatable/lambda/functor/ProfunctorTest.java b/src/test/java/com/jnape/palatable/lambda/functor/ProfunctorTest.java
index a6650b32a..6d1a34912 100644
--- a/src/test/java/com/jnape/palatable/lambda/functor/ProfunctorTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/functor/ProfunctorTest.java
@@ -1,10 +1,10 @@
 package com.jnape.palatable.lambda.functor;
 
+import com.jnape.palatable.lambda.functions.Fn1;
 import org.junit.Test;
 import testsupport.applicatives.InvocationRecordingProfunctor;
 
 import java.util.concurrent.atomic.AtomicReference;
-import java.util.function.Function;
 
 import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id;
 import static org.hamcrest.CoreMatchers.is;
@@ -14,7 +14,7 @@ public class ProfunctorTest {
 
     @Test
     public void diMapLUsesIdentityForRightDiMapFunction() {
-        AtomicReference> rightInvocation = new AtomicReference<>();
+        AtomicReference> rightInvocation = new AtomicReference<>();
         Profunctor> profunctor =
                 new InvocationRecordingProfunctor<>(new AtomicReference<>(), rightInvocation);
         profunctor.diMapL(Object::toString);
@@ -23,7 +23,7 @@ public void diMapLUsesIdentityForRightDiMapFunction() {
 
     @Test
     public void diMapRUsesIdentityForLeftDiMapFunction() {
-        AtomicReference> leftInvocation = new AtomicReference<>();
+        AtomicReference> leftInvocation = new AtomicReference<>();
         Profunctor> profunctor =
                 new InvocationRecordingProfunctor<>(leftInvocation, new AtomicReference<>());
         profunctor.diMapR(String::valueOf);
diff --git a/src/test/java/com/jnape/palatable/lambda/io/IOTest.java b/src/test/java/com/jnape/palatable/lambda/io/IOTest.java
index c6bd42b16..7d1659ad2 100644
--- a/src/test/java/com/jnape/palatable/lambda/io/IOTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/io/IOTest.java
@@ -14,7 +14,6 @@
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutorService;
-import java.util.function.Function;
 
 import static com.jnape.palatable.lambda.adt.Unit.UNIT;
 import static com.jnape.palatable.lambda.functions.builtin.fn2.Tupler2.tupler;
@@ -66,7 +65,7 @@ public void zipAndDerivativesComposesInParallel() {
             advanceSecond.await();
             return a;
         });
-        IO>> ioF = io(() -> {
+        IO>> ioF = io(() -> {
             advanceFirst.await();
             advanceSecond.countDown();
             return f;
@@ -77,7 +76,7 @@ public void zipAndDerivativesComposesInParallel() {
         assertEquals(f.apply(a), zip.unsafePerformAsyncIO(executor).join());
         assertEquals(f.apply(a), zip.unsafePerformAsyncIO(executor).join());
 
-        IO>> discardL = ioA.discardL(ioF);
+        IO>> discardL = ioA.discardL(ioF);
         assertEquals(f, discardL.unsafePerformAsyncIO().join());
         assertEquals(f, discardL.unsafePerformAsyncIO(executor).join());
 
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/ScanningIteratorTest.java b/src/test/java/com/jnape/palatable/lambda/iteration/ScanningIteratorTest.java
index cde0c2f1b..9405ee45a 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/ScanningIteratorTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/iteration/ScanningIteratorTest.java
@@ -1,9 +1,9 @@
 package com.jnape.palatable.lambda.iteration;
 
+import com.jnape.palatable.lambda.functions.Fn2;
 import org.junit.Test;
 
 import java.util.NoSuchElementException;
-import java.util.function.BiFunction;
 
 import static java.util.Arrays.asList;
 import static java.util.Collections.emptyIterator;
@@ -12,7 +12,7 @@
 
 public class ScanningIteratorTest {
 
-    public static final BiFunction ADD = (x, y) -> x + y;
+    public static final Fn2 ADD = Integer::sum;
 
     @Test
     public void hasNextAtLeastForB() {
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/ZippingIteratorTest.java b/src/test/java/com/jnape/palatable/lambda/iteration/ZippingIteratorTest.java
index f88705a91..58b351f6f 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/ZippingIteratorTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/iteration/ZippingIteratorTest.java
@@ -1,5 +1,6 @@
 package com.jnape.palatable.lambda.iteration;
 
+import com.jnape.palatable.lambda.functions.Fn2;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -7,7 +8,6 @@
 import org.mockito.runners.MockitoJUnitRunner;
 
 import java.util.Iterator;
-import java.util.function.BiFunction;
 
 import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertThat;
@@ -17,9 +17,9 @@
 @RunWith(MockitoJUnitRunner.class)
 public class ZippingIteratorTest {
 
-    @Mock private BiFunction zipper;
-    @Mock private Iterator                   as;
-    @Mock private Iterator                   bs;
+    @Mock private Fn2 zipper;
+    @Mock private Iterator            as;
+    @Mock private Iterator            bs;
 
     private ZippingIterator zippingIterator;
 
diff --git a/src/test/java/com/jnape/palatable/lambda/optics/PrismTest.java b/src/test/java/com/jnape/palatable/lambda/optics/PrismTest.java
index 47b76efdb..46d617e81 100644
--- a/src/test/java/com/jnape/palatable/lambda/optics/PrismTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/optics/PrismTest.java
@@ -40,9 +40,9 @@ public void simplePrismInference() {
 
     @Test
     public void unPrismExtractsMappings() {
-        Prism                     prism = prism(PARSE_INT.choose(), Object::toString);
-        Function                 is    = prism.unPrism()._1();
-        Function> sis   = prism.unPrism()._2();
+        Prism                prism = prism(PARSE_INT.choose(), Object::toString);
+        Fn1                 is    = prism.unPrism()._1();
+        Fn1> sis   = prism.unPrism()._2();
 
         assertEquals("123", is.apply(123));
         assertEquals(right(123), sis.apply("123"));
diff --git a/src/test/java/com/jnape/palatable/lambda/traversable/LambdaIterableTest.java b/src/test/java/com/jnape/palatable/lambda/traversable/LambdaIterableTest.java
index e76f48e5e..163fa5f20 100644
--- a/src/test/java/com/jnape/palatable/lambda/traversable/LambdaIterableTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/traversable/LambdaIterableTest.java
@@ -1,6 +1,7 @@
 package com.jnape.palatable.lambda.traversable;
 
 import com.jnape.palatable.lambda.adt.Maybe;
+import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.traitor.annotations.TestTraits;
 import com.jnape.palatable.traitor.framework.Subjects;
 import com.jnape.palatable.traitor.runners.Traits;
@@ -11,8 +12,6 @@
 import testsupport.traits.MonadLaws;
 import testsupport.traits.TraversableLaws;
 
-import java.util.function.Function;
-
 import static com.jnape.palatable.lambda.adt.Maybe.just;
 import static com.jnape.palatable.lambda.adt.Maybe.nothing;
 import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id;
@@ -41,8 +40,8 @@ public Subjects> testSubject() {
 
     @Test
     public void zipAppliesCartesianProductOfFunctionsAndValues() {
-        LambdaIterable> fns = wrap(asList(x -> x + 1, x -> x - 1));
-        LambdaIterable xs = wrap(asList(1, 2, 3));
+        LambdaIterable> fns = wrap(asList(x -> x + 1, x -> x - 1));
+        LambdaIterable                                 xs  = wrap(asList(1, 2, 3));
         assertThat(xs.zip(fns).unwrap(), iterates(2, 3, 4, 0, 1, 2));
     }
 
diff --git a/src/test/java/testsupport/EquatableM.java b/src/test/java/testsupport/EquatableM.java
index ad4272ed8..a046e3fa6 100644
--- a/src/test/java/testsupport/EquatableM.java
+++ b/src/test/java/testsupport/EquatableM.java
@@ -1,24 +1,24 @@
 package testsupport;
 
+import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functor.Applicative;
 import com.jnape.palatable.lambda.monad.Monad;
 
 import java.util.Objects;
-import java.util.function.Function;
 
 public final class EquatableM, A> implements Monad> {
 
-    private final Monad            ma;
-    private final Function equatable;
+    private final Monad       ma;
+    private final Fn1 equatable;
 
-    public EquatableM(Monad ma, Function equatable) {
+    public EquatableM(Monad ma, Fn1 equatable) {
         this.ma = ma;
         this.equatable = equatable;
     }
 
     @Override
-    public  EquatableM flatMap(Function>> f) {
-        return new EquatableM<>(ma.flatMap(f.andThen(x -> x.>coerce().ma)), equatable);
+    public  EquatableM flatMap(Fn1>> f) {
+        return new EquatableM<>(ma.flatMap(f.fmap(x -> x.>coerce().ma)), equatable);
     }
 
     @Override
@@ -27,13 +27,13 @@ public  EquatableM pure(B b) {
     }
 
     @Override
-    public  EquatableM fmap(Function fn) {
+    public  EquatableM fmap(Fn1 fn) {
         return new EquatableM<>(ma.fmap(fn), equatable);
     }
 
     @Override
-    public  EquatableM zip(Applicative, EquatableM> appFn) {
-        return new EquatableM<>(ma.zip(appFn.>>coerce().ma), equatable);
+    public  EquatableM zip(Applicative, EquatableM> appFn) {
+        return new EquatableM<>(ma.zip(appFn.>>coerce().ma), equatable);
     }
 
     @Override
diff --git a/src/test/java/testsupport/applicatives/InvocationRecordingBifunctor.java b/src/test/java/testsupport/applicatives/InvocationRecordingBifunctor.java
index 65ff38cba..8fca9d114 100644
--- a/src/test/java/testsupport/applicatives/InvocationRecordingBifunctor.java
+++ b/src/test/java/testsupport/applicatives/InvocationRecordingBifunctor.java
@@ -1,24 +1,25 @@
 package testsupport.applicatives;
 
+import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functor.Bifunctor;
 
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.Function;
 
 public final class InvocationRecordingBifunctor implements Bifunctor> {
-    private final AtomicReference> leftFn;
-    private final AtomicReference> rightFn;
+    private final AtomicReference> leftFn;
+    private final AtomicReference> rightFn;
 
-    public InvocationRecordingBifunctor(AtomicReference> leftFn,
-                                        AtomicReference> rightFn) {
+    public InvocationRecordingBifunctor(AtomicReference> leftFn,
+                                        AtomicReference> rightFn) {
         this.leftFn = leftFn;
         this.rightFn = rightFn;
     }
 
     @Override
     @SuppressWarnings("unchecked")
-    public  InvocationRecordingBifunctor biMap(Function lFn,
-                                                           Function rFn) {
+    public  InvocationRecordingBifunctor biMap(Fn1 lFn,
+                                                           Fn1 rFn) {
         leftFn.set(lFn);
         rightFn.set(rFn);
         return (InvocationRecordingBifunctor) this;
diff --git a/src/test/java/testsupport/applicatives/InvocationRecordingProfunctor.java b/src/test/java/testsupport/applicatives/InvocationRecordingProfunctor.java
index 28c34ee0f..403dee83c 100644
--- a/src/test/java/testsupport/applicatives/InvocationRecordingProfunctor.java
+++ b/src/test/java/testsupport/applicatives/InvocationRecordingProfunctor.java
@@ -1,24 +1,24 @@
 package testsupport.applicatives;
 
+import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functor.Profunctor;
 
 import java.util.concurrent.atomic.AtomicReference;
-import java.util.function.Function;
 
 public final class InvocationRecordingProfunctor implements Profunctor> {
-    private final AtomicReference> leftFn;
-    private final AtomicReference> rightFn;
+    private final AtomicReference> leftFn;
+    private final AtomicReference> rightFn;
 
-    public InvocationRecordingProfunctor(AtomicReference> leftFn,
-                                         AtomicReference> rightFn) {
+    public InvocationRecordingProfunctor(AtomicReference> leftFn,
+                                         AtomicReference> rightFn) {
         this.leftFn = leftFn;
         this.rightFn = rightFn;
     }
 
     @Override
     @SuppressWarnings("unchecked")
-    public  InvocationRecordingProfunctor diMap(Function lFn,
-                                                            Function rFn) {
+    public  InvocationRecordingProfunctor diMap(Fn1 lFn,
+                                                            Fn1 rFn) {
         leftFn.set(lFn);
         rightFn.set(rFn);
         return (InvocationRecordingProfunctor) this;
diff --git a/src/test/java/testsupport/functions/ExplainFold.java b/src/test/java/testsupport/functions/ExplainFold.java
index a168674e3..488b05476 100644
--- a/src/test/java/testsupport/functions/ExplainFold.java
+++ b/src/test/java/testsupport/functions/ExplainFold.java
@@ -1,12 +1,14 @@
 package testsupport.functions;
 
+import com.jnape.palatable.lambda.functions.Fn2;
+
 import java.util.function.BiFunction;
 
 import static java.lang.String.format;
 
 public class ExplainFold {
 
-    public static BiFunction explainFold() {
+    public static Fn2 explainFold() {
         return (acc, x) -> format("(%s + %s)", acc, x);
     }
 }
diff --git a/src/test/java/testsupport/matchers/LeftMatcher.java b/src/test/java/testsupport/matchers/LeftMatcher.java
index 7982965a8..7ccb74737 100644
--- a/src/test/java/testsupport/matchers/LeftMatcher.java
+++ b/src/test/java/testsupport/matchers/LeftMatcher.java
@@ -5,6 +5,7 @@
 import org.hamcrest.Matcher;
 import org.hamcrest.TypeSafeMatcher;
 
+import static com.jnape.palatable.lambda.functions.Effect.fromConsumer;
 import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly;
 
 public final class LeftMatcher extends TypeSafeMatcher> {
@@ -29,11 +30,11 @@ public void describeTo(Description description) {
     @Override
     protected void describeMismatchSafely(Either item, Description mismatchDescription) {
         mismatchDescription.appendText("was ");
-        item.peek(l -> {
+        item.peek(fromConsumer(l -> {
                       mismatchDescription.appendText("Left value of ");
                       lMatcher.describeMismatch(l, mismatchDescription);
-                  },
-                  r -> mismatchDescription.appendValue(item));
+                  }),
+                  fromConsumer(r -> mismatchDescription.appendValue(item)));
     }
 
     public static  LeftMatcher isLeftThat(Matcher lMatcher) {
diff --git a/src/test/java/testsupport/matchers/RightMatcher.java b/src/test/java/testsupport/matchers/RightMatcher.java
index 08965bf2f..8e4f15c36 100644
--- a/src/test/java/testsupport/matchers/RightMatcher.java
+++ b/src/test/java/testsupport/matchers/RightMatcher.java
@@ -5,6 +5,7 @@
 import org.hamcrest.Matcher;
 import org.hamcrest.TypeSafeMatcher;
 
+import static com.jnape.palatable.lambda.functions.Effect.fromConsumer;
 import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly;
 
 public final class RightMatcher extends TypeSafeMatcher> {
@@ -29,11 +30,11 @@ public void describeTo(Description description) {
     @Override
     protected void describeMismatchSafely(Either item, Description mismatchDescription) {
         mismatchDescription.appendText("was ");
-        item.peek(l -> mismatchDescription.appendValue(item),
-                  r -> {
+        item.peek(fromConsumer(l -> mismatchDescription.appendValue(item)),
+                  fromConsumer(r -> {
                       mismatchDescription.appendText("Right value of ");
                       rMatcher.describeMismatch(r, mismatchDescription);
-                  });
+                  }));
     }
 
     public static  RightMatcher isRightThat(Matcher rMatcher) {
diff --git a/src/test/java/testsupport/traits/ApplicativeLaws.java b/src/test/java/testsupport/traits/ApplicativeLaws.java
index 11397da5a..5b8b0b713 100644
--- a/src/test/java/testsupport/traits/ApplicativeLaws.java
+++ b/src/test/java/testsupport/traits/ApplicativeLaws.java
@@ -1,6 +1,7 @@
 package testsupport.traits;
 
 import com.jnape.palatable.lambda.adt.Maybe;
+import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functor.Applicative;
 import com.jnape.palatable.lambda.monoid.builtin.Present;
 import com.jnape.palatable.traitor.traits.Trait;
@@ -14,14 +15,13 @@
 import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id;
 import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy;
 import static java.util.Arrays.asList;
-import static java.util.function.Function.identity;
 
 public class ApplicativeLaws> implements Trait> {
 
     @Override
     public void test(Applicative applicative) {
         Present.present((x, y) -> x + "\n\t - " + y)
-                ., Maybe>>foldMap(
+                ., Maybe>>foldMap(
                         f -> f.apply(applicative),
                         asList(this::testIdentity,
                                this::testComposition,
@@ -37,44 +37,45 @@ public void test(Applicative applicative) {
     }
 
     private Maybe testIdentity(Applicative applicative) {
-        Applicative v = applicative.pure(1);
-        Applicative, App> pureId = v.pure(identity());
+        Applicative                                 v      = applicative.pure(1);
+        Applicative, App> pureId = v.pure(id());
         return v.zip(pureId).equals(v)
                ? nothing()
                : just("identity (v.zip(pureId).equals(v))");
     }
 
     private Maybe testComposition(Applicative applicative) {
-        Random random = new Random();
-        Integer firstInt = random.nextInt(100);
+        Random  random    = new Random();
+        Integer firstInt  = random.nextInt(100);
         Integer secondInt = random.nextInt(100);
 
-        Function, ? extends Function, ? extends Function>> compose = x -> x::compose;
-        Applicative, App> u = applicative.pure(x -> x + firstInt);
-        Applicative, App> v = applicative.pure(x -> x + secondInt);
-        Applicative w = applicative.pure("result: ");
+        Fn1,
+                Fn1,
+                        Fn1>> compose = x -> x::contraMap;
+        Applicative, App> u = applicative.pure(x -> x + firstInt);
+        Applicative, App> v = applicative.pure(x -> x + secondInt);
+        Applicative                                w = applicative.pure("result: ");
 
-        Applicative, ? extends Function, ? extends Function>>, App> pureCompose = u.pure(compose);
-        return w.zip(v.zip(u.zip(pureCompose))).equals(w.zip(v).zip(u))
+        return w.zip(v.zip(u.zip(u.pure(compose)))).equals(w.zip(v).zip(u))
                ? nothing()
                : just("composition (w.zip(v.zip(u.zip(pureCompose))).equals((w.zip(v)).zip(u)))");
     }
 
     private Maybe testHomomorphism(Applicative applicative) {
-        Function f = x -> x + 1;
-        int x = 1;
+        Fn1 f = x -> x + 1;
+        int                   x = 1;
 
-        Applicative pureX = applicative.pure(x);
-        Applicative, App> pureF = applicative.pure(f);
-        Applicative pureFx = applicative.pure(f.apply(x));
+        Applicative                                 pureX  = applicative.pure(x);
+        Applicative, App> pureF  = applicative.pure(f);
+        Applicative                                 pureFx = applicative.pure(f.apply(x));
         return pureX.zip(pureF).equals(pureFx)
                ? nothing()
                : just("homomorphism (pureX.zip(pureF).equals(pureFx))");
     }
 
     private Maybe testInterchange(Applicative applicative) {
-        Applicative, App> u = applicative.pure(x -> x + 1);
-        int y = 1;
+        Applicative, App> u = applicative.pure(x -> x + 1);
+        int                                                       y = 1;
 
         Applicative pureY = applicative.pure(y);
         return pureY.zip(u).equals(u.zip(applicative.pure(f -> f.apply(y))))
@@ -86,7 +87,7 @@ private Maybe testDiscardL(Applicative applicative) {
         Applicative u = applicative.pure("u");
         Applicative v = applicative.pure("v");
 
-        return u.discardL(v).equals(v.zip(u.zip(applicative.pure(constantly(identity())))))
+        return u.discardL(v).equals(v.zip(u.zip(applicative.pure(constantly(id())))))
                ? nothing()
                : just("discardL u.discardL(v).equals(v.zip(u.zip(applicative.pure(constantly(identity())))))");
     }
diff --git a/src/test/java/testsupport/traits/BifunctorLaws.java b/src/test/java/testsupport/traits/BifunctorLaws.java
index 55278590e..780519c17 100644
--- a/src/test/java/testsupport/traits/BifunctorLaws.java
+++ b/src/test/java/testsupport/traits/BifunctorLaws.java
@@ -1,12 +1,11 @@
 package testsupport.traits;
 
 import com.jnape.palatable.lambda.adt.Maybe;
+import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functor.Bifunctor;
 import com.jnape.palatable.lambda.monoid.builtin.Present;
 import com.jnape.palatable.traitor.traits.Trait;
 
-import java.util.function.Function;
-
 import static com.jnape.palatable.lambda.adt.Maybe.just;
 import static com.jnape.palatable.lambda.adt.Maybe.nothing;
 import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id;
@@ -17,7 +16,7 @@ public class BifunctorLaws> implements Trait bifunctor) {
         Present.present((x, y) -> x + "\n\t - " + y)
-                ., Maybe>>foldMap(
+                ., Maybe>>foldMap(
                         f -> f.apply(bifunctor),
                         asList(this::testLeftIdentity,
                                this::testRightIdentity,
diff --git a/src/test/java/testsupport/traits/FunctorLaws.java b/src/test/java/testsupport/traits/FunctorLaws.java
index dbe96c6e5..c2bb1791c 100644
--- a/src/test/java/testsupport/traits/FunctorLaws.java
+++ b/src/test/java/testsupport/traits/FunctorLaws.java
@@ -1,6 +1,7 @@
 package testsupport.traits;
 
 import com.jnape.palatable.lambda.adt.Maybe;
+import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functor.Functor;
 import com.jnape.palatable.lambda.monoid.builtin.Present;
 import com.jnape.palatable.traitor.traits.Trait;
@@ -10,15 +11,15 @@
 import static com.jnape.palatable.lambda.adt.Maybe.just;
 import static com.jnape.palatable.lambda.adt.Maybe.nothing;
 import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly;
+import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id;
 import static java.util.Arrays.asList;
-import static java.util.function.Function.identity;
 
 public class FunctorLaws> implements Trait> {
 
     @Override
     public void test(Functor f) {
         Present.present((x, y) -> x + "\n\t - " + y)
-                ., Maybe>>foldMap(
+                ., Maybe>>foldMap(
                         fn -> fn.apply(f),
                         asList(this::testIdentity,
                                this::testComposition))
@@ -28,17 +29,17 @@ public void test(Functor f) {
     }
 
     private Maybe testIdentity(Functor f) {
-        return f.fmap(identity()).equals(f)
+        return f.fmap(id()).equals(f)
                ? nothing()
                : just("identity (f.fmap(identity()).equals(f))");
     }
 
     private Maybe testComposition(Functor functor) {
-        Functor subject = functor.fmap(constantly(1));
-        Function f = x -> x * 3;
-        Function g = x -> x - 2;
-        return subject.fmap(f.compose(g)).equals(subject.fmap(g).fmap(f))
+        Functor   subject = functor.fmap(constantly(1));
+        Fn1 f       = x -> x * 3;
+        Fn1 g       = x -> x - 2;
+        return subject.fmap(f.contraMap(g)).equals(subject.fmap(g).fmap(f))
                ? nothing()
-               : just("composition (functor.fmap(f.compose(g)).equals(functor.fmap(g).fmap(f)))");
+               : just("composition (functor.fmap(f.contraMap(g)).equals(functor.fmap(g).fmap(f)))");
     }
 }
diff --git a/src/test/java/testsupport/traits/MonadLaws.java b/src/test/java/testsupport/traits/MonadLaws.java
index 98738eb57..5ea31ac98 100644
--- a/src/test/java/testsupport/traits/MonadLaws.java
+++ b/src/test/java/testsupport/traits/MonadLaws.java
@@ -21,7 +21,7 @@ public class MonadLaws> implements Trait> {
     @Override
     public void test(Monad m) {
         Present.present((x, y) -> x + "\n\t - " + y)
-                ., Maybe>>foldMap(f -> f.apply(m), asList(
+                ., Maybe>>foldMap(f -> f.apply(m), asList(
                         this::testLeftIdentity,
                         this::testRightIdentity,
                         this::testAssociativity,
@@ -32,8 +32,8 @@ public void test(Monad m) {
     }
 
     private Maybe testLeftIdentity(Monad m) {
-        Object a = new Object();
-        Fn1> fn = id().andThen(m::pure);
+        Object                        a  = new Object();
+        Fn1> fn = id().fmap(m::pure);
         return m.pure(a).flatMap(fn).equals(fn.apply(a))
                ? nothing()
                : just("left identity (m.pure(a).flatMap(fn).equals(fn.apply(a)))");
@@ -47,15 +47,15 @@ private Maybe testRightIdentity(Monad m) {
 
     private Maybe testAssociativity(Monad m) {
         Fn1> f = constantly(m.pure(new Object()));
-        Function> g = constantly(m.pure(new Object()));
+        Fn1> g = constantly(m.pure(new Object()));
         return m.flatMap(f).flatMap(g).equals(m.flatMap(a -> f.apply(a).flatMap(g)))
                ? nothing()
                : just("associativity: (m.flatMap(f).flatMap(g).equals(m.flatMap(a -> f.apply(a).flatMap(g))))");
     }
 
     private Maybe testJoin(Monad m) {
-        Monad, M> mma = m.pure(m.fmap(upcast()));
-        boolean equals = mma.flatMap(id()).equals(join(mma));
+        Monad, M> mma    = m.pure(m.fmap(upcast()));
+        boolean                    equals = mma.flatMap(id()).equals(join(mma));
         return equals
                ? nothing()
                : just("join: (m.pure(m).flatMap(id())).equals(Monad.join(m.pure(m)))");
diff --git a/src/test/java/testsupport/traits/TraversableLaws.java b/src/test/java/testsupport/traits/TraversableLaws.java
index a9095fd97..3939c3c3d 100644
--- a/src/test/java/testsupport/traits/TraversableLaws.java
+++ b/src/test/java/testsupport/traits/TraversableLaws.java
@@ -2,6 +2,7 @@
 
 import com.jnape.palatable.lambda.adt.Either;
 import com.jnape.palatable.lambda.adt.Maybe;
+import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functor.Applicative;
 import com.jnape.palatable.lambda.functor.builtin.Compose;
 import com.jnape.palatable.lambda.functor.builtin.Identity;
@@ -23,29 +24,32 @@ public class TraversableLaws> implements Trait
     @Override
     public void test(Traversable traversable) {
         Present.present((x, y) -> x + "\n\t - " + y)
-                ., Maybe>>foldMap(
+                ., Maybe>>foldMap(
                         f -> f.apply(traversable),
                         asList(this::testNaturality,
                                this::testIdentity,
                                this::testComposition)
                 )
                 .peek(s -> {
-                    throw new AssertionError("The following Traversable laws did not hold for instance of " + traversable.getClass() + ": \n\t - " + s);
+                    throw new AssertionError("The following Traversable laws did not hold for instance of "
+                                                     + traversable.getClass() + ": \n\t - " + s);
                 });
     }
 
     private Maybe testNaturality(Traversable trav) {
-        Function> f = Identity::new;
-        Function, Either> t = id -> right(id.runIdentity());
+        Fn1>                 f = Identity::new;
+        Fn1, Either> t = id -> right(id.runIdentity());
 
-        Function, Applicative, Identity>> pureFn = x -> new Identity<>(x);
-        Function, Applicative, Either>> pureFn2 = x -> right(x);
+        Fn1, Applicative, Identity>> pureFn =
+                x -> new Identity<>(x);
+        Fn1, Applicative, Either>> pureFn2 =
+                x -> right(x);
 
         return t.apply(trav.traverse(f, pureFn).fmap(id()).coerce())
-                       .equals(trav.traverse(t.compose(f), pureFn2).fmap(id()).coerce())
+                       .equals(trav.traverse(t.contraMap(f), pureFn2).fmap(id()).coerce())
                ? nothing()
                : just("naturality (t.apply(trav.traverse(f, pureFn).fmap(id()).coerce())\n" +
-                              "                .equals(trav.traverse(t.compose(f), pureFn2).fmap(id()).coerce()))");
+                              "                .equals(trav.traverse(t.contraMap(f), pureFn2).fmap(id()).coerce()))");
     }
 
     private Maybe testIdentity(Traversable trav) {
@@ -55,13 +59,13 @@ private Maybe testIdentity(Traversable trav) {
     }
 
     private Maybe testComposition(Traversable trav) {
-        Function> f = Identity::new;
-        Function>> g = x -> new Identity<>(x);
+        Fn1>                 f = Identity::new;
+        Fn1>> g = x -> new Identity<>(x);
 
-        return trav.traverse(f.andThen(x -> x.fmap(g)).andThen(Compose::new), x -> new Compose<>(new Identity<>(new Identity<>(x))))
+        return trav.traverse(f.fmap(x -> x.fmap(g)).fmap(Compose::new), x -> new Compose<>(new Identity<>(new Identity<>(x))))
                        .equals(new Compose<>(trav.traverse(f, x -> new Identity<>(x)).fmap(t -> t.traverse(g, x -> new Identity<>(x)))))
                ? nothing()
-               : just("compose (trav.traverse(f.andThen(x -> x.fmap(g)).andThen(Compose::new), x -> new Compose<>(new Identity<>(new Identity<>(x))))\n" +
+               : just("compose (trav.traverse(f.fmap(x -> x.fmap(g)).fmap(Compose::new), x -> new Compose<>(new Identity<>(new Identity<>(x))))\n" +
                               "                .equals(new Compose>(trav.traverse(f, x -> new Identity<>(x)).fmap(t -> t.traverse(g, x -> new Identity<>(x))))))");
     }
 }

From 70f4a1073cedccdb55baf2c1b4b8f0fa1275a81e Mon Sep 17 00:00:00 2001
From: jnape 
Date: Thu, 9 May 2019 20:12:00 -0500
Subject: [PATCH 39/69] Moving all internal classes to internal package

---
 src/main/java/com/jnape/palatable/lambda/adt/Try.java        | 4 ++--
 .../java/com/jnape/palatable/lambda/functions/Effect.java    | 2 +-
 src/main/java/com/jnape/palatable/lambda/functions/Fn1.java  | 2 +-
 src/main/java/com/jnape/palatable/lambda/functions/Fn2.java  | 3 +--
 src/main/java/com/jnape/palatable/lambda/functions/Fn3.java  | 2 +-
 src/main/java/com/jnape/palatable/lambda/functions/Fn4.java  | 2 +-
 src/main/java/com/jnape/palatable/lambda/functions/Fn5.java  | 2 +-
 src/main/java/com/jnape/palatable/lambda/functions/Fn6.java  | 2 +-
 src/main/java/com/jnape/palatable/lambda/functions/Fn7.java  | 2 +-
 src/main/java/com/jnape/palatable/lambda/functions/Fn8.java  | 2 +-
 .../jnape/palatable/lambda/functions/builtin/fn1/Cycle.java  | 2 +-
 .../palatable/lambda/functions/builtin/fn1/Distinct.java     | 2 +-
 .../palatable/lambda/functions/builtin/fn1/Flatten.java      | 2 +-
 .../jnape/palatable/lambda/functions/builtin/fn1/Init.java   | 2 +-
 .../jnape/palatable/lambda/functions/builtin/fn1/Repeat.java | 2 +-
 .../palatable/lambda/functions/builtin/fn1/Reverse.java      | 2 +-
 .../lambda/functions/builtin/fn2/CartesianProduct.java       | 2 +-
 .../jnape/palatable/lambda/functions/builtin/fn2/Cons.java   | 2 +-
 .../jnape/palatable/lambda/functions/builtin/fn2/Drop.java   | 2 +-
 .../palatable/lambda/functions/builtin/fn2/DropWhile.java    | 2 +-
 .../jnape/palatable/lambda/functions/builtin/fn2/Filter.java | 2 +-
 .../palatable/lambda/functions/builtin/fn2/InGroupsOf.java   | 2 +-
 .../jnape/palatable/lambda/functions/builtin/fn2/Map.java    | 2 +-
 .../palatable/lambda/functions/builtin/fn2/PrependAll.java   | 2 +-
 .../jnape/palatable/lambda/functions/builtin/fn2/Snoc.java   | 2 +-
 .../jnape/palatable/lambda/functions/builtin/fn2/Take.java   | 2 +-
 .../palatable/lambda/functions/builtin/fn2/TakeWhile.java    | 2 +-
 .../palatable/lambda/functions/builtin/fn2/Unfoldr.java      | 2 +-
 .../palatable/lambda/functions/builtin/fn3/ScanLeft.java     | 2 +-
 .../palatable/lambda/functions/builtin/fn3/ZipWith.java      | 4 +---
 .../palatable/lambda/functions/builtin/fn4/RateLimit.java    | 4 ++--
 .../lambda/functions/specialized/BiMonoidFactory.java        | 2 +-
 .../lambda/functions/specialized/MonoidFactory.java          | 2 +-
 .../jnape/palatable/lambda/functions/specialized/Pure.java   | 2 +-
 .../palatable/lambda/functions/specialized/SideEffect.java   | 2 +-
 .../{functions/specialized/checked => internal}/Runtime.java | 2 +-
 .../{ => internal}/iteration/CombinatorialIterator.java      | 2 +-
 .../{ => internal}/iteration/ConcatenatingIterable.java      | 2 +-
 .../lambda/{ => internal}/iteration/ConsingIterator.java     | 2 +-
 .../lambda/{ => internal}/iteration/CyclicIterable.java      | 2 +-
 .../lambda/{ => internal}/iteration/CyclicIterator.java      | 2 +-
 .../lambda/{ => internal}/iteration/DistinctIterable.java    | 2 +-
 .../lambda/{ => internal}/iteration/DroppingIterable.java    | 2 +-
 .../lambda/{ => internal}/iteration/DroppingIterator.java    | 2 +-
 .../lambda/{ => internal}/iteration/FilteringIterable.java   | 2 +-
 .../lambda/{ => internal}/iteration/FilteringIterator.java   | 2 +-
 .../lambda/{ => internal}/iteration/FlatteningIterator.java  | 2 +-
 .../lambda/{ => internal}/iteration/GroupingIterator.java    | 2 +-
 .../lambda/{ => internal}/iteration/ImmutableIterator.java   | 2 +-
 .../lambda/{ => internal}/iteration/ImmutableQueue.java      | 2 +-
 .../lambda/{ => internal}/iteration/ImmutableStack.java      | 2 +-
 .../lambda/{ => internal}/iteration/InfiniteIterator.java    | 2 +-
 .../lambda/{ => internal}/iteration/InitIterator.java        | 2 +-
 .../iteration/IterationInterruptedException.java             | 2 +-
 .../lambda/{ => internal}/iteration/MappingIterable.java     | 2 +-
 .../lambda/{ => internal}/iteration/MappingIterator.java     | 2 +-
 .../{ => internal}/iteration/PredicatedDroppingIterable.java | 2 +-
 .../{ => internal}/iteration/PredicatedDroppingIterator.java | 2 +-
 .../{ => internal}/iteration/PredicatedTakingIterable.java   | 2 +-
 .../{ => internal}/iteration/PredicatedTakingIterator.java   | 2 +-
 .../lambda/{ => internal}/iteration/PrependingIterator.java  | 2 +-
 .../{ => internal}/iteration/RateLimitingIterable.java       | 3 +--
 .../{ => internal}/iteration/RateLimitingIterator.java       | 2 +-
 .../lambda/{ => internal}/iteration/RepetitiousIterator.java | 2 +-
 .../lambda/{ => internal}/iteration/ReversingIterable.java   | 2 +-
 .../lambda/{ => internal}/iteration/ReversingIterator.java   | 2 +-
 .../lambda/{ => internal}/iteration/RewindableIterator.java  | 2 +-
 .../lambda/{ => internal}/iteration/ScanningIterator.java    | 2 +-
 .../lambda/{ => internal}/iteration/SnocIterable.java        | 2 +-
 .../lambda/{ => internal}/iteration/SnocIterator.java        | 2 +-
 .../lambda/{ => internal}/iteration/TakingIterable.java      | 2 +-
 .../lambda/{ => internal}/iteration/TakingIterator.java      | 2 +-
 .../lambda/{ => internal}/iteration/UnfoldingIterator.java   | 2 +-
 .../lambda/{ => internal}/iteration/UnioningIterable.java    | 2 +-
 .../lambda/{ => internal}/iteration/ZippingIterator.java     | 2 +-
 .../com/jnape/palatable/lambda/monoid/builtin/Concat.java    | 2 +-
 .../com/jnape/palatable/lambda/monoid/builtin/Union.java     | 2 +-
 .../lambda/functions/builtin/fn4/RateLimitTest.java          | 3 +--
 .../{ => internal}/iteration/CombinatorialIteratorTest.java  | 2 +-
 .../{ => internal}/iteration/ConcatenatingIterableTest.java  | 2 +-
 .../lambda/{ => internal}/iteration/ConsingIteratorTest.java | 2 +-
 .../lambda/{ => internal}/iteration/CyclicIterableTest.java  | 2 +-
 .../lambda/{ => internal}/iteration/CyclicIteratorTest.java  | 2 +-
 .../{ => internal}/iteration/DistinctIterableTest.java       | 2 +-
 .../{ => internal}/iteration/DroppingIterableTest.java       | 2 +-
 .../{ => internal}/iteration/DroppingIteratorTest.java       | 2 +-
 .../{ => internal}/iteration/FilteringIterableTest.java      | 2 +-
 .../{ => internal}/iteration/FilteringIteratorTest.java      | 2 +-
 .../{ => internal}/iteration/FlatteningIteratorTest.java     | 2 +-
 .../{ => internal}/iteration/GroupingIteratorTest.java       | 2 +-
 .../{ => internal}/iteration/ImmutableIteratorTest.java      | 2 +-
 .../{ => internal}/iteration/InfiniteIteratorTest.java       | 2 +-
 .../lambda/{ => internal}/iteration/InitIteratorTest.java    | 2 +-
 .../lambda/{ => internal}/iteration/MappingIterableTest.java | 2 +-
 .../lambda/{ => internal}/iteration/MappingIteratorTest.java | 2 +-
 .../iteration/PredicatedDroppingIterableTest.java            | 2 +-
 .../iteration/PredicatedDroppingIteratorTest.java            | 2 +-
 .../iteration/PredicatedTakingIterableTest.java              | 2 +-
 .../iteration/PredicatedTakingIteratorTest.java              | 2 +-
 .../{ => internal}/iteration/PrependingIteratorTest.java     | 2 +-
 .../{ => internal}/iteration/RepetitiousIteratorTest.java    | 2 +-
 .../{ => internal}/iteration/ReversingIterableTest.java      | 2 +-
 .../{ => internal}/iteration/ReversingIteratorTest.java      | 2 +-
 .../{ => internal}/iteration/RewindableIteratorTest.java     | 2 +-
 .../{ => internal}/iteration/ScanningIteratorTest.java       | 2 +-
 .../lambda/{ => internal}/iteration/SnocIterableTest.java    | 2 +-
 .../lambda/{ => internal}/iteration/SnocIteratorTest.java    | 2 +-
 .../lambda/{ => internal}/iteration/TakingIterableTest.java  | 2 +-
 .../lambda/{ => internal}/iteration/TakingIteratorTest.java  | 5 +++--
 .../{ => internal}/iteration/UnfoldingIteratorTest.java      | 2 +-
 .../{ => internal}/iteration/UnioningIterableTest.java       | 2 +-
 .../lambda/{ => internal}/iteration/ZippingIteratorTest.java | 2 +-
 112 files changed, 116 insertions(+), 120 deletions(-)
 rename src/main/java/com/jnape/palatable/lambda/{functions/specialized/checked => internal}/Runtime.java (76%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/CombinatorialIterator.java (96%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/ConcatenatingIterable.java (94%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/ConsingIterator.java (95%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/CyclicIterable.java (88%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/CyclicIterator.java (94%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/DistinctIterable.java (91%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/DroppingIterable.java (91%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/DroppingIterator.java (93%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/FilteringIterable.java (95%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/FilteringIterator.java (95%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/FlatteningIterator.java (92%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/GroupingIterator.java (92%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/ImmutableIterator.java (81%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/ImmutableQueue.java (98%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/ImmutableStack.java (97%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/InfiniteIterator.java (73%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/InitIterator.java (92%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/IterationInterruptedException.java (88%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/MappingIterable.java (95%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/MappingIterator.java (91%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/PredicatedDroppingIterable.java (95%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/PredicatedDroppingIterator.java (95%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/PredicatedTakingIterable.java (95%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/PredicatedTakingIterator.java (95%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/PrependingIterator.java (93%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/RateLimitingIterable.java (92%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/RateLimitingIterator.java (98%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/RepetitiousIterator.java (81%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/ReversingIterable.java (92%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/ReversingIterator.java (94%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/RewindableIterator.java (96%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/ScanningIterator.java (94%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/SnocIterable.java (93%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/SnocIterator.java (91%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/TakingIterable.java (91%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/TakingIterator.java (92%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/UnfoldingIterator.java (95%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/UnioningIterable.java (92%)
 rename src/main/java/com/jnape/palatable/lambda/{ => internal}/iteration/ZippingIterator.java (93%)
 rename src/test/java/com/jnape/palatable/lambda/{ => internal}/iteration/CombinatorialIteratorTest.java (97%)
 rename src/test/java/com/jnape/palatable/lambda/{ => internal}/iteration/ConcatenatingIterableTest.java (94%)
 rename src/test/java/com/jnape/palatable/lambda/{ => internal}/iteration/ConsingIteratorTest.java (97%)
 rename src/test/java/com/jnape/palatable/lambda/{ => internal}/iteration/CyclicIterableTest.java (88%)
 rename src/test/java/com/jnape/palatable/lambda/{ => internal}/iteration/CyclicIteratorTest.java (92%)
 rename src/test/java/com/jnape/palatable/lambda/{ => internal}/iteration/DistinctIterableTest.java (88%)
 rename src/test/java/com/jnape/palatable/lambda/{ => internal}/iteration/DroppingIterableTest.java (88%)
 rename src/test/java/com/jnape/palatable/lambda/{ => internal}/iteration/DroppingIteratorTest.java (95%)
 rename src/test/java/com/jnape/palatable/lambda/{ => internal}/iteration/FilteringIterableTest.java (91%)
 rename src/test/java/com/jnape/palatable/lambda/{ => internal}/iteration/FilteringIteratorTest.java (95%)
 rename src/test/java/com/jnape/palatable/lambda/{ => internal}/iteration/FlatteningIteratorTest.java (96%)
 rename src/test/java/com/jnape/palatable/lambda/{ => internal}/iteration/GroupingIteratorTest.java (96%)
 rename src/test/java/com/jnape/palatable/lambda/{ => internal}/iteration/ImmutableIteratorTest.java (92%)
 rename src/test/java/com/jnape/palatable/lambda/{ => internal}/iteration/InfiniteIteratorTest.java (93%)
 rename src/test/java/com/jnape/palatable/lambda/{ => internal}/iteration/InitIteratorTest.java (94%)
 rename src/test/java/com/jnape/palatable/lambda/{ => internal}/iteration/MappingIterableTest.java (91%)
 rename src/test/java/com/jnape/palatable/lambda/{ => internal}/iteration/MappingIteratorTest.java (91%)
 rename src/test/java/com/jnape/palatable/lambda/{ => internal}/iteration/PredicatedDroppingIterableTest.java (91%)
 rename src/test/java/com/jnape/palatable/lambda/{ => internal}/iteration/PredicatedDroppingIteratorTest.java (97%)
 rename src/test/java/com/jnape/palatable/lambda/{ => internal}/iteration/PredicatedTakingIterableTest.java (91%)
 rename src/test/java/com/jnape/palatable/lambda/{ => internal}/iteration/PredicatedTakingIteratorTest.java (98%)
 rename src/test/java/com/jnape/palatable/lambda/{ => internal}/iteration/PrependingIteratorTest.java (96%)
 rename src/test/java/com/jnape/palatable/lambda/{ => internal}/iteration/RepetitiousIteratorTest.java (93%)
 rename src/test/java/com/jnape/palatable/lambda/{ => internal}/iteration/ReversingIterableTest.java (90%)
 rename src/test/java/com/jnape/palatable/lambda/{ => internal}/iteration/ReversingIteratorTest.java (97%)
 rename src/test/java/com/jnape/palatable/lambda/{ => internal}/iteration/RewindableIteratorTest.java (97%)
 rename src/test/java/com/jnape/palatable/lambda/{ => internal}/iteration/ScanningIteratorTest.java (96%)
 rename src/test/java/com/jnape/palatable/lambda/{ => internal}/iteration/SnocIterableTest.java (89%)
 rename src/test/java/com/jnape/palatable/lambda/{ => internal}/iteration/SnocIteratorTest.java (95%)
 rename src/test/java/com/jnape/palatable/lambda/{ => internal}/iteration/TakingIterableTest.java (90%)
 rename src/test/java/com/jnape/palatable/lambda/{ => internal}/iteration/TakingIteratorTest.java (92%)
 rename src/test/java/com/jnape/palatable/lambda/{ => internal}/iteration/UnfoldingIteratorTest.java (96%)
 rename src/test/java/com/jnape/palatable/lambda/{ => internal}/iteration/UnioningIterableTest.java (94%)
 rename src/test/java/com/jnape/palatable/lambda/{ => internal}/iteration/ZippingIteratorTest.java (96%)

diff --git a/src/main/java/com/jnape/palatable/lambda/adt/Try.java b/src/main/java/com/jnape/palatable/lambda/adt/Try.java
index 3aeacead1..e89854b39 100644
--- a/src/main/java/com/jnape/palatable/lambda/adt/Try.java
+++ b/src/main/java/com/jnape/palatable/lambda/adt/Try.java
@@ -4,7 +4,6 @@
 import com.jnape.palatable.lambda.functions.Fn0;
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functions.specialized.SideEffect;
-import com.jnape.palatable.lambda.functions.specialized.checked.Runtime;
 import com.jnape.palatable.lambda.functor.Applicative;
 import com.jnape.palatable.lambda.functor.builtin.Lazy;
 import com.jnape.palatable.lambda.io.IO;
@@ -13,6 +12,7 @@
 
 import java.util.Objects;
 
+import static com.jnape.palatable.lambda.internal.Runtime.throwChecked;
 import static com.jnape.palatable.lambda.adt.Maybe.nothing;
 import static com.jnape.palatable.lambda.adt.Unit.UNIT;
 import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly;
@@ -354,7 +354,7 @@ private Failure(Throwable t) {
 
         @Override
         public A orThrow() {
-            throw Runtime.throwChecked(t);
+            throw throwChecked(t);
         }
 
         @Override
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Effect.java b/src/main/java/com/jnape/palatable/lambda/functions/Effect.java
index 8516c19c8..4fdfba136 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/Effect.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/Effect.java
@@ -2,7 +2,7 @@
 
 import com.jnape.palatable.lambda.adt.Unit;
 import com.jnape.palatable.lambda.functions.specialized.SideEffect;
-import com.jnape.palatable.lambda.functions.specialized.checked.Runtime;
+import com.jnape.palatable.lambda.internal.Runtime;
 import com.jnape.palatable.lambda.functor.Applicative;
 import com.jnape.palatable.lambda.io.IO;
 
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java
index 49c69d2de..9df14981a 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java
@@ -3,7 +3,7 @@
 import com.jnape.palatable.lambda.adt.Either;
 import com.jnape.palatable.lambda.adt.choice.Choice2;
 import com.jnape.palatable.lambda.adt.hlist.Tuple2;
-import com.jnape.palatable.lambda.functions.specialized.checked.Runtime;
+import com.jnape.palatable.lambda.internal.Runtime;
 import com.jnape.palatable.lambda.functor.Applicative;
 import com.jnape.palatable.lambda.functor.Cartesian;
 import com.jnape.palatable.lambda.functor.Cocartesian;
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn2.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn2.java
index 7620ea9a7..977082ed2 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/Fn2.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn2.java
@@ -1,11 +1,10 @@
 package com.jnape.palatable.lambda.functions;
 
 import com.jnape.palatable.lambda.adt.product.Product2;
-import com.jnape.palatable.lambda.functions.specialized.checked.Runtime;
+import com.jnape.palatable.lambda.internal.Runtime;
 import com.jnape.palatable.lambda.functor.Applicative;
 
 import java.util.function.BiFunction;
-import java.util.function.Function;
 
 import static com.jnape.palatable.lambda.functions.Fn3.fn3;
 import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly;
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn3.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn3.java
index 9003aa0ac..a225f7e3a 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/Fn3.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn3.java
@@ -1,7 +1,7 @@
 package com.jnape.palatable.lambda.functions;
 
 import com.jnape.palatable.lambda.adt.product.Product2;
-import com.jnape.palatable.lambda.functions.specialized.checked.Runtime;
+import com.jnape.palatable.lambda.internal.Runtime;
 import com.jnape.palatable.lambda.functor.Applicative;
 
 import static com.jnape.palatable.lambda.functions.Fn4.fn4;
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn4.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn4.java
index aa49270d5..e43dcda17 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/Fn4.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn4.java
@@ -1,7 +1,7 @@
 package com.jnape.palatable.lambda.functions;
 
 import com.jnape.palatable.lambda.adt.product.Product2;
-import com.jnape.palatable.lambda.functions.specialized.checked.Runtime;
+import com.jnape.palatable.lambda.internal.Runtime;
 import com.jnape.palatable.lambda.functor.Applicative;
 
 import static com.jnape.palatable.lambda.functions.Fn5.fn5;
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn5.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn5.java
index b0c0acfba..55364e8bb 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/Fn5.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn5.java
@@ -1,7 +1,7 @@
 package com.jnape.palatable.lambda.functions;
 
 import com.jnape.palatable.lambda.adt.product.Product2;
-import com.jnape.palatable.lambda.functions.specialized.checked.Runtime;
+import com.jnape.palatable.lambda.internal.Runtime;
 import com.jnape.palatable.lambda.functor.Applicative;
 
 import static com.jnape.palatable.lambda.functions.Fn6.fn6;
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn6.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn6.java
index 0f06798c6..5998bc9aa 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/Fn6.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn6.java
@@ -1,7 +1,7 @@
 package com.jnape.palatable.lambda.functions;
 
 import com.jnape.palatable.lambda.adt.product.Product2;
-import com.jnape.palatable.lambda.functions.specialized.checked.Runtime;
+import com.jnape.palatable.lambda.internal.Runtime;
 import com.jnape.palatable.lambda.functor.Applicative;
 
 import static com.jnape.palatable.lambda.functions.Fn7.fn7;
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn7.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn7.java
index 70b7ba3f6..87a3f8704 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/Fn7.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn7.java
@@ -1,7 +1,7 @@
 package com.jnape.palatable.lambda.functions;
 
 import com.jnape.palatable.lambda.adt.product.Product2;
-import com.jnape.palatable.lambda.functions.specialized.checked.Runtime;
+import com.jnape.palatable.lambda.internal.Runtime;
 import com.jnape.palatable.lambda.functor.Applicative;
 
 import static com.jnape.palatable.lambda.functions.Fn8.fn8;
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn8.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn8.java
index 040fa4346..4ead63674 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/Fn8.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn8.java
@@ -1,7 +1,7 @@
 package com.jnape.palatable.lambda.functions;
 
 import com.jnape.palatable.lambda.adt.product.Product2;
-import com.jnape.palatable.lambda.functions.specialized.checked.Runtime;
+import com.jnape.palatable.lambda.internal.Runtime;
 import com.jnape.palatable.lambda.functor.Applicative;
 
 /**
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Cycle.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Cycle.java
index 2c39f4391..a5aaaa25b 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Cycle.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Cycle.java
@@ -1,7 +1,7 @@
 package com.jnape.palatable.lambda.functions.builtin.fn1;
 
 import com.jnape.palatable.lambda.functions.Fn1;
-import com.jnape.palatable.lambda.iteration.CyclicIterable;
+import com.jnape.palatable.lambda.internal.iteration.CyclicIterable;
 
 import static java.util.Arrays.asList;
 
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Distinct.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Distinct.java
index aab8dfdb3..30b97dec4 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Distinct.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Distinct.java
@@ -1,7 +1,7 @@
 package com.jnape.palatable.lambda.functions.builtin.fn1;
 
 import com.jnape.palatable.lambda.functions.Fn1;
-import com.jnape.palatable.lambda.iteration.DistinctIterable;
+import com.jnape.palatable.lambda.internal.iteration.DistinctIterable;
 
 /**
  * Return an {@link Iterable} of the distinct values from the given input {@link Iterable}.
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Flatten.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Flatten.java
index c1f8c0f6d..812452965 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Flatten.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Flatten.java
@@ -1,7 +1,7 @@
 package com.jnape.palatable.lambda.functions.builtin.fn1;
 
 import com.jnape.palatable.lambda.functions.Fn1;
-import com.jnape.palatable.lambda.iteration.FlatteningIterator;
+import com.jnape.palatable.lambda.internal.iteration.FlatteningIterator;
 
 /**
  * Given a nested {@link Iterable} of {@link Iterable}s, return a lazily flattening {@link Iterable}
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Init.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Init.java
index bb75ad1b1..66cea88bf 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Init.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Init.java
@@ -1,7 +1,7 @@
 package com.jnape.palatable.lambda.functions.builtin.fn1;
 
 import com.jnape.palatable.lambda.functions.Fn1;
-import com.jnape.palatable.lambda.iteration.InitIterator;
+import com.jnape.palatable.lambda.internal.iteration.InitIterator;
 
 /**
  * Given an {@link Iterable}<A>, produce an
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Repeat.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Repeat.java
index 83c80e09a..0c91253d7 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Repeat.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Repeat.java
@@ -1,7 +1,7 @@
 package com.jnape.palatable.lambda.functions.builtin.fn1;
 
 import com.jnape.palatable.lambda.functions.Fn1;
-import com.jnape.palatable.lambda.iteration.RepetitiousIterator;
+import com.jnape.palatable.lambda.internal.iteration.RepetitiousIterator;
 
 /**
  * Given a value, return an infinite Iterable that repeatedly iterates that value.
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Reverse.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Reverse.java
index eaeecc014..54cbc5263 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Reverse.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn1/Reverse.java
@@ -1,7 +1,7 @@
 package com.jnape.palatable.lambda.functions.builtin.fn1;
 
 import com.jnape.palatable.lambda.functions.Fn1;
-import com.jnape.palatable.lambda.iteration.ReversingIterable;
+import com.jnape.palatable.lambda.internal.iteration.ReversingIterable;
 
 /**
  * Given an Iterable, return a reversed representation of that Iterable. Note that reversing
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/CartesianProduct.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/CartesianProduct.java
index 2ef85c703..17b5ca94b 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/CartesianProduct.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/CartesianProduct.java
@@ -3,7 +3,7 @@
 import com.jnape.palatable.lambda.adt.hlist.Tuple2;
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functions.Fn2;
-import com.jnape.palatable.lambda.iteration.CombinatorialIterator;
+import com.jnape.palatable.lambda.internal.iteration.CombinatorialIterator;
 
 /**
  * Lazily compute the cartesian product of an Iterable<A> and Iterable<B>,
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Cons.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Cons.java
index 7ad8405a0..63dabbaf2 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Cons.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Cons.java
@@ -2,7 +2,7 @@
 
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functions.Fn2;
-import com.jnape.palatable.lambda.iteration.ConsingIterator;
+import com.jnape.palatable.lambda.internal.iteration.ConsingIterator;
 
 /**
  * Prepend an element to an Iterable.
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Drop.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Drop.java
index c975a0efb..7229e51e9 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Drop.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Drop.java
@@ -2,7 +2,7 @@
 
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functions.Fn2;
-import com.jnape.palatable.lambda.iteration.DroppingIterable;
+import com.jnape.palatable.lambda.internal.iteration.DroppingIterable;
 
 /**
  * Lazily skip the first n elements from an Iterable by returning an Iterable
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/DropWhile.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/DropWhile.java
index f91d8ba15..a39ff3942 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/DropWhile.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/DropWhile.java
@@ -2,7 +2,7 @@
 
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functions.Fn2;
-import com.jnape.palatable.lambda.iteration.PredicatedDroppingIterable;
+import com.jnape.palatable.lambda.internal.iteration.PredicatedDroppingIterable;
 
 /**
  * Lazily limit the Iterable by skipping the first contiguous group of elements that satisfy the predicate,
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Filter.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Filter.java
index 2074ec59c..2b445ca11 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Filter.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Filter.java
@@ -2,7 +2,7 @@
 
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functions.Fn2;
-import com.jnape.palatable.lambda.iteration.FilteringIterable;
+import com.jnape.palatable.lambda.internal.iteration.FilteringIterable;
 
 /**
  * Lazily apply a predicate to each element in an Iterable, returning an Iterable of just the
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/InGroupsOf.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/InGroupsOf.java
index 5270cf60f..673d6c980 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/InGroupsOf.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/InGroupsOf.java
@@ -2,7 +2,7 @@
 
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functions.Fn2;
-import com.jnape.palatable.lambda.iteration.GroupingIterator;
+import com.jnape.palatable.lambda.internal.iteration.GroupingIterator;
 
 /**
  * Lazily group the Iterable by returning an Iterable of smaller Iterables of
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Map.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Map.java
index f5f37332b..ace10d667 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Map.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Map.java
@@ -2,7 +2,7 @@
 
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functions.Fn2;
-import com.jnape.palatable.lambda.iteration.MappingIterable;
+import com.jnape.palatable.lambda.internal.iteration.MappingIterable;
 
 /**
  * Lazily apply a function to each element in an Iterable, producing an Iterable of the mapped
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/PrependAll.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/PrependAll.java
index 7b2ed2a64..ad25f29f7 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/PrependAll.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/PrependAll.java
@@ -2,7 +2,7 @@
 
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functions.Fn2;
-import com.jnape.palatable.lambda.iteration.PrependingIterator;
+import com.jnape.palatable.lambda.internal.iteration.PrependingIterator;
 
 /**
  * Lazily prepend each value with of the Iterable with the supplied separator value. An empty
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Snoc.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Snoc.java
index 67fe1a137..bfd8007bc 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Snoc.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Snoc.java
@@ -2,7 +2,7 @@
 
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functions.Fn2;
-import com.jnape.palatable.lambda.iteration.SnocIterable;
+import com.jnape.palatable.lambda.internal.iteration.SnocIterable;
 
 /**
  * Opposite of {@link Cons}: lazily append an element to the end of the given {@link Iterable}.
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Take.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Take.java
index dbc55e349..15ddbcad2 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Take.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Take.java
@@ -2,7 +2,7 @@
 
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functions.Fn2;
-import com.jnape.palatable.lambda.iteration.TakingIterable;
+import com.jnape.palatable.lambda.internal.iteration.TakingIterable;
 
 /**
  * Lazily limit the Iterable to n elements by returning an Iterable that stops
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/TakeWhile.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/TakeWhile.java
index d0d051dce..07524b7b4 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/TakeWhile.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/TakeWhile.java
@@ -2,7 +2,7 @@
 
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functions.Fn2;
-import com.jnape.palatable.lambda.iteration.PredicatedTakingIterable;
+import com.jnape.palatable.lambda.internal.iteration.PredicatedTakingIterable;
 
 /**
  * Lazily limit the Iterable to the first group of contiguous elements that satisfy the predicate by
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Unfoldr.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Unfoldr.java
index aa451768b..dbf8c8480 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Unfoldr.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Unfoldr.java
@@ -4,7 +4,7 @@
 import com.jnape.palatable.lambda.adt.hlist.Tuple2;
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functions.Fn2;
-import com.jnape.palatable.lambda.iteration.UnfoldingIterator;
+import com.jnape.palatable.lambda.internal.iteration.UnfoldingIterator;
 
 /**
  * Given an initial seed value and a function that takes the seed type and produces an {@link Maybe}<{@link
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/ScanLeft.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/ScanLeft.java
index 49f77d96c..5db4f413a 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/ScanLeft.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/ScanLeft.java
@@ -3,7 +3,7 @@
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functions.Fn2;
 import com.jnape.palatable.lambda.functions.Fn3;
-import com.jnape.palatable.lambda.iteration.ScanningIterator;
+import com.jnape.palatable.lambda.internal.iteration.ScanningIterator;
 
 /**
  * Given an Iterable of As, a starting value B, and a
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/ZipWith.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/ZipWith.java
index 96c072bd2..f9af0c1f2 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/ZipWith.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/ZipWith.java
@@ -3,9 +3,7 @@
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functions.Fn2;
 import com.jnape.palatable.lambda.functions.Fn3;
-import com.jnape.palatable.lambda.iteration.ZippingIterator;
-
-import java.util.function.BiFunction;
+import com.jnape.palatable.lambda.internal.iteration.ZippingIterator;
 
 /**
  * Zip together two Iterables by applying a zipping function to the successive elements of each
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/RateLimit.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/RateLimit.java
index fa5a0844c..53d9b7189 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/RateLimit.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn4/RateLimit.java
@@ -5,8 +5,8 @@
 import com.jnape.palatable.lambda.functions.Fn2;
 import com.jnape.palatable.lambda.functions.Fn3;
 import com.jnape.palatable.lambda.functions.Fn4;
-import com.jnape.palatable.lambda.iteration.IterationInterruptedException;
-import com.jnape.palatable.lambda.iteration.RateLimitingIterable;
+import com.jnape.palatable.lambda.internal.iteration.IterationInterruptedException;
+import com.jnape.palatable.lambda.internal.iteration.RateLimitingIterable;
 
 import java.time.Duration;
 import java.time.Instant;
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/BiMonoidFactory.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/BiMonoidFactory.java
index a28e90614..198316f00 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/BiMonoidFactory.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/specialized/BiMonoidFactory.java
@@ -1,7 +1,7 @@
 package com.jnape.palatable.lambda.functions.specialized;
 
 import com.jnape.palatable.lambda.adt.product.Product2;
-import com.jnape.palatable.lambda.functions.specialized.checked.Runtime;
+import com.jnape.palatable.lambda.internal.Runtime;
 import com.jnape.palatable.lambda.monoid.Monoid;
 
 @FunctionalInterface
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/MonoidFactory.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/MonoidFactory.java
index e4d993def..1bcbb4314 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/MonoidFactory.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/specialized/MonoidFactory.java
@@ -1,6 +1,6 @@
 package com.jnape.palatable.lambda.functions.specialized;
 
-import com.jnape.palatable.lambda.functions.specialized.checked.Runtime;
+import com.jnape.palatable.lambda.internal.Runtime;
 import com.jnape.palatable.lambda.monoid.Monoid;
 
 public interface MonoidFactory extends SemigroupFactory {
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/Pure.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/Pure.java
index 0f63478f6..71d91b5c8 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/Pure.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/specialized/Pure.java
@@ -1,6 +1,6 @@
 package com.jnape.palatable.lambda.functions.specialized;
 
-import com.jnape.palatable.lambda.functions.specialized.checked.Runtime;
+import com.jnape.palatable.lambda.internal.Runtime;
 import com.jnape.palatable.lambda.functor.Applicative;
 import com.jnape.palatable.lambda.functor.Functor;
 
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/SideEffect.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/SideEffect.java
index 305fd900a..6295d4089 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/SideEffect.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/specialized/SideEffect.java
@@ -1,6 +1,6 @@
 package com.jnape.palatable.lambda.functions.specialized;
 
-import com.jnape.palatable.lambda.functions.specialized.checked.Runtime;
+import com.jnape.palatable.lambda.internal.Runtime;
 import com.jnape.palatable.lambda.io.IO;
 
 /**
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/Runtime.java b/src/main/java/com/jnape/palatable/lambda/internal/Runtime.java
similarity index 76%
rename from src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/Runtime.java
rename to src/main/java/com/jnape/palatable/lambda/internal/Runtime.java
index 5ba88fd93..a280744fe 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/checked/Runtime.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/Runtime.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.functions.specialized.checked;
+package com.jnape.palatable.lambda.internal;
 
 public final class Runtime {
 
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/CombinatorialIterator.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/CombinatorialIterator.java
similarity index 96%
rename from src/main/java/com/jnape/palatable/lambda/iteration/CombinatorialIterator.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/CombinatorialIterator.java
index 219582f4a..11922226a 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/CombinatorialIterator.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/CombinatorialIterator.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.adt.hlist.Tuple2;
 
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/ConcatenatingIterable.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/ConcatenatingIterable.java
similarity index 94%
rename from src/main/java/com/jnape/palatable/lambda/iteration/ConcatenatingIterable.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/ConcatenatingIterable.java
index f7ae08023..594be70b2 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/ConcatenatingIterable.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/ConcatenatingIterable.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import java.util.Iterator;
 
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/ConsingIterator.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/ConsingIterator.java
similarity index 95%
rename from src/main/java/com/jnape/palatable/lambda/iteration/ConsingIterator.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/ConsingIterator.java
index 5198f66f7..b560974bb 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/ConsingIterator.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/ConsingIterator.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.functions.Fn0;
 
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/CyclicIterable.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/CyclicIterable.java
similarity index 88%
rename from src/main/java/com/jnape/palatable/lambda/iteration/CyclicIterable.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/CyclicIterable.java
index 6d08dbcf2..3218892b2 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/CyclicIterable.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/CyclicIterable.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import java.util.Iterator;
 
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/CyclicIterator.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/CyclicIterator.java
similarity index 94%
rename from src/main/java/com/jnape/palatable/lambda/iteration/CyclicIterator.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/CyclicIterator.java
index 2705ffa06..827652a44 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/CyclicIterator.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/CyclicIterator.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import java.util.ArrayList;
 import java.util.Iterator;
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/DistinctIterable.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/DistinctIterable.java
similarity index 91%
rename from src/main/java/com/jnape/palatable/lambda/iteration/DistinctIterable.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/DistinctIterable.java
index 447b76168..19758a6df 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/DistinctIterable.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/DistinctIterable.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import java.util.HashMap;
 import java.util.Iterator;
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/DroppingIterable.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/DroppingIterable.java
similarity index 91%
rename from src/main/java/com/jnape/palatable/lambda/iteration/DroppingIterable.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/DroppingIterable.java
index b545a296f..1d9534b17 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/DroppingIterable.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/DroppingIterable.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import java.util.Iterator;
 
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/DroppingIterator.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/DroppingIterator.java
similarity index 93%
rename from src/main/java/com/jnape/palatable/lambda/iteration/DroppingIterator.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/DroppingIterator.java
index 5f69eb643..5b758695b 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/DroppingIterator.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/DroppingIterator.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import java.util.Iterator;
 import java.util.NoSuchElementException;
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/FilteringIterable.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/FilteringIterable.java
similarity index 95%
rename from src/main/java/com/jnape/palatable/lambda/iteration/FilteringIterable.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/FilteringIterable.java
index 7503e152a..7accde2f8 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/FilteringIterable.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/FilteringIterable.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.functions.Fn1;
 
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/FilteringIterator.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/FilteringIterator.java
similarity index 95%
rename from src/main/java/com/jnape/palatable/lambda/iteration/FilteringIterator.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/FilteringIterator.java
index d283a1129..4a9346d40 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/FilteringIterator.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/FilteringIterator.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.functions.Fn1;
 
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/FlatteningIterator.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/FlatteningIterator.java
similarity index 92%
rename from src/main/java/com/jnape/palatable/lambda/iteration/FlatteningIterator.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/FlatteningIterator.java
index 40458cd48..f02759374 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/FlatteningIterator.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/FlatteningIterator.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import java.util.Iterator;
 import java.util.NoSuchElementException;
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/GroupingIterator.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/GroupingIterator.java
similarity index 92%
rename from src/main/java/com/jnape/palatable/lambda/iteration/GroupingIterator.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/GroupingIterator.java
index fdaf95ebe..08d2f8c3f 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/GroupingIterator.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/GroupingIterator.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import java.util.ArrayList;
 import java.util.Iterator;
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/ImmutableIterator.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/ImmutableIterator.java
similarity index 81%
rename from src/main/java/com/jnape/palatable/lambda/iteration/ImmutableIterator.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/ImmutableIterator.java
index 7252d2313..cc41f275d 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/ImmutableIterator.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/ImmutableIterator.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import java.util.Iterator;
 
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/ImmutableQueue.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/ImmutableQueue.java
similarity index 98%
rename from src/main/java/com/jnape/palatable/lambda/iteration/ImmutableQueue.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/ImmutableQueue.java
index c7b109d3b..1b683c870 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/ImmutableQueue.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/ImmutableQueue.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.adt.Maybe;
 
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/ImmutableStack.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/ImmutableStack.java
similarity index 97%
rename from src/main/java/com/jnape/palatable/lambda/iteration/ImmutableStack.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/ImmutableStack.java
index e2ca4a8a2..a337ec21b 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/ImmutableStack.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/ImmutableStack.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.adt.Maybe;
 
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/InfiniteIterator.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/InfiniteIterator.java
similarity index 73%
rename from src/main/java/com/jnape/palatable/lambda/iteration/InfiniteIterator.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/InfiniteIterator.java
index 88b7c640d..f136da18d 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/InfiniteIterator.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/InfiniteIterator.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 public abstract class InfiniteIterator extends ImmutableIterator {
     @Override
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/InitIterator.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/InitIterator.java
similarity index 92%
rename from src/main/java/com/jnape/palatable/lambda/iteration/InitIterator.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/InitIterator.java
index 0b1daa4e9..31eed515f 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/InitIterator.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/InitIterator.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import java.util.Iterator;
 import java.util.NoSuchElementException;
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/IterationInterruptedException.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/IterationInterruptedException.java
similarity index 88%
rename from src/main/java/com/jnape/palatable/lambda/iteration/IterationInterruptedException.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/IterationInterruptedException.java
index ed3308961..c52797198 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/IterationInterruptedException.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/IterationInterruptedException.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.functions.builtin.fn4.RateLimit;
 
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/MappingIterable.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/MappingIterable.java
similarity index 95%
rename from src/main/java/com/jnape/palatable/lambda/iteration/MappingIterable.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/MappingIterable.java
index 4bffb3b3d..3d2f1ba65 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/MappingIterable.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/MappingIterable.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.functions.Fn1;
 
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/MappingIterator.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/MappingIterator.java
similarity index 91%
rename from src/main/java/com/jnape/palatable/lambda/iteration/MappingIterator.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/MappingIterator.java
index ed13cf281..6fb64fd90 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/MappingIterator.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/MappingIterator.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.functions.Fn1;
 
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/PredicatedDroppingIterable.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/PredicatedDroppingIterable.java
similarity index 95%
rename from src/main/java/com/jnape/palatable/lambda/iteration/PredicatedDroppingIterable.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/PredicatedDroppingIterable.java
index 591e561f5..d87cf0e09 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/PredicatedDroppingIterable.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/PredicatedDroppingIterable.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.functions.Fn1;
 
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/PredicatedDroppingIterator.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/PredicatedDroppingIterator.java
similarity index 95%
rename from src/main/java/com/jnape/palatable/lambda/iteration/PredicatedDroppingIterator.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/PredicatedDroppingIterator.java
index 8bbba7783..7add62a45 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/PredicatedDroppingIterator.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/PredicatedDroppingIterator.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.functions.Fn1;
 
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/PredicatedTakingIterable.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/PredicatedTakingIterable.java
similarity index 95%
rename from src/main/java/com/jnape/palatable/lambda/iteration/PredicatedTakingIterable.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/PredicatedTakingIterable.java
index 8a612fa11..de9c7682e 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/PredicatedTakingIterable.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/PredicatedTakingIterable.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.functions.Fn1;
 
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/PredicatedTakingIterator.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/PredicatedTakingIterator.java
similarity index 95%
rename from src/main/java/com/jnape/palatable/lambda/iteration/PredicatedTakingIterator.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/PredicatedTakingIterator.java
index 6d228ae85..9760450b0 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/PredicatedTakingIterator.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/PredicatedTakingIterator.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.functions.Fn1;
 
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/PrependingIterator.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/PrependingIterator.java
similarity index 93%
rename from src/main/java/com/jnape/palatable/lambda/iteration/PrependingIterator.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/PrependingIterator.java
index 53755c0f2..8914c2aca 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/PrependingIterator.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/PrependingIterator.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import java.util.Iterator;
 import java.util.NoSuchElementException;
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/RateLimitingIterable.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/RateLimitingIterable.java
similarity index 92%
rename from src/main/java/com/jnape/palatable/lambda/iteration/RateLimitingIterable.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/RateLimitingIterable.java
index 63bb5611f..3a7c856d4 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/RateLimitingIterable.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/RateLimitingIterable.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.adt.hlist.Tuple3;
 import com.jnape.palatable.lambda.functions.Fn0;
@@ -8,7 +8,6 @@
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Set;
-import java.util.function.Supplier;
 
 public final class RateLimitingIterable implements Iterable {
     private final Iterable                               as;
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/RateLimitingIterator.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/RateLimitingIterator.java
similarity index 98%
rename from src/main/java/com/jnape/palatable/lambda/iteration/RateLimitingIterator.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/RateLimitingIterator.java
index 057106dd9..1046f406c 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/RateLimitingIterator.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/RateLimitingIterator.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.adt.Try;
 import com.jnape.palatable.lambda.adt.hlist.Tuple3;
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/RepetitiousIterator.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/RepetitiousIterator.java
similarity index 81%
rename from src/main/java/com/jnape/palatable/lambda/iteration/RepetitiousIterator.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/RepetitiousIterator.java
index 51a6715a5..55652d4c4 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/RepetitiousIterator.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/RepetitiousIterator.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 public final class RepetitiousIterator extends InfiniteIterator {
 
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/ReversingIterable.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/ReversingIterable.java
similarity index 92%
rename from src/main/java/com/jnape/palatable/lambda/iteration/ReversingIterable.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/ReversingIterable.java
index df4c25e45..29aff81db 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/ReversingIterable.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/ReversingIterable.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import java.util.Iterator;
 
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/ReversingIterator.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/ReversingIterator.java
similarity index 94%
rename from src/main/java/com/jnape/palatable/lambda/iteration/ReversingIterator.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/ReversingIterator.java
index 428898058..70e1baa60 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/ReversingIterator.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/ReversingIterator.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import java.util.ArrayList;
 import java.util.Iterator;
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/RewindableIterator.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/RewindableIterator.java
similarity index 96%
rename from src/main/java/com/jnape/palatable/lambda/iteration/RewindableIterator.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/RewindableIterator.java
index d4de2c5d7..5bdde4312 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/RewindableIterator.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/RewindableIterator.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import java.util.Iterator;
 import java.util.NoSuchElementException;
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/ScanningIterator.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/ScanningIterator.java
similarity index 94%
rename from src/main/java/com/jnape/palatable/lambda/iteration/ScanningIterator.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/ScanningIterator.java
index 187982cca..43fc4ece5 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/ScanningIterator.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/ScanningIterator.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.functions.Fn2;
 
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/SnocIterable.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/SnocIterable.java
similarity index 93%
rename from src/main/java/com/jnape/palatable/lambda/iteration/SnocIterable.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/SnocIterable.java
index a16947b4a..9a0118200 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/SnocIterable.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/SnocIterable.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import java.util.Collections;
 import java.util.Iterator;
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/SnocIterator.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/SnocIterator.java
similarity index 91%
rename from src/main/java/com/jnape/palatable/lambda/iteration/SnocIterator.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/SnocIterator.java
index 7c084c7ab..e3c336a91 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/SnocIterator.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/SnocIterator.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import java.util.Iterator;
 import java.util.NoSuchElementException;
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/TakingIterable.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/TakingIterable.java
similarity index 91%
rename from src/main/java/com/jnape/palatable/lambda/iteration/TakingIterable.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/TakingIterable.java
index ce67f8e89..f228b596a 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/TakingIterable.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/TakingIterable.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import java.util.Iterator;
 
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/TakingIterator.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/TakingIterator.java
similarity index 92%
rename from src/main/java/com/jnape/palatable/lambda/iteration/TakingIterator.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/TakingIterator.java
index 3b558d68e..900f7ddb7 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/TakingIterator.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/TakingIterator.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import java.util.Iterator;
 import java.util.NoSuchElementException;
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/UnfoldingIterator.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/UnfoldingIterator.java
similarity index 95%
rename from src/main/java/com/jnape/palatable/lambda/iteration/UnfoldingIterator.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/UnfoldingIterator.java
index 146b19126..7ed719046 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/UnfoldingIterator.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/UnfoldingIterator.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.adt.Maybe;
 import com.jnape.palatable.lambda.adt.hlist.Tuple2;
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/UnioningIterable.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/UnioningIterable.java
similarity index 92%
rename from src/main/java/com/jnape/palatable/lambda/iteration/UnioningIterable.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/UnioningIterable.java
index 641ab8255..fc4c6ed60 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/UnioningIterable.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/UnioningIterable.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import java.util.Iterator;
 
diff --git a/src/main/java/com/jnape/palatable/lambda/iteration/ZippingIterator.java b/src/main/java/com/jnape/palatable/lambda/internal/iteration/ZippingIterator.java
similarity index 93%
rename from src/main/java/com/jnape/palatable/lambda/iteration/ZippingIterator.java
rename to src/main/java/com/jnape/palatable/lambda/internal/iteration/ZippingIterator.java
index 20175de5c..107a6ec08 100644
--- a/src/main/java/com/jnape/palatable/lambda/iteration/ZippingIterator.java
+++ b/src/main/java/com/jnape/palatable/lambda/internal/iteration/ZippingIterator.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.functions.Fn2;
 
diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Concat.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Concat.java
index 002834bd1..83c7c31c8 100644
--- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Concat.java
+++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Concat.java
@@ -1,7 +1,7 @@
 package com.jnape.palatable.lambda.monoid.builtin;
 
 import com.jnape.palatable.lambda.functions.Fn1;
-import com.jnape.palatable.lambda.iteration.ConcatenatingIterable;
+import com.jnape.palatable.lambda.internal.iteration.ConcatenatingIterable;
 import com.jnape.palatable.lambda.monoid.Monoid;
 
 import java.util.Collections;
diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Union.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Union.java
index 8da150dc5..283bd2980 100644
--- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Union.java
+++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Union.java
@@ -2,7 +2,7 @@
 
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.lambda.functions.builtin.fn1.Distinct;
-import com.jnape.palatable.lambda.iteration.UnioningIterable;
+import com.jnape.palatable.lambda.internal.iteration.UnioningIterable;
 import com.jnape.palatable.lambda.monoid.Monoid;
 
 import java.util.Collections;
diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn4/RateLimitTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn4/RateLimitTest.java
index a03305b74..b91b92b08 100644
--- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn4/RateLimitTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn4/RateLimitTest.java
@@ -1,8 +1,7 @@
 package com.jnape.palatable.lambda.functions.builtin.fn4;
 
 import com.jnape.palatable.lambda.functions.Fn1;
-import com.jnape.palatable.lambda.functions.specialized.SideEffect;
-import com.jnape.palatable.lambda.iteration.IterationInterruptedException;
+import com.jnape.palatable.lambda.internal.iteration.IterationInterruptedException;
 import com.jnape.palatable.traitor.annotations.TestTraits;
 import com.jnape.palatable.traitor.runners.Traits;
 import org.junit.Before;
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/CombinatorialIteratorTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/CombinatorialIteratorTest.java
similarity index 97%
rename from src/test/java/com/jnape/palatable/lambda/iteration/CombinatorialIteratorTest.java
rename to src/test/java/com/jnape/palatable/lambda/internal/iteration/CombinatorialIteratorTest.java
index 7678bd2c4..639136dd7 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/CombinatorialIteratorTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/CombinatorialIteratorTest.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/ConcatenatingIterableTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/ConcatenatingIterableTest.java
similarity index 94%
rename from src/test/java/com/jnape/palatable/lambda/iteration/ConcatenatingIterableTest.java
rename to src/test/java/com/jnape/palatable/lambda/internal/iteration/ConcatenatingIterableTest.java
index c82efdc70..92ffd28b9 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/ConcatenatingIterableTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/ConcatenatingIterableTest.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.traitor.annotations.TestTraits;
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/ConsingIteratorTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/ConsingIteratorTest.java
similarity index 97%
rename from src/test/java/com/jnape/palatable/lambda/iteration/ConsingIteratorTest.java
rename to src/test/java/com/jnape/palatable/lambda/internal/iteration/ConsingIteratorTest.java
index 301108b0f..85f6c6ba0 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/ConsingIteratorTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/ConsingIteratorTest.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/CyclicIterableTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/CyclicIterableTest.java
similarity index 88%
rename from src/test/java/com/jnape/palatable/lambda/iteration/CyclicIterableTest.java
rename to src/test/java/com/jnape/palatable/lambda/internal/iteration/CyclicIterableTest.java
index 66938afa1..a4ce12dce 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/CyclicIterableTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/CyclicIterableTest.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.traitor.annotations.TestTraits;
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/CyclicIteratorTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/CyclicIteratorTest.java
similarity index 92%
rename from src/test/java/com/jnape/palatable/lambda/iteration/CyclicIteratorTest.java
rename to src/test/java/com/jnape/palatable/lambda/internal/iteration/CyclicIteratorTest.java
index ba7e84485..5af519d32 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/CyclicIteratorTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/CyclicIteratorTest.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import org.junit.Test;
 
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/DistinctIterableTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/DistinctIterableTest.java
similarity index 88%
rename from src/test/java/com/jnape/palatable/lambda/iteration/DistinctIterableTest.java
rename to src/test/java/com/jnape/palatable/lambda/internal/iteration/DistinctIterableTest.java
index 69a2bd252..ae6d53ce5 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/DistinctIterableTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/DistinctIterableTest.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.traitor.annotations.TestTraits;
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/DroppingIterableTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/DroppingIterableTest.java
similarity index 88%
rename from src/test/java/com/jnape/palatable/lambda/iteration/DroppingIterableTest.java
rename to src/test/java/com/jnape/palatable/lambda/internal/iteration/DroppingIterableTest.java
index 52ab7899f..cccdd2878 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/DroppingIterableTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/DroppingIterableTest.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.traitor.annotations.TestTraits;
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/DroppingIteratorTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/DroppingIteratorTest.java
similarity index 95%
rename from src/test/java/com/jnape/palatable/lambda/iteration/DroppingIteratorTest.java
rename to src/test/java/com/jnape/palatable/lambda/internal/iteration/DroppingIteratorTest.java
index 9bbdad7ad..b13dc33d1 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/DroppingIteratorTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/DroppingIteratorTest.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/FilteringIterableTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/FilteringIterableTest.java
similarity index 91%
rename from src/test/java/com/jnape/palatable/lambda/iteration/FilteringIterableTest.java
rename to src/test/java/com/jnape/palatable/lambda/internal/iteration/FilteringIterableTest.java
index 7d1c645d6..b2f40b516 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/FilteringIterableTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/FilteringIterableTest.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.traitor.annotations.TestTraits;
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/FilteringIteratorTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/FilteringIteratorTest.java
similarity index 95%
rename from src/test/java/com/jnape/palatable/lambda/iteration/FilteringIteratorTest.java
rename to src/test/java/com/jnape/palatable/lambda/internal/iteration/FilteringIteratorTest.java
index 5f2c3cb7e..68f3ab567 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/FilteringIteratorTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/FilteringIteratorTest.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import org.junit.Test;
 
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/FlatteningIteratorTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/FlatteningIteratorTest.java
similarity index 96%
rename from src/test/java/com/jnape/palatable/lambda/iteration/FlatteningIteratorTest.java
rename to src/test/java/com/jnape/palatable/lambda/internal/iteration/FlatteningIteratorTest.java
index 7288e8fbc..ce286ecd2 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/FlatteningIteratorTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/FlatteningIteratorTest.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import org.junit.Test;
 
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/GroupingIteratorTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/GroupingIteratorTest.java
similarity index 96%
rename from src/test/java/com/jnape/palatable/lambda/iteration/GroupingIteratorTest.java
rename to src/test/java/com/jnape/palatable/lambda/internal/iteration/GroupingIteratorTest.java
index 0caab11a5..0288574d2 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/GroupingIteratorTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/GroupingIteratorTest.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/ImmutableIteratorTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/ImmutableIteratorTest.java
similarity index 92%
rename from src/test/java/com/jnape/palatable/lambda/iteration/ImmutableIteratorTest.java
rename to src/test/java/com/jnape/palatable/lambda/internal/iteration/ImmutableIteratorTest.java
index da73c4aef..15369f60a 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/ImmutableIteratorTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/ImmutableIteratorTest.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/InfiniteIteratorTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/InfiniteIteratorTest.java
similarity index 93%
rename from src/test/java/com/jnape/palatable/lambda/iteration/InfiniteIteratorTest.java
rename to src/test/java/com/jnape/palatable/lambda/internal/iteration/InfiniteIteratorTest.java
index 7ce772cf6..a2df8b32c 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/InfiniteIteratorTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/InfiniteIteratorTest.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/InitIteratorTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/InitIteratorTest.java
similarity index 94%
rename from src/test/java/com/jnape/palatable/lambda/iteration/InitIteratorTest.java
rename to src/test/java/com/jnape/palatable/lambda/internal/iteration/InitIteratorTest.java
index 04c512cb3..99f12dee2 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/InitIteratorTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/InitIteratorTest.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import org.junit.Test;
 
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/MappingIterableTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/MappingIterableTest.java
similarity index 91%
rename from src/test/java/com/jnape/palatable/lambda/iteration/MappingIterableTest.java
rename to src/test/java/com/jnape/palatable/lambda/internal/iteration/MappingIterableTest.java
index fdddf37e0..b86b95650 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/MappingIterableTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/MappingIterableTest.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.traitor.annotations.TestTraits;
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/MappingIteratorTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/MappingIteratorTest.java
similarity index 91%
rename from src/test/java/com/jnape/palatable/lambda/iteration/MappingIteratorTest.java
rename to src/test/java/com/jnape/palatable/lambda/internal/iteration/MappingIteratorTest.java
index c4522f8c1..396982cdc 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/MappingIteratorTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/MappingIteratorTest.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.functions.Fn1;
 import org.junit.Test;
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/PredicatedDroppingIterableTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/PredicatedDroppingIterableTest.java
similarity index 91%
rename from src/test/java/com/jnape/palatable/lambda/iteration/PredicatedDroppingIterableTest.java
rename to src/test/java/com/jnape/palatable/lambda/internal/iteration/PredicatedDroppingIterableTest.java
index 2202c2b98..55d6a3ef1 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/PredicatedDroppingIterableTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/PredicatedDroppingIterableTest.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.traitor.annotations.TestTraits;
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/PredicatedDroppingIteratorTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/PredicatedDroppingIteratorTest.java
similarity index 97%
rename from src/test/java/com/jnape/palatable/lambda/iteration/PredicatedDroppingIteratorTest.java
rename to src/test/java/com/jnape/palatable/lambda/internal/iteration/PredicatedDroppingIteratorTest.java
index 68f933a9a..bb3afa82f 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/PredicatedDroppingIteratorTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/PredicatedDroppingIteratorTest.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.functions.Fn1;
 import org.junit.Before;
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/PredicatedTakingIterableTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/PredicatedTakingIterableTest.java
similarity index 91%
rename from src/test/java/com/jnape/palatable/lambda/iteration/PredicatedTakingIterableTest.java
rename to src/test/java/com/jnape/palatable/lambda/internal/iteration/PredicatedTakingIterableTest.java
index bb8738cc5..e819c90f2 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/PredicatedTakingIterableTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/PredicatedTakingIterableTest.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.traitor.annotations.TestTraits;
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/PredicatedTakingIteratorTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/PredicatedTakingIteratorTest.java
similarity index 98%
rename from src/test/java/com/jnape/palatable/lambda/iteration/PredicatedTakingIteratorTest.java
rename to src/test/java/com/jnape/palatable/lambda/internal/iteration/PredicatedTakingIteratorTest.java
index 833ad43c8..70ba8953f 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/PredicatedTakingIteratorTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/PredicatedTakingIteratorTest.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.functions.specialized.Predicate;
 import org.junit.Test;
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/PrependingIteratorTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/PrependingIteratorTest.java
similarity index 96%
rename from src/test/java/com/jnape/palatable/lambda/iteration/PrependingIteratorTest.java
rename to src/test/java/com/jnape/palatable/lambda/internal/iteration/PrependingIteratorTest.java
index 84bdebc1a..4e922aa43 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/PrependingIteratorTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/PrependingIteratorTest.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import org.junit.Rule;
 import org.junit.Test;
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/RepetitiousIteratorTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/RepetitiousIteratorTest.java
similarity index 93%
rename from src/test/java/com/jnape/palatable/lambda/iteration/RepetitiousIteratorTest.java
rename to src/test/java/com/jnape/palatable/lambda/internal/iteration/RepetitiousIteratorTest.java
index bcf9d2628..f99823f25 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/RepetitiousIteratorTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/RepetitiousIteratorTest.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/ReversingIterableTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/ReversingIterableTest.java
similarity index 90%
rename from src/test/java/com/jnape/palatable/lambda/iteration/ReversingIterableTest.java
rename to src/test/java/com/jnape/palatable/lambda/internal/iteration/ReversingIterableTest.java
index e70b7cbd9..44ea4f446 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/ReversingIterableTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/ReversingIterableTest.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.traitor.annotations.TestTraits;
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/ReversingIteratorTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/ReversingIteratorTest.java
similarity index 97%
rename from src/test/java/com/jnape/palatable/lambda/iteration/ReversingIteratorTest.java
rename to src/test/java/com/jnape/palatable/lambda/internal/iteration/ReversingIteratorTest.java
index 391bcfb26..1fd9afce1 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/ReversingIteratorTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/ReversingIteratorTest.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/RewindableIteratorTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/RewindableIteratorTest.java
similarity index 97%
rename from src/test/java/com/jnape/palatable/lambda/iteration/RewindableIteratorTest.java
rename to src/test/java/com/jnape/palatable/lambda/internal/iteration/RewindableIteratorTest.java
index a8bee457c..532397934 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/RewindableIteratorTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/RewindableIteratorTest.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/ScanningIteratorTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/ScanningIteratorTest.java
similarity index 96%
rename from src/test/java/com/jnape/palatable/lambda/iteration/ScanningIteratorTest.java
rename to src/test/java/com/jnape/palatable/lambda/internal/iteration/ScanningIteratorTest.java
index 9405ee45a..43d24fad0 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/ScanningIteratorTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/ScanningIteratorTest.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.functions.Fn2;
 import org.junit.Test;
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/SnocIterableTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/SnocIterableTest.java
similarity index 89%
rename from src/test/java/com/jnape/palatable/lambda/iteration/SnocIterableTest.java
rename to src/test/java/com/jnape/palatable/lambda/internal/iteration/SnocIterableTest.java
index 258e872a3..6451e8b4f 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/SnocIterableTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/SnocIterableTest.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.traitor.annotations.TestTraits;
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/SnocIteratorTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/SnocIteratorTest.java
similarity index 95%
rename from src/test/java/com/jnape/palatable/lambda/iteration/SnocIteratorTest.java
rename to src/test/java/com/jnape/palatable/lambda/internal/iteration/SnocIteratorTest.java
index 6fca49817..96080f32b 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/SnocIteratorTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/SnocIteratorTest.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/TakingIterableTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/TakingIterableTest.java
similarity index 90%
rename from src/test/java/com/jnape/palatable/lambda/iteration/TakingIterableTest.java
rename to src/test/java/com/jnape/palatable/lambda/internal/iteration/TakingIterableTest.java
index b1bd84454..e72b6f060 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/TakingIterableTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/TakingIterableTest.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.traitor.annotations.TestTraits;
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/TakingIteratorTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/TakingIteratorTest.java
similarity index 92%
rename from src/test/java/com/jnape/palatable/lambda/iteration/TakingIteratorTest.java
rename to src/test/java/com/jnape/palatable/lambda/internal/iteration/TakingIteratorTest.java
index 9f17bcf4d..e6a03a6f2 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/TakingIteratorTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/TakingIteratorTest.java
@@ -1,7 +1,8 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import org.junit.Test;
 
+import java.util.Collections;
 import java.util.List;
 
 import static java.util.Arrays.asList;
@@ -40,7 +41,7 @@ public void doesNotHaveNextIfTakenAllOfIterable() {
 
     @Test
     public void doesNotHaveNextForEmptyIterable() {
-        TakingIterator takingIterator = new TakingIterator<>(3, emptyList().iterator());
+        TakingIterator takingIterator = new TakingIterator<>(3, Collections.emptyIterator());
         assertThat(takingIterator.hasNext(), is(false));
     }
 }
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/UnfoldingIteratorTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/UnfoldingIteratorTest.java
similarity index 96%
rename from src/test/java/com/jnape/palatable/lambda/iteration/UnfoldingIteratorTest.java
rename to src/test/java/com/jnape/palatable/lambda/internal/iteration/UnfoldingIteratorTest.java
index 68fa1ec9c..4b1199565 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/UnfoldingIteratorTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/UnfoldingIteratorTest.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.adt.Maybe;
 import com.jnape.palatable.lambda.adt.hlist.Tuple2;
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/UnioningIterableTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/UnioningIterableTest.java
similarity index 94%
rename from src/test/java/com/jnape/palatable/lambda/iteration/UnioningIterableTest.java
rename to src/test/java/com/jnape/palatable/lambda/internal/iteration/UnioningIterableTest.java
index dddec5ad9..b28bc2b61 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/UnioningIterableTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/UnioningIterableTest.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.functions.Fn1;
 import com.jnape.palatable.traitor.annotations.TestTraits;
diff --git a/src/test/java/com/jnape/palatable/lambda/iteration/ZippingIteratorTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/ZippingIteratorTest.java
similarity index 96%
rename from src/test/java/com/jnape/palatable/lambda/iteration/ZippingIteratorTest.java
rename to src/test/java/com/jnape/palatable/lambda/internal/iteration/ZippingIteratorTest.java
index 58b351f6f..96e655db0 100644
--- a/src/test/java/com/jnape/palatable/lambda/iteration/ZippingIteratorTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/ZippingIteratorTest.java
@@ -1,4 +1,4 @@
-package com.jnape.palatable.lambda.iteration;
+package com.jnape.palatable.lambda.internal.iteration;
 
 import com.jnape.palatable.lambda.functions.Fn2;
 import org.junit.Before;

From d27225cc559c77964774736a15e45a7f21422a56 Mon Sep 17 00:00:00 2001
From: jnape 
Date: Thu, 9 May 2019 20:18:19 -0500
Subject: [PATCH 40/69] Improving inference for Pure

---
 .../jnape/palatable/lambda/functions/specialized/Pure.java | 7 ++++---
 src/main/java/com/jnape/palatable/lambda/optics/Prism.java | 2 +-
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/Pure.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/Pure.java
index 71d91b5c8..a49cf98b6 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/Pure.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/specialized/Pure.java
@@ -1,8 +1,8 @@
 package com.jnape.palatable.lambda.functions.specialized;
 
-import com.jnape.palatable.lambda.internal.Runtime;
 import com.jnape.palatable.lambda.functor.Applicative;
 import com.jnape.palatable.lambda.functor.Functor;
+import com.jnape.palatable.lambda.internal.Runtime;
 
 /**
  * Generalized, portable {@link Applicative#pure(Object)}, with a loosened {@link Functor} constraint.
@@ -14,9 +14,10 @@ public interface Pure> {
 
      Functor checkedApply(A a) throws Throwable;
 
-    default  Functor apply(A a) {
+    default > FA apply(A a) {
         try {
-            return checkedApply(a);
+            @SuppressWarnings("unchecked") FA fa = (FA) checkedApply(a);
+            return fa;
         } catch (Throwable t) {
             throw Runtime.throwChecked(t);
         }
diff --git a/src/main/java/com/jnape/palatable/lambda/optics/Prism.java b/src/main/java/com/jnape/palatable/lambda/optics/Prism.java
index b52f67fd0..d83f01774 100644
--- a/src/main/java/com/jnape/palatable/lambda/optics/Prism.java
+++ b/src/main/java/com/jnape/palatable/lambda/optics/Prism.java
@@ -95,7 +95,7 @@ static  Prism prism(Fn1, ?>,
                         Cocartesian, ?>>optic(pafb -> pafb.cocartesian()
                         .diMap(s -> sta.apply(s).match(Choice2::a, Choice2::b),
-                               tOrFb -> tOrFb.match(pure::apply, fb -> fb.fmap(bt))));
+                               tOrFb -> tOrFb.>match(pure::apply, fb -> fb.fmap(bt))));
             }
         };
     }

From d32692ce987588e3385513c9ecf36e38c81f0db0 Mon Sep 17 00:00:00 2001
From: jnape 
Date: Thu, 9 May 2019 20:20:52 -0500
Subject: [PATCH 41/69] Removing Noop and offering a constant SideEffect NOOP

---
 CHANGELOG.md                                  |  1 +
 .../lambda/functions/specialized/Noop.java    | 36 -------------------
 .../functions/specialized/SideEffect.java     |  5 +++
 3 files changed, 6 insertions(+), 36 deletions(-)
 delete mode 100644 src/main/java/com/jnape/palatable/lambda/functions/specialized/Noop.java

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 76b7ca7cb..c74f691eb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -43,6 +43,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
 - `Market`, `Tagged`, profunctors supporting optics 
 - `Re` for viewing an `Optic` in one direction reliably
 - `Pre` for viewing at most one value from an `Optic` in one direction
+- `SideEffect`, for representing side-effects runnable by `IO`
 
 ## [3.3.0] - 2019-02-18
 ### Added
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/Noop.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/Noop.java
deleted file mode 100644
index 73a867626..000000000
--- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/Noop.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.jnape.palatable.lambda.functions.specialized;
-
-import com.jnape.palatable.lambda.adt.Unit;
-import com.jnape.palatable.lambda.functions.Effect;
-import com.jnape.palatable.lambda.io.IO;
-
-import static com.jnape.palatable.lambda.adt.Unit.UNIT;
-import static com.jnape.palatable.lambda.io.IO.io;
-
-/**
- * As the name might suggest, this is an {@link Effect} that, *ahem*, has no effect.
- *
- * @param  the argument type
- */
-public final class Noop implements Effect {
-    private static final Noop INSTANCE = new Noop<>();
-
-    private Noop() {
-    }
-
-    @Override
-    public IO checkedApply(A a) throws Throwable {
-        return io(UNIT);
-    }
-
-    /**
-     * Static factory method that returns the singleton {@link Noop} instance.
-     *
-     * @param  the argument type
-     * @return the singleton {@link Noop} instance
-     */
-    @SuppressWarnings("unchecked")
-    public static  Noop noop() {
-        return (Noop) INSTANCE;
-    }
-}
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/SideEffect.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/SideEffect.java
index 6295d4089..f0872ed9e 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/SideEffect.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/specialized/SideEffect.java
@@ -14,6 +14,11 @@
  */
 public interface SideEffect {
 
+    /**
+     * A no-op {@link SideEffect}
+     */
+    @SuppressWarnings("unused") SideEffect NOOP = () -> {};
+
     @SuppressWarnings("NonAsciiCharacters")
     void Ω() throws Throwable;
 

From e8a0352fc0501e2e9a48c8b1b9ea003da109953c Mon Sep 17 00:00:00 2001
From: jnape 
Date: Sat, 11 May 2019 17:04:17 -0500
Subject: [PATCH 42/69] IO#safe, IO#ensuring, and IO#throwing

---
 CHANGELOG.md                                  |  3 +
 .../com/jnape/palatable/lambda/io/IO.java     | 40 +++++++++++
 .../com/jnape/palatable/lambda/io/IOTest.java | 67 +++++++++++++++++++
 3 files changed, 110 insertions(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index c74f691eb..106373584 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -44,6 +44,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
 - `Re` for viewing an `Optic` in one direction reliably
 - `Pre` for viewing at most one value from an `Optic` in one direction
 - `SideEffect`, for representing side-effects runnable by `IO`
+- `IO#safe`, mapping an `IO` to an `IO>` that will never throw
+- `IO#ensuring`, like `finally` semantics for `IO`s
+- `IO#throwing`, for producing an `IO` that will throw a given `Throwable` when executed
 
 ## [3.3.0] - 2019-02-18
 ### Added
diff --git a/src/main/java/com/jnape/palatable/lambda/io/IO.java b/src/main/java/com/jnape/palatable/lambda/io/IO.java
index 2848da1fc..6036d1335 100644
--- a/src/main/java/com/jnape/palatable/lambda/io/IO.java
+++ b/src/main/java/com/jnape/palatable/lambda/io/IO.java
@@ -1,5 +1,6 @@
 package com.jnape.palatable.lambda.io;
 
+import com.jnape.palatable.lambda.adt.Either;
 import com.jnape.palatable.lambda.adt.Try;
 import com.jnape.palatable.lambda.adt.Unit;
 import com.jnape.palatable.lambda.adt.choice.Choice2;
@@ -19,11 +20,13 @@
 import static com.jnape.palatable.lambda.adt.choice.Choice2.a;
 import static com.jnape.palatable.lambda.adt.hlist.HList.tuple;
 import static com.jnape.palatable.lambda.functions.Fn0.fn0;
+import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly;
 import static com.jnape.palatable.lambda.functions.builtin.fn2.Into.into;
 import static com.jnape.palatable.lambda.functions.builtin.fn3.FoldLeft.foldLeft;
 import static com.jnape.palatable.lambda.functions.recursion.RecursiveResult.recurse;
 import static com.jnape.palatable.lambda.functions.recursion.RecursiveResult.terminate;
 import static com.jnape.palatable.lambda.functions.recursion.Trampoline.trampoline;
+import static com.jnape.palatable.lambda.monad.Monad.join;
 import static java.util.concurrent.CompletableFuture.completedFuture;
 import static java.util.concurrent.CompletableFuture.supplyAsync;
 import static java.util.concurrent.ForkJoinPool.commonPool;
@@ -93,6 +96,32 @@ public CompletableFuture unsafePerformAsyncIO(Executor executor) {
         };
     }
 
+    /**
+     * Return an {@link IO} that will run ensureIO strictly after running this {@link IO} regardless of
+     * whether this {@link IO} terminates normally, analogous to a finally block.
+     *
+     * @param ensureIO the {@link IO} to ensure runs strictly after this {@link IO}
+     * @return the combined {@link IO}
+     */
+    public final IO ensuring(IO ensureIO) {
+        return join(fmap(a -> ensureIO.fmap(constantly(a)))
+                            .exceptionally(t -> join(ensureIO.>fmap(constantly(io(() -> {throw t;})))
+                                                             .exceptionally(t2 -> io(() -> {
+                                                                 t.addSuppressed(t2);
+                                                                 throw t;
+                                                             })))));
+    }
+
+    /**
+     * Return a safe {@link IO} that will never throw by lifting the result of this {@link IO} into {@link Either},
+     * catching any {@link Throwable} and wrapping it in a {@link Either#left(Object) left}.
+     *
+     * @return the safe {@link IO}
+     */
+    public final IO> safe() {
+        return fmap(Either::right).exceptionally(Either::left);
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -157,6 +186,17 @@ public final  IO flatMap(Fn1>> f) {
         return new Compose<>(source, Choice2.b(flatMap));
     }
 
+    /**
+     * Produce an {@link IO} that throws the given {@link Throwable} when executed.
+     *
+     * @param t   the {@link Throwable}
+     * @param  any result type
+     * @return the {@link IO}
+     */
+    public static  IO throwing(Throwable t) {
+        return io(() -> {throw t;});
+    }
+
     /**
      * Static factory method for creating an {@link IO} that just returns a when performed.
      *
diff --git a/src/test/java/com/jnape/palatable/lambda/io/IOTest.java b/src/test/java/com/jnape/palatable/lambda/io/IOTest.java
index 7d1659ad2..2c86683e3 100644
--- a/src/test/java/com/jnape/palatable/lambda/io/IOTest.java
+++ b/src/test/java/com/jnape/palatable/lambda/io/IOTest.java
@@ -13,8 +13,13 @@
 
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
 import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicInteger;
 
+import static com.jnape.palatable.lambda.adt.Either.left;
+import static com.jnape.palatable.lambda.adt.Either.right;
 import static com.jnape.palatable.lambda.adt.Unit.UNIT;
 import static com.jnape.palatable.lambda.functions.builtin.fn2.Tupler2.tupler;
 import static com.jnape.palatable.lambda.functions.builtin.fn3.Times.times;
@@ -23,7 +28,9 @@
 import static java.util.concurrent.CompletableFuture.completedFuture;
 import static java.util.concurrent.Executors.newFixedThreadPool;
 import static java.util.concurrent.ForkJoinPool.commonPool;
+import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
 import static testsupport.Constants.STACK_EXPLODING_NUMBER;
 
 @RunWith(Traits.class)
@@ -174,6 +181,66 @@ public IO checkedApply(IO a) {
                              return a.flatMap(x -> x < STACK_EXPLODING_NUMBER ? apply(io(x + 1)) : io(x));
                          }
                      }.apply(io(0)).unsafePerformAsyncIO().join());
+    }
+
+    @Test
+    public void safe() {
+        assertEquals(right(1), io(() -> 1).safe().unsafePerformIO());
+        IllegalStateException thrown = new IllegalStateException("kaboom");
+        assertEquals(left(thrown), io(() -> {throw thrown;}).safe().unsafePerformIO());
+    }
+
+    @Test
+    public void ensuring() {
+        AtomicInteger counter    = new AtomicInteger(0);
+        IO   incCounter = io(counter::incrementAndGet);
+        assertEquals("foo", io(() -> "foo").ensuring(incCounter).unsafePerformIO());
+        assertEquals(1, counter.get());
+
+        IllegalStateException thrown = new IllegalStateException("kaboom");
+        try {
+            io(() -> {throw thrown;}).ensuring(incCounter).unsafePerformIO();
+            fail("Expected exception to have been thrown, but wasn't.");
+        } catch (IllegalStateException actual) {
+            assertEquals(thrown, actual);
+            assertEquals(2, counter.get());
+        }
+    }
 
+    @Test
+    public void ensuringRunsStrictlyAfterIO() {
+        Executor      twoThreads = Executors.newFixedThreadPool(2);
+        AtomicInteger counter    = new AtomicInteger(0);
+        io(() -> {
+            Thread.sleep(100);
+            counter.incrementAndGet();
+        }).ensuring(io(() -> {
+            if (counter.get() == 0)
+                fail("Expected to run after initial IO, but ran first");
+        })).unsafePerformAsyncIO(twoThreads).join();
+    }
+
+    @Test
+    public void ensuringAttachesThrownExceptionToThrownBodyException() {
+        IllegalStateException thrownByBody     = new IllegalStateException("kaboom");
+        IllegalStateException thrownByEnsuring = new IllegalStateException("KABOOM");
+
+        try {
+            io(() -> {throw thrownByBody;}).ensuring(io(() -> {throw thrownByEnsuring;})).unsafePerformIO();
+            fail("Expected exception to have been thrown, but wasn't.");
+        } catch (IllegalStateException actual) {
+            assertEquals(thrownByBody, actual);
+            assertArrayEquals(new Throwable[]{thrownByEnsuring}, actual.getSuppressed());
+        }
+    }
+
+    @Test
+    public void throwing() {
+        IllegalStateException expected = new IllegalStateException("thrown");
+        try {
+            IO.throwing(expected).unsafePerformIO();
+        } catch (IllegalStateException actual) {
+            assertEquals(expected, actual);
+        }
     }
 }
\ No newline at end of file

From a88cd97ca1a4cbc2b27e75c4a9528df7310bd278 Mon Sep 17 00:00:00 2001
From: jnape 
Date: Sat, 11 May 2019 17:27:05 -0500
Subject: [PATCH 43/69] Bracket for producing a value from an IO that can be
 cleaned up

---
 CHANGELOG.md                                  |  1 +
 .../lambda/functions/builtin/fn3/Bracket.java | 52 +++++++++++++
 .../functions/builtin/fn3/BracketTest.java    | 77 +++++++++++++++++++
 3 files changed, 130 insertions(+)
 create mode 100644 src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/Bracket.java
 create mode 100644 src/test/java/com/jnape/palatable/lambda/functions/builtin/fn3/BracketTest.java

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 106373584..cc0afb897 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -47,6 +47,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
 - `IO#safe`, mapping an `IO` to an `IO>` that will never throw
 - `IO#ensuring`, like `finally` semantics for `IO`s
 - `IO#throwing`, for producing an `IO` that will throw a given `Throwable` when executed
+- `Bracket`, for bracketing an `IO` operation with a mapping operation and a cleanup operation 
 
 ## [3.3.0] - 2019-02-18
 ### Added
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/Bracket.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/Bracket.java
new file mode 100644
index 000000000..59e6f512d
--- /dev/null
+++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/Bracket.java
@@ -0,0 +1,52 @@
+package com.jnape.palatable.lambda.functions.builtin.fn3;
+
+import com.jnape.palatable.lambda.functions.Fn1;
+import com.jnape.palatable.lambda.functions.Fn2;
+import com.jnape.palatable.lambda.functions.Fn3;
+import com.jnape.palatable.lambda.io.IO;
+import com.jnape.palatable.lambda.monad.Monad;
+
+/**
+ * Given an {@link IO} that yields some type A, a cleanup operation to run if a value of that type could be
+ * provisioned, and a kleisli arrow from that type to a new {@link IO} of type B, produce an
+ * {@link IO}<B> that, when run, will provision the A,
+ * {@link Monad#flatMap(Fn1) flatMap} it to B, and clean up the original value if it was produced in the
+ * first place.
+ *
+ * @param  the initial value to map and clean up
+ * @param  the resulting type
+ */
+public final class Bracket implements
+        Fn3, Fn1>, Fn1>, IO> {
+
+    private static final Bracket INSTANCE = new Bracket<>();
+
+    private Bracket() {
+    }
+
+    @Override
+    public IO checkedApply(IO io, Fn1> cleanupIO,
+                              Fn1> bodyIO) throws Throwable {
+        return io.flatMap(a -> bodyIO.apply(a).ensuring(cleanupIO.apply(a)));
+    }
+
+    @SuppressWarnings("unchecked")
+    public static  Bracket bracket() {
+        return (Bracket) INSTANCE;
+    }
+
+    public static  Fn2>, Fn1>, IO> bracket(
+            IO io) {
+        return Bracket.bracket().apply(io);
+    }
+
+    public static  Fn1>, IO> bracket(
+            IO io, Fn1> cleanupIO) {
+        return Bracket.bracket(io).apply(cleanupIO);
+    }
+
+    public static  IO bracket(IO io, Fn1> cleanupIO,
+                                       Fn1> bodyIO) {
+        return Bracket.bracket(io, cleanupIO).apply(bodyIO);
+    }
+}
diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn3/BracketTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn3/BracketTest.java
new file mode 100644
index 000000000..389ca5508
--- /dev/null
+++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn3/BracketTest.java
@@ -0,0 +1,77 @@
+package com.jnape.palatable.lambda.functions.builtin.fn3;
+
+import com.jnape.palatable.lambda.io.IO;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static com.jnape.palatable.lambda.functions.builtin.fn3.Bracket.bracket;
+import static com.jnape.palatable.lambda.io.IO.io;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+public class BracketTest {
+
+    private AtomicInteger count;
+
+    @Before
+    public void setUp() {
+        count = new AtomicInteger(0);
+    }
+
+    @Test
+    public void cleanupHappyPath() {
+        IO hashIO = bracket(io(() -> count), c -> io(c::incrementAndGet), c -> io(c::hashCode));
+
+        assertEquals(0, count.get());
+        assertEquals((Integer) count.hashCode(), hashIO.unsafePerformIO());
+        assertEquals(1, count.get());
+    }
+
+    @Test
+    public void cleanupSadPath() {
+        IllegalStateException thrown = new IllegalStateException("kaboom");
+        IO           hashIO = bracket(io(count), c -> io(c::incrementAndGet), c -> io(() -> {throw thrown;}));
+
+        try {
+            hashIO.unsafePerformIO();
+            fail("Expected exception to be raised");
+        } catch (IllegalStateException actual) {
+            assertEquals(thrown, actual);
+            assertEquals(1, count.get());
+        }
+    }
+
+    @Test
+    public void cleanupOnlyRunsIfInitialIORuns() {
+        IllegalStateException thrown = new IllegalStateException("kaboom");
+        IO hashIO = bracket(io(() -> {throw thrown;}),
+                                     __ -> io(count::incrementAndGet),
+                                     __ -> io(count::incrementAndGet));
+        try {
+            hashIO.unsafePerformIO();
+            fail("Expected exception to be raised");
+        } catch (IllegalStateException actual) {
+            assertEquals(thrown, actual);
+            assertEquals(0, count.get());
+        }
+    }
+
+    @Test
+    public void errorsInCleanupAreAddedToBodyErrors() {
+        IllegalStateException bodyError    = new IllegalStateException("kaboom");
+        IllegalStateException cleanupError = new IllegalStateException("KABOOM");
+        IO hashIO = bracket(io(count),
+                                     c -> io(() -> {throw cleanupError;}),
+                                     c -> io(() -> {throw bodyError;}));
+        try {
+            hashIO.unsafePerformIO();
+            fail("Expected exception to be raised");
+        } catch (IllegalStateException actual) {
+            assertEquals(bodyError, actual);
+            assertArrayEquals(new Throwable[]{cleanupError}, actual.getSuppressed());
+        }
+    }
+}
\ No newline at end of file

From 3af50faef1bf6aad29fb5b039e3d384ea98d8d4e Mon Sep 17 00:00:00 2001
From: jnape 
Date: Sat, 11 May 2019 20:13:20 -0500
Subject: [PATCH 44/69] Updating travis yml for jdk 11

---
 .travis.yml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.travis.yml b/.travis.yml
index 9bcf99945..8ea4e5783 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,3 +1,4 @@
 language: java
 jdk:
   - oraclejdk8
+  - oraclejdk11

From b0949c9a4a0cdc8ce2dd3543123226927a297adb Mon Sep 17 00:00:00 2001
From: jnape 
Date: Sat, 11 May 2019 20:13:52 -0500
Subject: [PATCH 45/69] Adding Pure static factory method to aid inference
 pre-11

---
 .../lambda/functions/specialized/Pure.java       | 11 +++++++++++
 .../lambda/functions/specialized/PureTest.java   | 16 ++++++++++++++++
 2 files changed, 27 insertions(+)
 create mode 100644 src/test/java/com/jnape/palatable/lambda/functions/specialized/PureTest.java

diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/Pure.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/Pure.java
index a49cf98b6..77d3bd91a 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/Pure.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/specialized/Pure.java
@@ -22,4 +22,15 @@ public interface Pure> {
             throw Runtime.throwChecked(t);
         }
     }
+
+    /**
+     * Static method to aid inference.
+     *
+     * @param pure the {@link Pure}
+     * @param   the {@link Functor} witness
+     * @return the {@link Pure}
+     */
+    static > Pure pure(Pure pure) {
+        return pure;
+    }
 }
diff --git a/src/test/java/com/jnape/palatable/lambda/functions/specialized/PureTest.java b/src/test/java/com/jnape/palatable/lambda/functions/specialized/PureTest.java
new file mode 100644
index 000000000..cda6be607
--- /dev/null
+++ b/src/test/java/com/jnape/palatable/lambda/functions/specialized/PureTest.java
@@ -0,0 +1,16 @@
+package com.jnape.palatable.lambda.functions.specialized;
+
+import com.jnape.palatable.lambda.adt.Maybe;
+import org.junit.Test;
+
+import static com.jnape.palatable.lambda.adt.Maybe.just;
+import static org.junit.Assert.assertEquals;
+
+public class PureTest {
+
+    @Test
+    @SuppressWarnings("RedundantTypeArguments")
+    public void inference() {
+        assertEquals(just(1), Pure.>pure(Maybe::just).>apply(1));
+    }
+}
\ No newline at end of file

From 576292ca0929eb018277ffb2294c894b54cb27e9 Mon Sep 17 00:00:00 2001
From: jnape 
Date: Sun, 12 May 2019 16:37:16 -0500
Subject: [PATCH 46/69] Removing extraneous imports

---
 src/main/java/com/jnape/palatable/lambda/adt/Try.java           | 2 +-
 .../com/jnape/palatable/lambda/adt/coproduct/CoProduct4.java    | 2 --
 .../com/jnape/palatable/lambda/adt/coproduct/CoProduct6.java    | 2 --
 src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple3.java  | 2 --
 src/main/java/com/jnape/palatable/lambda/functions/Effect.java  | 2 +-
 src/main/java/com/jnape/palatable/lambda/functions/Fn1.java     | 2 +-
 src/main/java/com/jnape/palatable/lambda/functions/Fn2.java     | 2 +-
 src/main/java/com/jnape/palatable/lambda/functions/Fn3.java     | 2 +-
 src/main/java/com/jnape/palatable/lambda/functions/Fn4.java     | 2 +-
 src/main/java/com/jnape/palatable/lambda/functions/Fn5.java     | 2 +-
 src/main/java/com/jnape/palatable/lambda/functions/Fn6.java     | 2 +-
 src/main/java/com/jnape/palatable/lambda/functions/Fn7.java     | 2 +-
 src/main/java/com/jnape/palatable/lambda/functions/Fn8.java     | 2 +-
 .../com/jnape/palatable/lambda/monad/transformer/MonadT.java    | 2 --
 .../palatable/lambda/monad/transformer/builtin/IdentityT.java   | 1 -
 .../java/com/jnape/palatable/lambda/optics/lenses/SetLens.java  | 1 -
 .../java/com/jnape/palatable/lambda/adt/hlist/Tuple2Test.java   | 1 -
 .../java/com/jnape/palatable/lambda/adt/hlist/Tuple3Test.java   | 2 --
 .../java/com/jnape/palatable/lambda/adt/hlist/Tuple4Test.java   | 2 --
 .../java/com/jnape/palatable/lambda/adt/hlist/Tuple5Test.java   | 2 --
 .../java/com/jnape/palatable/lambda/adt/hlist/Tuple6Test.java   | 2 --
 .../java/com/jnape/palatable/lambda/adt/hlist/Tuple7Test.java   | 2 --
 src/test/java/com/jnape/palatable/lambda/functions/Fn2Test.java | 1 -
 .../palatable/lambda/functions/builtin/fn2/GroupByTest.java     | 1 -
 .../palatable/lambda/internal/iteration/TakingIteratorTest.java | 1 -
 .../palatable/lambda/monad/transformer/builtin/MaybeTTest.java  | 1 -
 src/test/java/com/jnape/palatable/lambda/optics/PrismTest.java  | 2 --
 .../testsupport/applicatives/InvocationRecordingBifunctor.java  | 1 -
 src/test/java/testsupport/assertion/LensAssert.java             | 1 -
 src/test/java/testsupport/functions/ExplainFold.java            | 2 --
 src/test/java/testsupport/traits/ApplicativeLaws.java           | 1 -
 src/test/java/testsupport/traits/FunctorLaws.java               | 2 --
 src/test/java/testsupport/traits/MonadLaws.java                 | 2 --
 src/test/java/testsupport/traits/TraversableLaws.java           | 2 --
 34 files changed, 10 insertions(+), 48 deletions(-)

diff --git a/src/main/java/com/jnape/palatable/lambda/adt/Try.java b/src/main/java/com/jnape/palatable/lambda/adt/Try.java
index e89854b39..adaae9a85 100644
--- a/src/main/java/com/jnape/palatable/lambda/adt/Try.java
+++ b/src/main/java/com/jnape/palatable/lambda/adt/Try.java
@@ -12,13 +12,13 @@
 
 import java.util.Objects;
 
-import static com.jnape.palatable.lambda.internal.Runtime.throwChecked;
 import static com.jnape.palatable.lambda.adt.Maybe.nothing;
 import static com.jnape.palatable.lambda.adt.Unit.UNIT;
 import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly;
 import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id;
 import static com.jnape.palatable.lambda.functions.builtin.fn1.Upcast.upcast;
 import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy;
+import static com.jnape.palatable.lambda.internal.Runtime.throwChecked;
 
 /**
  * A {@link Monad} of the evaluation outcome of an expression that might throw. Try/catch/finally semantics map to
diff --git a/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct4.java b/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct4.java
index c8466dfa1..4deea96eb 100644
--- a/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct4.java
+++ b/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct4.java
@@ -5,8 +5,6 @@
 import com.jnape.palatable.lambda.adt.product.Product4;
 import com.jnape.palatable.lambda.functions.Fn1;
 
-import java.util.function.Function;
-
 import static com.jnape.palatable.lambda.adt.Maybe.just;
 import static com.jnape.palatable.lambda.adt.Maybe.nothing;
 import static com.jnape.palatable.lambda.adt.hlist.HList.tuple;
diff --git a/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct6.java b/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct6.java
index 084b3860d..d8d8d2301 100644
--- a/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct6.java
+++ b/src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct6.java
@@ -5,8 +5,6 @@
 import com.jnape.palatable.lambda.adt.product.Product6;
 import com.jnape.palatable.lambda.functions.Fn1;
 
-import java.util.function.Function;
-
 import static com.jnape.palatable.lambda.adt.Maybe.just;
 import static com.jnape.palatable.lambda.adt.Maybe.nothing;
 import static com.jnape.palatable.lambda.adt.hlist.HList.tuple;
diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple3.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple3.java
index 74f21bc8f..01ed4cf6c 100644
--- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple3.java
+++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple3.java
@@ -9,8 +9,6 @@
 import com.jnape.palatable.lambda.monad.Monad;
 import com.jnape.palatable.lambda.traversable.Traversable;
 
-import java.util.function.Function;
-
 import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly;
 
 /**
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Effect.java b/src/main/java/com/jnape/palatable/lambda/functions/Effect.java
index 4fdfba136..21b9ed723 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/Effect.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/Effect.java
@@ -2,8 +2,8 @@
 
 import com.jnape.palatable.lambda.adt.Unit;
 import com.jnape.palatable.lambda.functions.specialized.SideEffect;
-import com.jnape.palatable.lambda.internal.Runtime;
 import com.jnape.palatable.lambda.functor.Applicative;
+import com.jnape.palatable.lambda.internal.Runtime;
 import com.jnape.palatable.lambda.io.IO;
 
 import java.util.function.Consumer;
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java
index 9df14981a..fcf44bd69 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java
@@ -3,11 +3,11 @@
 import com.jnape.palatable.lambda.adt.Either;
 import com.jnape.palatable.lambda.adt.choice.Choice2;
 import com.jnape.palatable.lambda.adt.hlist.Tuple2;
-import com.jnape.palatable.lambda.internal.Runtime;
 import com.jnape.palatable.lambda.functor.Applicative;
 import com.jnape.palatable.lambda.functor.Cartesian;
 import com.jnape.palatable.lambda.functor.Cocartesian;
 import com.jnape.palatable.lambda.functor.builtin.Lazy;
+import com.jnape.palatable.lambda.internal.Runtime;
 import com.jnape.palatable.lambda.monad.Monad;
 
 import java.util.function.Function;
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn2.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn2.java
index 977082ed2..769f0a4d1 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/Fn2.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn2.java
@@ -1,8 +1,8 @@
 package com.jnape.palatable.lambda.functions;
 
 import com.jnape.palatable.lambda.adt.product.Product2;
-import com.jnape.palatable.lambda.internal.Runtime;
 import com.jnape.palatable.lambda.functor.Applicative;
+import com.jnape.palatable.lambda.internal.Runtime;
 
 import java.util.function.BiFunction;
 
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn3.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn3.java
index a225f7e3a..881d848ff 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/Fn3.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn3.java
@@ -1,8 +1,8 @@
 package com.jnape.palatable.lambda.functions;
 
 import com.jnape.palatable.lambda.adt.product.Product2;
-import com.jnape.palatable.lambda.internal.Runtime;
 import com.jnape.palatable.lambda.functor.Applicative;
+import com.jnape.palatable.lambda.internal.Runtime;
 
 import static com.jnape.palatable.lambda.functions.Fn4.fn4;
 import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly;
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn4.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn4.java
index e43dcda17..f2e9f7d47 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/Fn4.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn4.java
@@ -1,8 +1,8 @@
 package com.jnape.palatable.lambda.functions;
 
 import com.jnape.palatable.lambda.adt.product.Product2;
-import com.jnape.palatable.lambda.internal.Runtime;
 import com.jnape.palatable.lambda.functor.Applicative;
+import com.jnape.palatable.lambda.internal.Runtime;
 
 import static com.jnape.palatable.lambda.functions.Fn5.fn5;
 import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly;
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn5.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn5.java
index 55364e8bb..c89b8dadd 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/Fn5.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn5.java
@@ -1,8 +1,8 @@
 package com.jnape.palatable.lambda.functions;
 
 import com.jnape.palatable.lambda.adt.product.Product2;
-import com.jnape.palatable.lambda.internal.Runtime;
 import com.jnape.palatable.lambda.functor.Applicative;
+import com.jnape.palatable.lambda.internal.Runtime;
 
 import static com.jnape.palatable.lambda.functions.Fn6.fn6;
 import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly;
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn6.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn6.java
index 5998bc9aa..4e7bbea89 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/Fn6.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn6.java
@@ -1,8 +1,8 @@
 package com.jnape.palatable.lambda.functions;
 
 import com.jnape.palatable.lambda.adt.product.Product2;
-import com.jnape.palatable.lambda.internal.Runtime;
 import com.jnape.palatable.lambda.functor.Applicative;
+import com.jnape.palatable.lambda.internal.Runtime;
 
 import static com.jnape.palatable.lambda.functions.Fn7.fn7;
 import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly;
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn7.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn7.java
index 87a3f8704..2d27e6be2 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/Fn7.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn7.java
@@ -1,8 +1,8 @@
 package com.jnape.palatable.lambda.functions;
 
 import com.jnape.palatable.lambda.adt.product.Product2;
-import com.jnape.palatable.lambda.internal.Runtime;
 import com.jnape.palatable.lambda.functor.Applicative;
+import com.jnape.palatable.lambda.internal.Runtime;
 
 import static com.jnape.palatable.lambda.functions.Fn8.fn8;
 import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly;
diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn8.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn8.java
index 4ead63674..a38e74eb1 100644
--- a/src/main/java/com/jnape/palatable/lambda/functions/Fn8.java
+++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn8.java
@@ -1,8 +1,8 @@
 package com.jnape.palatable.lambda.functions;
 
 import com.jnape.palatable.lambda.adt.product.Product2;
-import com.jnape.palatable.lambda.internal.Runtime;
 import com.jnape.palatable.lambda.functor.Applicative;
+import com.jnape.palatable.lambda.internal.Runtime;
 
 /**
  * A function taking six arguments. Defined in terms of {@link Fn7}, so similarly auto-curried.
diff --git a/src/main/java/com/jnape/palatable/lambda/monad/transformer/MonadT.java b/src/main/java/com/jnape/palatable/lambda/monad/transformer/MonadT.java
index e95bdd68d..17b6dfd4e 100644
--- a/src/main/java/com/jnape/palatable/lambda/monad/transformer/MonadT.java
+++ b/src/main/java/com/jnape/palatable/lambda/monad/transformer/MonadT.java
@@ -6,8 +6,6 @@
 import com.jnape.palatable.lambda.monad.Monad;
 import com.jnape.palatable.lambda.monad.transformer.builtin.MaybeT;
 
-import java.util.function.Function;
-
 /**
  * An interface representing a {@link Monad} transformer.
  * 

diff --git a/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/IdentityT.java b/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/IdentityT.java index 26ffffb51..a3e87e3fc 100644 --- a/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/IdentityT.java +++ b/src/main/java/com/jnape/palatable/lambda/monad/transformer/builtin/IdentityT.java @@ -9,7 +9,6 @@ import com.jnape.palatable.lambda.monad.transformer.MonadT; import java.util.Objects; -import java.util.function.Function; /** * A {@link MonadT monad transformer} for {@link Identity}. diff --git a/src/main/java/com/jnape/palatable/lambda/optics/lenses/SetLens.java b/src/main/java/com/jnape/palatable/lambda/optics/lenses/SetLens.java index 3c2790d53..6b66649ed 100644 --- a/src/main/java/com/jnape/palatable/lambda/optics/lenses/SetLens.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/lenses/SetLens.java @@ -8,7 +8,6 @@ import java.util.Set; import static com.jnape.palatable.lambda.optics.Lens.simpleLens; -import static java.util.Collections.singleton; /** * Lenses that operate on {@link Set}s. diff --git a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple2Test.java b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple2Test.java index e4a4ee0bb..75d4bcbe2 100644 --- a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple2Test.java +++ b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple2Test.java @@ -14,7 +14,6 @@ import java.util.HashMap; import java.util.Map; -import java.util.function.Function; import static com.jnape.palatable.lambda.adt.hlist.HList.singletonHList; import static com.jnape.palatable.lambda.adt.hlist.HList.tuple; diff --git a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple3Test.java b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple3Test.java index 4a086c5f4..d52b407bb 100644 --- a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple3Test.java +++ b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple3Test.java @@ -12,8 +12,6 @@ import testsupport.traits.MonadLaws; import testsupport.traits.TraversableLaws; -import java.util.function.Function; - import static com.jnape.palatable.lambda.adt.hlist.HList.tuple; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.spy; diff --git a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple4Test.java b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple4Test.java index 59280ec53..4e0fa9659 100644 --- a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple4Test.java +++ b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple4Test.java @@ -12,8 +12,6 @@ import testsupport.traits.MonadLaws; import testsupport.traits.TraversableLaws; -import java.util.function.Function; - import static com.jnape.palatable.lambda.adt.hlist.HList.tuple; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.spy; diff --git a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple5Test.java b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple5Test.java index 970ee1c62..45e4edc67 100644 --- a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple5Test.java +++ b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple5Test.java @@ -13,8 +13,6 @@ import testsupport.traits.MonadLaws; import testsupport.traits.TraversableLaws; -import java.util.function.Function; - import static com.jnape.palatable.lambda.adt.hlist.HList.tuple; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.spy; diff --git a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple6Test.java b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple6Test.java index 796ed4752..1fb7ab578 100644 --- a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple6Test.java +++ b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple6Test.java @@ -13,8 +13,6 @@ import testsupport.traits.MonadLaws; import testsupport.traits.TraversableLaws; -import java.util.function.Function; - import static com.jnape.palatable.lambda.adt.hlist.HList.tuple; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.spy; diff --git a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple7Test.java b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple7Test.java index b8c07e3db..6203fe15e 100644 --- a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple7Test.java +++ b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple7Test.java @@ -13,8 +13,6 @@ import testsupport.traits.MonadLaws; import testsupport.traits.TraversableLaws; -import java.util.function.Function; - import static com.jnape.palatable.lambda.adt.hlist.HList.tuple; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.spy; diff --git a/src/test/java/com/jnape/palatable/lambda/functions/Fn2Test.java b/src/test/java/com/jnape/palatable/lambda/functions/Fn2Test.java index b5c9413b3..dbe1d5b7a 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/Fn2Test.java +++ b/src/test/java/com/jnape/palatable/lambda/functions/Fn2Test.java @@ -8,7 +8,6 @@ import static org.hamcrest.core.Is.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; public class Fn2Test { diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/GroupByTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/GroupByTest.java index b04ea7999..5a9401099 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/GroupByTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/GroupByTest.java @@ -10,7 +10,6 @@ import static com.jnape.palatable.lambda.functions.builtin.fn2.GroupBy.groupBy; import static java.util.Arrays.asList; import static java.util.Collections.emptyList; -import static java.util.Collections.emptyMap; import static java.util.Collections.singletonList; import static org.junit.Assert.assertEquals; diff --git a/src/test/java/com/jnape/palatable/lambda/internal/iteration/TakingIteratorTest.java b/src/test/java/com/jnape/palatable/lambda/internal/iteration/TakingIteratorTest.java index e6a03a6f2..d22dd8138 100644 --- a/src/test/java/com/jnape/palatable/lambda/internal/iteration/TakingIteratorTest.java +++ b/src/test/java/com/jnape/palatable/lambda/internal/iteration/TakingIteratorTest.java @@ -6,7 +6,6 @@ import java.util.List; import static java.util.Arrays.asList; -import static java.util.Collections.emptyList; import static org.hamcrest.core.Is.is; import static org.junit.Assert.assertThat; diff --git a/src/test/java/com/jnape/palatable/lambda/monad/transformer/builtin/MaybeTTest.java b/src/test/java/com/jnape/palatable/lambda/monad/transformer/builtin/MaybeTTest.java index 8060ce8b3..9a5368cdc 100644 --- a/src/test/java/com/jnape/palatable/lambda/monad/transformer/builtin/MaybeTTest.java +++ b/src/test/java/com/jnape/palatable/lambda/monad/transformer/builtin/MaybeTTest.java @@ -1,7 +1,6 @@ package com.jnape.palatable.lambda.monad.transformer.builtin; import com.jnape.palatable.lambda.adt.Either; -import com.jnape.palatable.lambda.monad.transformer.builtin.MaybeT; import com.jnape.palatable.traitor.annotations.TestTraits; import com.jnape.palatable.traitor.framework.Subjects; import com.jnape.palatable.traitor.runners.Traits; diff --git a/src/test/java/com/jnape/palatable/lambda/optics/PrismTest.java b/src/test/java/com/jnape/palatable/lambda/optics/PrismTest.java index 46d617e81..81b74b14e 100644 --- a/src/test/java/com/jnape/palatable/lambda/optics/PrismTest.java +++ b/src/test/java/com/jnape/palatable/lambda/optics/PrismTest.java @@ -5,8 +5,6 @@ import com.jnape.palatable.lambda.functions.Fn1; import org.junit.Test; -import java.util.function.Function; - import static com.jnape.palatable.lambda.adt.Either.left; import static com.jnape.palatable.lambda.adt.Either.right; import static com.jnape.palatable.lambda.adt.Maybe.just; diff --git a/src/test/java/testsupport/applicatives/InvocationRecordingBifunctor.java b/src/test/java/testsupport/applicatives/InvocationRecordingBifunctor.java index 8fca9d114..a39803ee1 100644 --- a/src/test/java/testsupport/applicatives/InvocationRecordingBifunctor.java +++ b/src/test/java/testsupport/applicatives/InvocationRecordingBifunctor.java @@ -4,7 +4,6 @@ import com.jnape.palatable.lambda.functor.Bifunctor; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Function; public final class InvocationRecordingBifunctor implements Bifunctor> { private final AtomicReference> leftFn; diff --git a/src/test/java/testsupport/assertion/LensAssert.java b/src/test/java/testsupport/assertion/LensAssert.java index b966e97f2..aea73adb5 100644 --- a/src/test/java/testsupport/assertion/LensAssert.java +++ b/src/test/java/testsupport/assertion/LensAssert.java @@ -6,7 +6,6 @@ import com.jnape.palatable.lambda.functions.Fn2; import com.jnape.palatable.lambda.functions.builtin.fn2.Map; import com.jnape.palatable.lambda.functor.Functor; -import com.jnape.palatable.lambda.functor.Profunctor; import com.jnape.palatable.lambda.monoid.builtin.Present; import com.jnape.palatable.lambda.optics.Optic; diff --git a/src/test/java/testsupport/functions/ExplainFold.java b/src/test/java/testsupport/functions/ExplainFold.java index 488b05476..d59a2378b 100644 --- a/src/test/java/testsupport/functions/ExplainFold.java +++ b/src/test/java/testsupport/functions/ExplainFold.java @@ -2,8 +2,6 @@ import com.jnape.palatable.lambda.functions.Fn2; -import java.util.function.BiFunction; - import static java.lang.String.format; public class ExplainFold { diff --git a/src/test/java/testsupport/traits/ApplicativeLaws.java b/src/test/java/testsupport/traits/ApplicativeLaws.java index 5b8b0b713..e449fe603 100644 --- a/src/test/java/testsupport/traits/ApplicativeLaws.java +++ b/src/test/java/testsupport/traits/ApplicativeLaws.java @@ -7,7 +7,6 @@ import com.jnape.palatable.traitor.traits.Trait; import java.util.Random; -import java.util.function.Function; import static com.jnape.palatable.lambda.adt.Maybe.just; import static com.jnape.palatable.lambda.adt.Maybe.nothing; diff --git a/src/test/java/testsupport/traits/FunctorLaws.java b/src/test/java/testsupport/traits/FunctorLaws.java index c2bb1791c..13ad2b423 100644 --- a/src/test/java/testsupport/traits/FunctorLaws.java +++ b/src/test/java/testsupport/traits/FunctorLaws.java @@ -6,8 +6,6 @@ import com.jnape.palatable.lambda.monoid.builtin.Present; import com.jnape.palatable.traitor.traits.Trait; -import java.util.function.Function; - import static com.jnape.palatable.lambda.adt.Maybe.just; import static com.jnape.palatable.lambda.adt.Maybe.nothing; import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; diff --git a/src/test/java/testsupport/traits/MonadLaws.java b/src/test/java/testsupport/traits/MonadLaws.java index 5ea31ac98..6a2df2392 100644 --- a/src/test/java/testsupport/traits/MonadLaws.java +++ b/src/test/java/testsupport/traits/MonadLaws.java @@ -6,8 +6,6 @@ import com.jnape.palatable.lambda.monoid.builtin.Present; import com.jnape.palatable.traitor.traits.Trait; -import java.util.function.Function; - import static com.jnape.palatable.lambda.adt.Maybe.just; import static com.jnape.palatable.lambda.adt.Maybe.nothing; import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; diff --git a/src/test/java/testsupport/traits/TraversableLaws.java b/src/test/java/testsupport/traits/TraversableLaws.java index 3939c3c3d..f27eca241 100644 --- a/src/test/java/testsupport/traits/TraversableLaws.java +++ b/src/test/java/testsupport/traits/TraversableLaws.java @@ -10,8 +10,6 @@ import com.jnape.palatable.lambda.traversable.Traversable; import com.jnape.palatable.traitor.traits.Trait; -import java.util.function.Function; - import static com.jnape.palatable.lambda.adt.Either.right; import static com.jnape.palatable.lambda.adt.Maybe.just; import static com.jnape.palatable.lambda.adt.Maybe.nothing; From c0752977a98a76a0bba2818e472af8fcb1da2265 Mon Sep 17 00:00:00 2001 From: jnape Date: Mon, 13 May 2019 17:46:21 -0500 Subject: [PATCH 47/69] Adding Effect#noop back, it's just too convenient --- .../com/jnape/palatable/lambda/functions/Effect.java | 11 +++++++++++ .../lambda/functions/specialized/SideEffect.java | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Effect.java b/src/main/java/com/jnape/palatable/lambda/functions/Effect.java index 21b9ed723..6e23e2932 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Effect.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Effect.java @@ -10,6 +10,7 @@ import static com.jnape.palatable.lambda.adt.Unit.UNIT; import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; +import static com.jnape.palatable.lambda.functions.specialized.SideEffect.NOOP; import static com.jnape.palatable.lambda.io.IO.io; /** @@ -90,6 +91,16 @@ static Effect effect(SideEffect sideEffect) { return effect(constantly(io(sideEffect))); } + /** + * Create an {@link Effect} that accepts an input and does nothing; + * + * @return the noop {@link Effect} + */ + @SuppressWarnings("unused") + static Effect noop() { + return effect(NOOP).contraMap(constantly(UNIT)); + } + /** * Create an {@link Effect} from an {@link Fn1} that yields an {@link IO}. * diff --git a/src/main/java/com/jnape/palatable/lambda/functions/specialized/SideEffect.java b/src/main/java/com/jnape/palatable/lambda/functions/specialized/SideEffect.java index f0872ed9e..6ef2092a1 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/specialized/SideEffect.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/specialized/SideEffect.java @@ -17,7 +17,7 @@ public interface SideEffect { /** * A no-op {@link SideEffect} */ - @SuppressWarnings("unused") SideEffect NOOP = () -> {}; + SideEffect NOOP = () -> {}; @SuppressWarnings("NonAsciiCharacters") void Ω() throws Throwable; From 17309bfac547f39c3d6c9e89e8d9bacd84c0f8df Mon Sep 17 00:00:00 2001 From: jnape Date: Tue, 14 May 2019 19:33:57 -0500 Subject: [PATCH 48/69] IO internally composes using the given Executor, rather than the FJP --- src/main/java/com/jnape/palatable/lambda/io/IO.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/jnape/palatable/lambda/io/IO.java b/src/main/java/com/jnape/palatable/lambda/io/IO.java index 6036d1335..a42181bd2 100644 --- a/src/main/java/com/jnape/palatable/lambda/io/IO.java +++ b/src/main/java/com/jnape/palatable/lambda/io/IO.java @@ -316,7 +316,7 @@ public CompletableFuture unsafePerformAsyncIO(Executor executor) { .match(zip -> zip.unsafePerformAsyncIO(executor) .thenCompose(f -> io.thenApply(f.toFunction())), flatMap -> io.thenComposeAsync(obj -> flatMap.apply(obj) - .unsafePerformAsyncIO(executor))), + .unsafePerformAsyncIO(executor), executor)), source.unsafePerformAsyncIO(executor), compositions)); return future; From 51590cd2fac0431bf825583409a53eaa82e7410f Mon Sep 17 00:00:00 2001 From: jnape Date: Tue, 14 May 2019 19:45:42 -0500 Subject: [PATCH 49/69] Try#failure loses extraneous parameter; Try#orThrow can transform first --- .../com/jnape/palatable/lambda/adt/Try.java | 30 ++++++++++++++----- .../jnape/palatable/lambda/adt/TryTest.java | 25 ++++++++++++---- 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/jnape/palatable/lambda/adt/Try.java b/src/main/java/com/jnape/palatable/lambda/adt/Try.java index adaae9a85..00b629a72 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/Try.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/Try.java @@ -110,7 +110,24 @@ public final Throwable forfeit(Fn1 fn) { * @return possibly the success value * @throws T anything that the call site may want to explicitly catch or indicate could be thrown */ - public abstract A orThrow() throws T; + public final A orThrow() throws T { + try { + return orThrow(id()); + } catch (Throwable t) { + throw throwChecked(t); + } + } + + /** + * If this is a success value, return it. Otherwise, transform the captured failure with fn and throw + * the result. + * + * @param the type of the thrown {@link Throwable} + * @return possibly the success value + * @throws T the transformation output + */ + public abstract A orThrow(Fn1 fn) throws T; + /** * If this is a success, wrap the value in a {@link Maybe#just} and return it. Otherwise, return {@link @@ -228,12 +245,11 @@ public static Try success(A a) { /** * Static factory method for creating a failure value. * - * @param t the wrapped {@link Throwable} - * @param the failure parameter type + * @param t the {@link Throwable} * @param the success parameter type * @return a failure value of t */ - public static Try failure(T t) { + public static Try failure(Throwable t) { return new Failure<>(t); } @@ -353,8 +369,8 @@ private Failure(Throwable t) { } @Override - public A orThrow() { - throw throwChecked(t); + public A orThrow(Fn1 fn) throws T { + throw fn.apply(t); } @Override @@ -388,7 +404,7 @@ private Success(A a) { } @Override - public A orThrow() { + public A orThrow(Fn1 fn) { return a; } diff --git a/src/test/java/com/jnape/palatable/lambda/adt/TryTest.java b/src/test/java/com/jnape/palatable/lambda/adt/TryTest.java index 77425e391..ee6ad0dd7 100644 --- a/src/test/java/com/jnape/palatable/lambda/adt/TryTest.java +++ b/src/test/java/com/jnape/palatable/lambda/adt/TryTest.java @@ -51,7 +51,7 @@ public Subjects> testSubject() { @Test public void catchingWithGenericPredicate() { - Try caught = Try.failure(new RuntimeException()) + Try caught = Try.failure(new RuntimeException()) .catching(__ -> false, r -> "caught first") .catching(__ -> true, r -> "caught second"); @@ -68,7 +68,7 @@ public void catchingIsANoOpForSuccess() { @Test public void firstMatchingCatchBlockWins() { - Try caught = Try.failure(new IllegalStateException()) + Try caught = Try.failure(new IllegalStateException()) .catching(__ -> true, __ -> "first") .catching(__ -> true, __ -> "second"); @@ -77,7 +77,7 @@ public void firstMatchingCatchBlockWins() { @Test public void catchBasedOnExceptionType() { - Try caught = Try.failure(new IllegalStateException()) + Try caught = Try.failure(new IllegalStateException()) .catching(IllegalArgumentException.class, __ -> "illegal argument exception") .catching(IllegalStateException.class, __ -> "illegal state exception") .catching(RuntimeException.class, __ -> "runtime exception"); @@ -114,14 +114,14 @@ public void exceptionThrownInEnsuringBlockIsCaught() { @Test public void forfeitEnsuresFailure() { IllegalStateException expected = new IllegalStateException(); - assertEquals(expected, Try.failure(expected).forfeit(__ -> new IllegalArgumentException())); + assertEquals(expected, Try.failure(expected).forfeit(__ -> new IllegalArgumentException())); assertEquals(expected, Try.success(1).forfeit(__ -> expected)); } @Test public void recoverEnsuresSuccess() { assertEquals((Integer) 1, Try.success(1).recover(constantly(1))); - assertEquals((Integer) 1, Try.failure(new IllegalArgumentException()).recover(constantly(1))); + assertEquals((Integer) 1, Try.failure(new IllegalArgumentException()).recover(constantly(1))); } @Test @@ -233,4 +233,19 @@ public void orThrowCanStillThrowCheckedExceptions() { } catch (Exception expected) { } } + + @Test + public void orThrowCanTransformFirst() { + try { + Try.trying(() -> { + throw new IllegalStateException(); + }).orThrow(IllegalArgumentException::new); + fail("Expected RuntimeException to be thrown, but nothing was"); + } catch (IllegalStateException ioException) { + fail("Expected thrown exception to not be IllegalStateException, but it was"); + } catch (IllegalArgumentException expected) { + } catch (Exception e) { + fail("A different exception altogether was thrown."); + } + } } \ No newline at end of file From 60a7efff751dbe98079cd443e2db2ac07fb9485a Mon Sep 17 00:00:00 2001 From: jnape Date: Tue, 14 May 2019 20:00:49 -0500 Subject: [PATCH 50/69] peek now accepts a -> IO for better inference --- .../jnape/palatable/lambda/adt/Either.java | 3 ++- .../com/jnape/palatable/lambda/adt/Maybe.java | 4 +-- .../lambda/functions/builtin/fn2/Peek.java | 17 ++++++------ .../lambda/functions/builtin/fn2/Peek2.java | 27 ++++++++++--------- .../jnape/palatable/lambda/adt/MaybeTest.java | 7 ++--- .../testsupport/assertion/LensAssert.java | 3 ++- .../testsupport/matchers/LeftMatcher.java | 6 ++--- .../testsupport/matchers/RightMatcher.java | 6 ++--- .../testsupport/traits/ApplicativeLaws.java | 6 ++--- .../testsupport/traits/BifunctorLaws.java | 6 ++--- .../java/testsupport/traits/FunctorLaws.java | 6 ++--- .../java/testsupport/traits/MonadLaws.java | 6 ++--- .../testsupport/traits/TraversableLaws.java | 7 +++-- 13 files changed, 54 insertions(+), 50 deletions(-) diff --git a/src/main/java/com/jnape/palatable/lambda/adt/Either.java b/src/main/java/com/jnape/palatable/lambda/adt/Either.java index 1148c0523..360043cb6 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/Either.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/Either.java @@ -12,6 +12,7 @@ import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Bifunctor; import com.jnape.palatable.lambda.functor.builtin.Lazy; +import com.jnape.palatable.lambda.io.IO; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; @@ -176,7 +177,7 @@ public Either peek(Effect effect) { * @param rightEffect the effecting consumer for right values * @return the Either, unaltered */ - public Either peek(Effect leftEffect, Effect rightEffect) { + public Either peek(Fn1> leftEffect, Fn1> rightEffect) { return Peek2.peek2(leftEffect, rightEffect, this); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/Maybe.java b/src/main/java/com/jnape/palatable/lambda/adt/Maybe.java index 94f4e6bda..2913599a0 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/Maybe.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/Maybe.java @@ -5,13 +5,13 @@ import com.jnape.palatable.lambda.adt.coproduct.CoProduct2; import com.jnape.palatable.lambda.adt.hlist.HList; import com.jnape.palatable.lambda.adt.hlist.Tuple2; -import com.jnape.palatable.lambda.functions.Effect; import com.jnape.palatable.lambda.functions.Fn0; import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functions.builtin.fn2.Peek; import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Functor; import com.jnape.palatable.lambda.functor.builtin.Lazy; +import com.jnape.palatable.lambda.io.IO; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.traversable.Traversable; @@ -206,7 +206,7 @@ public Choice2 invert() { * @param effect the consumer * @return the same Maybe instance */ - public final Maybe peek(Effect effect) { + public final Maybe peek(Fn1> effect) { return Peek.peek(effect, this); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek.java index 83a33484d..bea6bb1c5 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek.java @@ -4,6 +4,7 @@ import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functions.Fn2; import com.jnape.palatable.lambda.functor.Functor; +import com.jnape.palatable.lambda.io.IO; /** * Given an {@link Effect}, "peek" at the value contained inside a {@link Functor} via {@link Functor#fmap(Fn1)}, @@ -12,7 +13,7 @@ * @param the functor parameter type * @param the functor type */ -public final class Peek> implements Fn2, FA, FA> { +public final class Peek> implements Fn2>, FA, FA> { private static final Peek INSTANCE = new Peek<>(); private Peek() { @@ -20,11 +21,11 @@ private Peek() { @Override @SuppressWarnings("unchecked") - public FA checkedApply(Effect consumer, FA fa) { + public FA checkedApply(Fn1> effect, FA fa) { return (FA) fa.fmap(a -> { - consumer.apply(a).unsafePerformIO(); + effect.apply(a).unsafePerformIO(); return a; - }); + }).coerce(); } @SuppressWarnings("unchecked") @@ -32,11 +33,11 @@ public FA checkedApply(Effect consumer, FA fa) { return (Peek) INSTANCE; } - public static > Fn1 peek(Effect consumer) { - return Peek.peek().apply(consumer); + public static > Fn1 peek(Fn1> effect) { + return Peek.peek().apply(effect); } - public static > FA peek(Effect consumer, FA fa) { - return Peek.peek(consumer).apply(fa); + public static > FA peek(Fn1> effect, FA fa) { + return Peek.peek(effect).apply(fa); } } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek2.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek2.java index 7e3d3c465..3114f26c1 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek2.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Peek2.java @@ -6,6 +6,7 @@ import com.jnape.palatable.lambda.functions.Fn3; import com.jnape.palatable.lambda.functor.Bifunctor; import com.jnape.palatable.lambda.functor.BoundedBifunctor; +import com.jnape.palatable.lambda.io.IO; /** * Given two {@link Effect}s, "peek" at the values contained inside a {@link Bifunctor} via @@ -16,7 +17,7 @@ * @param the bifunctor type */ public final class Peek2> implements - Fn3, Effect, FAB, FAB> { + Fn3>, Fn1>, FAB, FAB> { private static final Peek2 INSTANCE = new Peek2<>(); private Peek2() { @@ -24,12 +25,12 @@ private Peek2() { @Override @SuppressWarnings("unchecked") - public FAB checkedApply(Effect aConsumer, Effect bConsumer, FAB fab) { + public FAB checkedApply(Fn1> effectA, Fn1> effectB, FAB fab) { return (FAB) fab.biMap(a -> { - aConsumer.apply(a).unsafePerformIO(); + effectA.apply(a).unsafePerformIO(); return a; }, b -> { - bConsumer.apply(b).unsafePerformIO(); + effectB.apply(b).unsafePerformIO(); return b; }); } @@ -39,21 +40,21 @@ public FAB checkedApply(Effect aConsumer, Effect bConsumer return (Peek2) INSTANCE; } - public static > Fn2, FAB, FAB> - peek2(Effect aConsumer) { - return Peek2.peek2().apply(aConsumer); + public static > + Fn2>, FAB, FAB> peek2(Fn1> effectA) { + return Peek2.peek2().apply(effectA); } public static > Fn1 peek2( - Effect aConsumer, - Effect bConsumer) { - return Peek2.peek2(aConsumer).apply(bConsumer); + Fn1> effectA, + Fn1> effectB) { + return Peek2.peek2(effectA).apply(effectB); } public static > FAB peek2( - Effect aConsumer, - Effect bConsumer, + Fn1> effectA, + Fn1> effectB, FAB fab) { - return Peek2.peek2(aConsumer, bConsumer).apply(fab); + return Peek2.peek2(effectA, effectB).apply(fab); } } diff --git a/src/test/java/com/jnape/palatable/lambda/adt/MaybeTest.java b/src/test/java/com/jnape/palatable/lambda/adt/MaybeTest.java index 281f00cf8..0548e74f4 100644 --- a/src/test/java/com/jnape/palatable/lambda/adt/MaybeTest.java +++ b/src/test/java/com/jnape/palatable/lambda/adt/MaybeTest.java @@ -21,9 +21,10 @@ import static com.jnape.palatable.lambda.adt.Maybe.nothing; import static com.jnape.palatable.lambda.adt.Unit.UNIT; import static com.jnape.palatable.lambda.adt.hlist.HList.tuple; -import static com.jnape.palatable.lambda.functions.Effect.fromConsumer; +import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; import static com.jnape.palatable.lambda.functions.builtin.fn2.Eq.eq; import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; +import static com.jnape.palatable.lambda.io.IO.io; import static com.jnape.palatable.traitor.framework.Subjects.subjects; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertSame; @@ -98,10 +99,10 @@ public void fromEither() { @Test public void peek() { AtomicInteger ref = new AtomicInteger(0); - assertEquals(just(1), just(1).peek(fromConsumer(__ -> ref.incrementAndGet()))); + assertEquals(just(1), just(1).peek(constantly(io(ref::incrementAndGet)))); assertEquals(1, ref.get()); - assertEquals(nothing(), nothing().peek(fromConsumer(__ -> ref.incrementAndGet()))); + assertEquals(nothing(), nothing().peek(constantly(io(ref::incrementAndGet)))); assertEquals(1, ref.get()); } diff --git a/src/test/java/testsupport/assertion/LensAssert.java b/src/test/java/testsupport/assertion/LensAssert.java index aea73adb5..2c174cada 100644 --- a/src/test/java/testsupport/assertion/LensAssert.java +++ b/src/test/java/testsupport/assertion/LensAssert.java @@ -6,6 +6,7 @@ import com.jnape.palatable.lambda.functions.Fn2; import com.jnape.palatable.lambda.functions.builtin.fn2.Map; import com.jnape.palatable.lambda.functor.Functor; +import com.jnape.palatable.lambda.io.IO; import com.jnape.palatable.lambda.monoid.builtin.Present; import com.jnape.palatable.lambda.optics.Optic; @@ -33,7 +34,7 @@ public static void assertLensLawfulness(Optic, Functor< .reduceLeft(asList(falsify("You get back what you put in", (s, b) -> view(lens, set(lens, b, s)), (s, b) -> b, cases), falsify("Putting back what you got changes nothing", (s, b) -> set(lens, view(lens, s), s), (s, b) -> s, cases), falsify("Setting twice is equivalent to setting once", (s, b) -> set(lens, b, set(lens, b, s)), (s, b) -> set(lens, b, s), cases))) - .peek(failures -> {throw new AssertionError("Lens law failures\n\n" + failures);}); + .peek(failures -> IO.throwing(new AssertionError("Lens law failures\n\n" + failures))); } private static Maybe falsify(String label, Fn2 l, Fn2 r, diff --git a/src/test/java/testsupport/matchers/LeftMatcher.java b/src/test/java/testsupport/matchers/LeftMatcher.java index 7ccb74737..fa57261fe 100644 --- a/src/test/java/testsupport/matchers/LeftMatcher.java +++ b/src/test/java/testsupport/matchers/LeftMatcher.java @@ -5,8 +5,8 @@ import org.hamcrest.Matcher; import org.hamcrest.TypeSafeMatcher; -import static com.jnape.palatable.lambda.functions.Effect.fromConsumer; import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; +import static com.jnape.palatable.lambda.io.IO.io; public final class LeftMatcher extends TypeSafeMatcher> { @@ -30,11 +30,11 @@ public void describeTo(Description description) { @Override protected void describeMismatchSafely(Either item, Description mismatchDescription) { mismatchDescription.appendText("was "); - item.peek(fromConsumer(l -> { + item.peek(l -> io(() -> { mismatchDescription.appendText("Left value of "); lMatcher.describeMismatch(l, mismatchDescription); }), - fromConsumer(r -> mismatchDescription.appendValue(item))); + r -> io(() -> mismatchDescription.appendValue(item))); } public static LeftMatcher isLeftThat(Matcher lMatcher) { diff --git a/src/test/java/testsupport/matchers/RightMatcher.java b/src/test/java/testsupport/matchers/RightMatcher.java index 8e4f15c36..cce44fe03 100644 --- a/src/test/java/testsupport/matchers/RightMatcher.java +++ b/src/test/java/testsupport/matchers/RightMatcher.java @@ -5,8 +5,8 @@ import org.hamcrest.Matcher; import org.hamcrest.TypeSafeMatcher; -import static com.jnape.palatable.lambda.functions.Effect.fromConsumer; import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; +import static com.jnape.palatable.lambda.io.IO.io; public final class RightMatcher extends TypeSafeMatcher> { @@ -30,8 +30,8 @@ public void describeTo(Description description) { @Override protected void describeMismatchSafely(Either item, Description mismatchDescription) { mismatchDescription.appendText("was "); - item.peek(fromConsumer(l -> mismatchDescription.appendValue(item)), - fromConsumer(r -> { + item.peek(l -> io(() -> mismatchDescription.appendValue(item)), + r -> io(() -> { mismatchDescription.appendText("Right value of "); rMatcher.describeMismatch(r, mismatchDescription); })); diff --git a/src/test/java/testsupport/traits/ApplicativeLaws.java b/src/test/java/testsupport/traits/ApplicativeLaws.java index e449fe603..1d5c0904f 100644 --- a/src/test/java/testsupport/traits/ApplicativeLaws.java +++ b/src/test/java/testsupport/traits/ApplicativeLaws.java @@ -3,6 +3,7 @@ import com.jnape.palatable.lambda.adt.Maybe; import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functor.Applicative; +import com.jnape.palatable.lambda.io.IO; import com.jnape.palatable.lambda.monoid.builtin.Present; import com.jnape.palatable.traitor.traits.Trait; @@ -30,9 +31,8 @@ public void test(Applicative applicative) { this::testDiscardR, this::testLazyZip) ) - .peek(s -> { - throw new AssertionError("The following Applicative laws did not hold for instance of " + applicative.getClass() + ": \n\t - " + s); - }); + .peek(s -> IO.throwing(new AssertionError("The following Applicative laws did not hold for instance of " + + applicative.getClass() + ": \n\t - " + s))); } private Maybe testIdentity(Applicative applicative) { diff --git a/src/test/java/testsupport/traits/BifunctorLaws.java b/src/test/java/testsupport/traits/BifunctorLaws.java index 780519c17..d682435e6 100644 --- a/src/test/java/testsupport/traits/BifunctorLaws.java +++ b/src/test/java/testsupport/traits/BifunctorLaws.java @@ -3,6 +3,7 @@ import com.jnape.palatable.lambda.adt.Maybe; import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functor.Bifunctor; +import com.jnape.palatable.lambda.io.IO; import com.jnape.palatable.lambda.monoid.builtin.Present; import com.jnape.palatable.traitor.traits.Trait; @@ -22,9 +23,8 @@ public void test(Bifunctor bifunctor) { this::testRightIdentity, this::testMutualIdentity) ) - .peek(s -> { - throw new AssertionError("The following Bifunctor laws did not hold for instance of " + bifunctor.getClass() + ": \n\t - " + s); - }); + .peek(s -> IO.throwing(new AssertionError("The following Bifunctor laws did not hold for instance of " + + bifunctor.getClass() + ": \n\t - " + s))); } private Maybe testLeftIdentity(Bifunctor bifunctor) { diff --git a/src/test/java/testsupport/traits/FunctorLaws.java b/src/test/java/testsupport/traits/FunctorLaws.java index 13ad2b423..5fc7d5937 100644 --- a/src/test/java/testsupport/traits/FunctorLaws.java +++ b/src/test/java/testsupport/traits/FunctorLaws.java @@ -3,6 +3,7 @@ import com.jnape.palatable.lambda.adt.Maybe; import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functor.Functor; +import com.jnape.palatable.lambda.io.IO; import com.jnape.palatable.lambda.monoid.builtin.Present; import com.jnape.palatable.traitor.traits.Trait; @@ -21,9 +22,8 @@ public void test(Functor f) { fn -> fn.apply(f), asList(this::testIdentity, this::testComposition)) - .peek(s -> { - throw new AssertionError("The following Functor laws did not hold for instance of " + f.getClass() + ": \n\t - " + s); - }); + .peek(s -> IO.throwing(new AssertionError("The following Functor laws did not hold for instance of " + + f.getClass() + ": \n\t - " + s))); } private Maybe testIdentity(Functor f) { diff --git a/src/test/java/testsupport/traits/MonadLaws.java b/src/test/java/testsupport/traits/MonadLaws.java index 6a2df2392..2ff5a6e77 100644 --- a/src/test/java/testsupport/traits/MonadLaws.java +++ b/src/test/java/testsupport/traits/MonadLaws.java @@ -2,6 +2,7 @@ import com.jnape.palatable.lambda.adt.Maybe; import com.jnape.palatable.lambda.functions.Fn1; +import com.jnape.palatable.lambda.io.IO; import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.monoid.builtin.Present; import com.jnape.palatable.traitor.traits.Trait; @@ -24,9 +25,8 @@ public void test(Monad m) { this::testRightIdentity, this::testAssociativity, this::testJoin)) - .peek(s -> { - throw new AssertionError("The following Monad laws did not hold for instance of " + m.getClass() + ": \n\t - " + s); - }); + .peek(s -> IO.throwing(new AssertionError("The following Monad laws did not hold for instance of " + + m.getClass() + ": \n\t - " + s))); } private Maybe testLeftIdentity(Monad m) { diff --git a/src/test/java/testsupport/traits/TraversableLaws.java b/src/test/java/testsupport/traits/TraversableLaws.java index f27eca241..c0a6c4968 100644 --- a/src/test/java/testsupport/traits/TraversableLaws.java +++ b/src/test/java/testsupport/traits/TraversableLaws.java @@ -6,6 +6,7 @@ import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.builtin.Compose; import com.jnape.palatable.lambda.functor.builtin.Identity; +import com.jnape.palatable.lambda.io.IO; import com.jnape.palatable.lambda.monoid.builtin.Present; import com.jnape.palatable.lambda.traversable.Traversable; import com.jnape.palatable.traitor.traits.Trait; @@ -28,10 +29,8 @@ public void test(Traversable traversable) { this::testIdentity, this::testComposition) ) - .peek(s -> { - throw new AssertionError("The following Traversable laws did not hold for instance of " - + traversable.getClass() + ": \n\t - " + s); - }); + .peek(s -> IO.throwing(new AssertionError("The following Traversable laws did not hold for instance of " + + traversable.getClass() + ": \n\t - " + s))); } private Maybe testNaturality(Traversable trav) { From a6636d5c23451ff50dd9d7678024b495dbdf1dbb Mon Sep 17 00:00:00 2001 From: jnape Date: Wed, 15 May 2019 17:46:40 -0500 Subject: [PATCH 51/69] Renaming current fn2 sfm to curried, and new fn2 just aids inference --- .../com/jnape/palatable/lambda/functions/Fn1.java | 6 +++--- .../com/jnape/palatable/lambda/functions/Fn2.java | 13 +++++++++---- .../jnape/palatable/lambda/monoid/builtin/Endo.java | 4 ++-- .../java/com/jnape/palatable/lambda/optics/Iso.java | 2 +- .../lambda/optics/lenses/IterableLens.java | 4 ++-- .../palatable/lambda/traversable/LambdaMap.java | 4 ++-- .../jnape/palatable/lambda/functions/Fn2Test.java | 10 ++++++++-- 7 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java index fcf44bd69..d08195f42 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java @@ -12,7 +12,7 @@ import java.util.function.Function; -import static com.jnape.palatable.lambda.functions.Fn2.fn2; +import static com.jnape.palatable.lambda.functions.Fn2.curried; import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; /** @@ -69,7 +69,7 @@ default Fn0 thunk(A a) { * @return the widened function */ default Fn2 widen() { - return fn2(constantly(this)); + return curried(constantly(this)); } /** @@ -246,7 +246,7 @@ default Fn1 contraMap(Fn1 fn) { * @return an {@link Fn2}<Y, Z, B> */ default Fn2 compose(Fn2 before) { - return fn2(before.fmap(this::contraMap))::apply; + return curried(before.fmap(this::contraMap))::apply; } /** diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn2.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn2.java index 769f0a4d1..f0e138ec5 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Fn2.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn2.java @@ -100,7 +100,7 @@ default BiFunction toBiFunction() { */ @Override default Fn2 discardR(Applicative> appB) { - return fn2(Fn1.super.discardR(appB)); + return curried(Fn1.super.discardR(appB)); } /** @@ -108,7 +108,7 @@ default Fn2 discardR(Applicative> appB) { */ @Override default Fn2 diMapL(Fn1 fn) { - return fn2(Fn1.super.diMapL(fn)); + return curried(Fn1.super.diMapL(fn)); } /** @@ -116,7 +116,7 @@ default Fn2 diMapL(Fn1 fn) { */ @Override default Fn2 contraMap(Fn1 fn) { - return fn2(Fn1.super.contraMap(fn)); + return curried(Fn1.super.contraMap(fn)); } /** @@ -149,7 +149,12 @@ static Fn2 fromBiFunction(BiFunction the output type * @return the {@link Fn2} */ - static Fn2 fn2(Fn1> curriedFn1) { + static Fn2 curried(Fn1> curriedFn1) { return (a, b) -> curriedFn1.apply(a).apply(b); } + + static Fn2 fn2(Fn2 fn2) { + return fn2; + } + } diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Endo.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Endo.java index 75a4090ba..990689535 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Endo.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Endo.java @@ -4,7 +4,7 @@ import com.jnape.palatable.lambda.functions.Fn2; import com.jnape.palatable.lambda.monoid.Monoid; -import static com.jnape.palatable.lambda.functions.Fn2.fn2; +import static com.jnape.palatable.lambda.functions.Fn2.curried; import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id; /** @@ -35,7 +35,7 @@ public Fn1 checkedApply(Fn1 f, Fn1 g) { @Override public Fn2, A, A> apply(Fn1 f) { - return fn2(Monoid.super.apply(f)); + return curried(Monoid.super.apply(f)); } @SuppressWarnings("unchecked") diff --git a/src/main/java/com/jnape/palatable/lambda/optics/Iso.java b/src/main/java/com/jnape/palatable/lambda/optics/Iso.java index 11fdd4345..feb59212c 100644 --- a/src/main/java/com/jnape/palatable/lambda/optics/Iso.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/Iso.java @@ -137,7 +137,7 @@ default Iso discardR(Applicative> appB) { @Override default Iso flatMap(Fn1>> fn) { //noinspection RedundantTypeArguments - return unIso().fmap(bt -> Fn2.fn2( + return unIso().fmap(bt -> Fn2.curried( fn1(bt.fmap(fn.>fmap(Monad>::coerce)) .fmap(Iso::unIso) .fmap(Tuple2::_2) diff --git a/src/main/java/com/jnape/palatable/lambda/optics/lenses/IterableLens.java b/src/main/java/com/jnape/palatable/lambda/optics/lenses/IterableLens.java index b0bd8e810..b0f125c14 100644 --- a/src/main/java/com/jnape/palatable/lambda/optics/lenses/IterableLens.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/lenses/IterableLens.java @@ -6,7 +6,7 @@ import com.jnape.palatable.lambda.optics.Iso; import com.jnape.palatable.lambda.optics.Lens; -import static com.jnape.palatable.lambda.functions.Fn2.fn2; +import static com.jnape.palatable.lambda.functions.Fn2.curried; import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id; import static com.jnape.palatable.lambda.functions.builtin.fn2.Cons.cons; import static com.jnape.palatable.lambda.functions.builtin.fn2.Map.map; @@ -45,7 +45,7 @@ public static Lens.Simple, Maybe> head() { * @return a lens focusing on the tail of an {@link Iterable} */ public static Lens.Simple, Iterable> tail() { - return simpleLens(Tail::tail, fn2(Head.head().fmap(o -> o.fmap(cons()).orElse(id())))); + return simpleLens(Tail::tail, curried(Head.head().fmap(o -> o.fmap(cons()).orElse(id())))); } /** diff --git a/src/main/java/com/jnape/palatable/lambda/traversable/LambdaMap.java b/src/main/java/com/jnape/palatable/lambda/traversable/LambdaMap.java index 94a2e2e7c..81f6dd953 100644 --- a/src/main/java/com/jnape/palatable/lambda/traversable/LambdaMap.java +++ b/src/main/java/com/jnape/palatable/lambda/traversable/LambdaMap.java @@ -10,7 +10,7 @@ import java.util.Objects; import static com.jnape.palatable.lambda.adt.hlist.HList.tuple; -import static com.jnape.palatable.lambda.functions.Fn2.fn2; +import static com.jnape.palatable.lambda.functions.Fn2.curried; import static com.jnape.palatable.lambda.functions.builtin.fn2.Into.into; import static com.jnape.palatable.lambda.functions.builtin.fn2.Map.map; import static com.jnape.palatable.lambda.functions.builtin.fn2.ToMap.toMap; @@ -50,7 +50,7 @@ public LambdaMap fmap(Fn1 fn) { AppC extends Applicative, AppTrav extends Applicative> AppTrav traverse(Fn1 fn, Fn1 pure) { - return foldLeft(fn2(appTrav -> into((k, appV) -> (AppTrav) appTrav.zip(appV.fmap(v -> m -> { + return foldLeft(curried(appTrav -> into((k, appV) -> (AppTrav) appTrav.zip(appV.fmap(v -> m -> { ((LambdaMap) m).unwrap().put(k, v); return m; })))), diff --git a/src/test/java/com/jnape/palatable/lambda/functions/Fn2Test.java b/src/test/java/com/jnape/palatable/lambda/functions/Fn2Test.java index dbe1d5b7a..71e3a65e3 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/Fn2Test.java +++ b/src/test/java/com/jnape/palatable/lambda/functions/Fn2Test.java @@ -36,9 +36,15 @@ public void toBiFunction() { } @Test - public void fn2() { + public void curried() { Fn1> curriedFn1 = (x) -> (y) -> String.format(x, y); - assertEquals("foo bar", Fn2.fn2(curriedFn1).apply("foo %s", "bar")); + assertEquals("foo bar", Fn2.curried(curriedFn1).apply("foo %s", "bar")); + } + + @Test + public void fn2() { + Fn2 fn2 = Fn2.fn2(String::format); + assertEquals("foo bar", fn2.apply("foo %s", "bar")); } @Test From 8cf4050d971b6b49dd33a2217ff4424ab11408cb Mon Sep 17 00:00:00 2001 From: jnape Date: Wed, 15 May 2019 17:52:27 -0500 Subject: [PATCH 52/69] Effect#andThen for right-to-left composition of effects --- .../com/jnape/palatable/lambda/functions/Effect.java | 10 ++++++++++ .../jnape/palatable/lambda/functions/EffectTest.java | 11 +++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Effect.java b/src/main/java/com/jnape/palatable/lambda/functions/Effect.java index 6e23e2932..fd135aa25 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Effect.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Effect.java @@ -46,6 +46,16 @@ default IO apply(A a) { } } + /** + * Left-to-right composition of {@link Effect Effects}. + * + * @param effect the other {@link Effect} + * @return the composed {@link Effect} + */ + default Effect andThen(Effect effect) { + return a -> apply(a).flatMap(constantly(effect.apply(a))); + } + /** * {@inheritDoc} */ diff --git a/src/test/java/com/jnape/palatable/lambda/functions/EffectTest.java b/src/test/java/com/jnape/palatable/lambda/functions/EffectTest.java index c0a442762..49554fae3 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/EffectTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functions/EffectTest.java @@ -13,6 +13,8 @@ import static com.jnape.palatable.lambda.functions.Effect.effect; import static com.jnape.palatable.lambda.functions.Effect.fromConsumer; import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; +import static com.jnape.palatable.lambda.functions.specialized.SideEffect.sideEffect; +import static com.jnape.palatable.lambda.io.IO.io; import static java.util.Arrays.asList; import static java.util.Collections.singletonList; import static org.junit.Assert.assertEquals; @@ -36,6 +38,15 @@ public void covariantReturns() { assertEquals(asList("1", "2", "3", "4"), results); } + @Test + public void andThen() { + AtomicInteger counter = new AtomicInteger(); + Effect inc = c -> io(sideEffect(c::incrementAndGet)); + + inc.andThen(inc).apply(counter).unsafePerformIO(); + assertEquals(2, counter.get()); + } + @Test public void staticFactoryMethods() { AtomicInteger counter = new AtomicInteger(); From 03065e915731bb310ff800d2c0966bbff4dd94bc Mon Sep 17 00:00:00 2001 From: jnape Date: Wed, 15 May 2019 18:16:24 -0500 Subject: [PATCH 53/69] Adding javadoc --- .../java/com/jnape/palatable/lambda/functions/Fn2.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Fn2.java b/src/main/java/com/jnape/palatable/lambda/functions/Fn2.java index f0e138ec5..0528ff71a 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Fn2.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn2.java @@ -153,8 +153,16 @@ static Fn2 curried(Fn1> curriedFn1) { return (a, b) -> curriedFn1.apply(a).apply(b); } + /** + * Static method to aid inference. + * + * @param fn2 the {@link Fn2} + * @param the first input type + * @param the second input type + * @param the output type + * @return the {@link Fn2} + */ static Fn2 fn2(Fn2 fn2) { return fn2; } - } From 44e7f2220cdc22549bad3ef4afab37b44e6c321d Mon Sep 17 00:00:00 2001 From: jnape Date: Thu, 16 May 2019 18:00:01 -0500 Subject: [PATCH 54/69] Effect#noop allows custom parametricity --- .../java/com/jnape/palatable/lambda/functions/Effect.java | 4 ++-- .../com/jnape/palatable/lambda/functions/EffectTest.java | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Effect.java b/src/main/java/com/jnape/palatable/lambda/functions/Effect.java index fd135aa25..077935f49 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Effect.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Effect.java @@ -97,7 +97,7 @@ static Effect fromConsumer(Consumer consumer) { * @param sideEffect the {@link SideEffect} * @return the {@link Effect} */ - static Effect effect(SideEffect sideEffect) { + static Effect effect(SideEffect sideEffect) { return effect(constantly(io(sideEffect))); } @@ -108,7 +108,7 @@ static Effect effect(SideEffect sideEffect) { */ @SuppressWarnings("unused") static Effect noop() { - return effect(NOOP).contraMap(constantly(UNIT)); + return effect(NOOP); } /** diff --git a/src/test/java/com/jnape/palatable/lambda/functions/EffectTest.java b/src/test/java/com/jnape/palatable/lambda/functions/EffectTest.java index 49554fae3..0609643f5 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/EffectTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functions/EffectTest.java @@ -9,7 +9,6 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; -import static com.jnape.palatable.lambda.adt.Unit.UNIT; import static com.jnape.palatable.lambda.functions.Effect.effect; import static com.jnape.palatable.lambda.functions.Effect.fromConsumer; import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; @@ -51,8 +50,8 @@ public void andThen() { public void staticFactoryMethods() { AtomicInteger counter = new AtomicInteger(); - Effect runnableEffect = effect(counter::incrementAndGet); - runnableEffect.apply(UNIT).unsafePerformIO(); + Effect sideEffect = effect(counter::incrementAndGet); + sideEffect.apply("foo").unsafePerformIO(); assertEquals(1, counter.get()); Effect fnEffect = Effect.fromConsumer(AtomicInteger::incrementAndGet); From 5a2ae62963bf23291a0ba9df07903a0d55560021 Mon Sep 17 00:00:00 2001 From: jnape Date: Fri, 17 May 2019 00:03:53 -0500 Subject: [PATCH 55/69] Either#peek only requires Fn1 --- src/main/java/com/jnape/palatable/lambda/adt/Either.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/jnape/palatable/lambda/adt/Either.java b/src/main/java/com/jnape/palatable/lambda/adt/Either.java index 360043cb6..0fe24612f 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/Either.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/Either.java @@ -2,7 +2,6 @@ import com.jnape.palatable.lambda.adt.choice.Choice3; import com.jnape.palatable.lambda.adt.coproduct.CoProduct2; -import com.jnape.palatable.lambda.functions.Effect; import com.jnape.palatable.lambda.functions.Fn0; import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functions.Fn2; @@ -166,7 +165,7 @@ public final Either merge(Fn2 leftFn, * @param effect the effecting consumer * @return the Either, unaltered */ - public Either peek(Effect effect) { + public Either peek(Fn1> effect) { return Peek.peek(effect, this); } From 6f30dee6d9352fef8af4088eb3945b0d5b2d16c9 Mon Sep 17 00:00:00 2001 From: jnape Date: Fri, 17 May 2019 18:53:05 -0500 Subject: [PATCH 56/69] Traversable#traverse requires one less type parameter --- src/main/java/com/jnape/palatable/lambda/adt/Either.java | 3 +-- src/main/java/com/jnape/palatable/lambda/adt/Maybe.java | 3 +-- src/main/java/com/jnape/palatable/lambda/adt/These.java | 4 ++-- src/main/java/com/jnape/palatable/lambda/adt/Try.java | 3 +-- .../java/com/jnape/palatable/lambda/adt/choice/Choice2.java | 3 +-- .../java/com/jnape/palatable/lambda/adt/choice/Choice3.java | 3 +-- .../java/com/jnape/palatable/lambda/adt/choice/Choice4.java | 3 +-- .../java/com/jnape/palatable/lambda/adt/choice/Choice5.java | 3 +-- .../java/com/jnape/palatable/lambda/adt/choice/Choice6.java | 3 +-- .../java/com/jnape/palatable/lambda/adt/choice/Choice7.java | 3 +-- .../java/com/jnape/palatable/lambda/adt/choice/Choice8.java | 3 +-- .../jnape/palatable/lambda/adt/hlist/SingletonHList.java | 3 +-- .../java/com/jnape/palatable/lambda/adt/hlist/Tuple2.java | 6 +++--- .../java/com/jnape/palatable/lambda/adt/hlist/Tuple3.java | 6 +++--- .../java/com/jnape/palatable/lambda/adt/hlist/Tuple4.java | 6 +++--- .../java/com/jnape/palatable/lambda/adt/hlist/Tuple5.java | 6 +++--- .../java/com/jnape/palatable/lambda/adt/hlist/Tuple6.java | 6 +++--- .../java/com/jnape/palatable/lambda/adt/hlist/Tuple7.java | 6 +++--- .../java/com/jnape/palatable/lambda/adt/hlist/Tuple8.java | 6 +++--- .../lambda/functions/recursion/RecursiveResult.java | 3 +-- .../com/jnape/palatable/lambda/functor/builtin/Const.java | 3 +-- .../jnape/palatable/lambda/functor/builtin/Identity.java | 3 +-- .../com/jnape/palatable/lambda/functor/builtin/Lazy.java | 3 +-- .../jnape/palatable/lambda/traversable/LambdaIterable.java | 3 +-- .../com/jnape/palatable/lambda/traversable/LambdaMap.java | 5 ++--- .../com/jnape/palatable/lambda/traversable/Traversable.java | 5 ++--- 26 files changed, 43 insertions(+), 61 deletions(-) diff --git a/src/main/java/com/jnape/palatable/lambda/adt/Either.java b/src/main/java/com/jnape/palatable/lambda/adt/Either.java index 0fe24612f..29e421570 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/Either.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/Either.java @@ -282,8 +282,7 @@ public final Either discardR(Applicative> appB) { @Override @SuppressWarnings("unchecked") public final , TravB extends Traversable>, - AppB extends Applicative, - AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + AppTrav extends Applicative> AppTrav traverse(Fn1> fn, Fn1 pure) { return (AppTrav) match(l -> pure.apply((TravB) left(l)), r -> fn.apply(r).fmap(Either::right)); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/Maybe.java b/src/main/java/com/jnape/palatable/lambda/adt/Maybe.java index 2913599a0..4cc726673 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/Maybe.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/Maybe.java @@ -213,8 +213,7 @@ public final Maybe peek(Fn1> effect) { @Override @SuppressWarnings("unchecked") public final , TravB extends Traversable>, - AppB extends Applicative, - AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + AppTrav extends Applicative> AppTrav traverse(Fn1> fn, Fn1 pure) { return match(__ -> pure.apply((TravB) Maybe.nothing()), a -> (AppTrav) fn.apply(a).fmap(Maybe::just)); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/These.java b/src/main/java/com/jnape/palatable/lambda/adt/These.java index 039b149fd..5f8e67270 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/These.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/These.java @@ -62,8 +62,8 @@ public final These pure(C c) { @Override @SuppressWarnings("unchecked") public , TravB extends Traversable>, - AppB extends Applicative, AppTrav extends Applicative> - AppTrav traverse(Fn1 fn, Fn1 pure) { + AppTrav extends Applicative> + AppTrav traverse(Fn1> fn, Fn1 pure) { return match(a -> pure.apply((TravB) a(a)), b -> fn.apply(b).fmap(this::pure).fmap(Applicative::coerce).coerce(), into((a, b) -> fn.apply(b).fmap(c -> both(a, c)).fmap(Applicative::coerce).coerce())); diff --git a/src/main/java/com/jnape/palatable/lambda/adt/Try.java b/src/main/java/com/jnape/palatable/lambda/adt/Try.java index 00b629a72..40a678339 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/Try.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/Try.java @@ -224,8 +224,7 @@ public Try discardR(Applicative> appB) { @Override @SuppressWarnings("unchecked") public , TravB extends Traversable>, - AppB extends Applicative, - AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + AppTrav extends Applicative> AppTrav traverse(Fn1> fn, Fn1 pure) { return match(t -> pure.apply((TravB) failure(t)), a -> fn.apply(a).fmap(Try::success).fmap(Applicative::coerce).coerce()); diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice2.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice2.java index 24cc10bc5..7366881c2 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice2.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice2.java @@ -151,8 +151,7 @@ public final Choice2 flatMap(Fn1, TravB extends Traversable>, - AppB extends Applicative, - AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + AppTrav extends Applicative> AppTrav traverse(Fn1> fn, Fn1 pure) { return match(a -> pure.apply((TravB) a(a)), b -> fn.apply(b).>fmap(Choice2::b).fmap(Functor::coerce).coerce()); diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice3.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice3.java index 0b58ca14f..5e4388419 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice3.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice3.java @@ -152,8 +152,7 @@ public Choice3 flatMap(Fn1, TravB extends Traversable>, - AppB extends Applicative, - AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + AppTrav extends Applicative> AppTrav traverse(Fn1> fn, Fn1 pure) { return match(a -> pure.apply((TravB) Choice3.a(a)).coerce(), b -> pure.apply((TravB) Choice3.b(b)).coerce(), diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice4.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice4.java index a93eae6cd..4f79f3d5e 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice4.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice4.java @@ -152,8 +152,7 @@ public Choice4 flatMap(Fn1, TravB extends Traversable>, - AppB extends Applicative, - AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + AppTrav extends Applicative> AppTrav traverse(Fn1> fn, Fn1 pure) { return match(a -> pure.apply((TravB) Choice4.a(a)).coerce(), b -> pure.apply((TravB) Choice4.b(b)).coerce(), diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice5.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice5.java index e3e4a7958..8714e4395 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice5.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice5.java @@ -156,8 +156,7 @@ public Choice5 flatMap(Fn1, TravB extends Traversable>, - AppB extends Applicative, - AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + AppTrav extends Applicative> AppTrav traverse(Fn1> fn, Fn1 pure) { return match(a -> pure.apply((TravB) Choice5.a(a)).coerce(), b -> pure.apply((TravB) Choice5.b(b)).coerce(), diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice6.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice6.java index dd788fb5b..ff2ba8df5 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice6.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice6.java @@ -161,8 +161,7 @@ public Choice6 flatMap(Fn1, TravB extends Traversable>, - AppB extends Applicative, - AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + AppTrav extends Applicative> AppTrav traverse(Fn1> fn, Fn1 pure) { return match(a -> pure.apply((TravB) Choice6.a(a)).coerce(), b -> pure.apply((TravB) Choice6.b(b)).coerce(), diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice7.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice7.java index a72489ecb..590796133 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice7.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice7.java @@ -163,8 +163,7 @@ public Choice7 flatMap( @Override @SuppressWarnings("unchecked") public , TravB extends Traversable>, - AppB extends Applicative, - AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + AppTrav extends Applicative> AppTrav traverse(Fn1> fn, Fn1 pure) { return match(a -> pure.apply((TravB) Choice7.a(a)).coerce(), b -> pure.apply((TravB) Choice7.b(b)).coerce(), diff --git a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice8.java b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice8.java index 2d21f27ba..cfdb71587 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice8.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/choice/Choice8.java @@ -157,8 +157,7 @@ public Choice8 flatMap( @Override @SuppressWarnings("unchecked") public , TravB extends Traversable>, - AppB extends Applicative, - AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + AppTrav extends Applicative> AppTrav traverse(Fn1> fn, Fn1 pure) { return match(a -> pure.apply((TravB) Choice8.a(a)).coerce(), b -> pure.apply((TravB) Choice8.b(b)).coerce(), diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/SingletonHList.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/SingletonHList.java index ca8f76b5c..176745aba 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/SingletonHList.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/SingletonHList.java @@ -70,8 +70,7 @@ public <_1Prime> SingletonHList<_1Prime> flatMap(Fn1, TravB extends Traversable>, - AppB extends Applicative, - AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + AppTrav extends Applicative> AppTrav traverse(Fn1> fn, Fn1 pure) { return fn.apply(head()).fmap(SingletonHList::new).fmap(Applicative::coerce).coerce(); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple2.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple2.java index afb1d9e95..78bf332c3 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple2.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple2.java @@ -133,9 +133,9 @@ public <_2Prime> Tuple2<_1, _2Prime> flatMap(Fn1, TravB extends Traversable<_2Prime, Tuple2<_1, ?>>, - AppB extends Applicative<_2Prime, App>, - AppTrav extends Applicative> AppTrav traverse(Fn1 fn, - Fn1 pure) { + AppTrav extends Applicative> AppTrav traverse( + Fn1> fn, + Fn1 pure) { return fn.apply(_2).fmap(_2Prime -> fmap(constantly(_2Prime))).fmap(Applicative::coerce).coerce(); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple3.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple3.java index 01ed4cf6c..0e99a88b9 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple3.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple3.java @@ -135,9 +135,9 @@ public <_3Prime> Tuple3<_1, _2, _3Prime> flatMap( @Override public <_3Prime, App extends Applicative, TravB extends Traversable<_3Prime, Tuple3<_1, _2, ?>>, - AppB extends Applicative<_3Prime, App>, - AppTrav extends Applicative> AppTrav traverse(Fn1 fn, - Fn1 pure) { + AppTrav extends Applicative> AppTrav traverse( + Fn1> fn, + Fn1 pure) { return fn.apply(_3).fmap(_3Prime -> fmap(constantly(_3Prime))).fmap(Applicative::coerce).coerce(); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple4.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple4.java index 90a1d3ec6..1e99d3fd5 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple4.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple4.java @@ -150,9 +150,9 @@ public <_4Prime> Tuple4<_1, _2, _3, _4Prime> flatMap( @Override public <_4Prime, App extends Applicative, TravB extends Traversable<_4Prime, Tuple4<_1, _2, _3, ?>>, - AppB extends Applicative<_4Prime, App>, - AppTrav extends Applicative> AppTrav traverse(Fn1 fn, - Fn1 pure) { + AppTrav extends Applicative> AppTrav traverse( + Fn1> fn, + Fn1 pure) { return fn.apply(_4).fmap(_4Prime -> fmap(constantly(_4Prime))).fmap(Applicative::coerce).coerce(); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple5.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple5.java index 2e321fbae..0292831d2 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple5.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple5.java @@ -170,9 +170,9 @@ public <_5Prime> Tuple5<_1, _2, _3, _4, _5Prime> flatMap( @Override public <_5Prime, App extends Applicative, TravB extends Traversable<_5Prime, Tuple5<_1, _2, _3, _4, ?>>, - AppB extends Applicative<_5Prime, App>, - AppTrav extends Applicative> AppTrav traverse(Fn1 fn, - Fn1 pure) { + AppTrav extends Applicative> AppTrav traverse( + Fn1> fn, + Fn1 pure) { return fn.apply(_5).fmap(_3Prime -> fmap(constantly(_3Prime))).fmap(Applicative::coerce).coerce(); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple6.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple6.java index 4ec22546b..86991a8ae 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple6.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple6.java @@ -191,9 +191,9 @@ public <_6Prime> Tuple6<_1, _2, _3, _4, _5, _6Prime> flatMap( @Override public <_6Prime, App extends Applicative, TravB extends Traversable<_6Prime, Tuple6<_1, _2, _3, _4, _5, ?>>, - AppB extends Applicative<_6Prime, App>, - AppTrav extends Applicative> AppTrav traverse(Fn1 fn, - Fn1 pure) { + AppTrav extends Applicative> AppTrav traverse( + Fn1> fn, + Fn1 pure) { return fn.apply(_6).fmap(_6Prime -> fmap(constantly(_6Prime))).fmap(Applicative::coerce).coerce(); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple7.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple7.java index e42cc4968..60d42664c 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple7.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple7.java @@ -212,9 +212,9 @@ public <_7Prime> Tuple7<_1, _2, _3, _4, _5, _6, _7Prime> flatMap( @Override public <_7Prime, App extends Applicative, TravB extends Traversable<_7Prime, Tuple7<_1, _2, _3, _4, _5, _6, ?>>, - AppB extends Applicative<_7Prime, App>, - AppTrav extends Applicative> AppTrav traverse(Fn1 fn, - Fn1 pure) { + AppTrav extends Applicative> AppTrav traverse( + Fn1> fn, + Fn1 pure) { return fn.apply(_7).fmap(_7Prime -> fmap(constantly(_7Prime))).fmap(Applicative::coerce).coerce(); } diff --git a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple8.java b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple8.java index e9db4aba9..81054635e 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple8.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple8.java @@ -232,9 +232,9 @@ public <_8Prime> Tuple8<_1, _2, _3, _4, _5, _6, _7, _8Prime> flatMap( @Override public <_8Prime, App extends Applicative, TravB extends Traversable<_8Prime, Tuple8<_1, _2, _3, _4, _5, _6, _7, ?>>, - AppB extends Applicative<_8Prime, App>, - AppTrav extends Applicative> AppTrav traverse(Fn1 fn, - Fn1 pure) { + AppTrav extends Applicative> AppTrav traverse( + Fn1> fn, + Fn1 pure) { return fn.apply(_8).fmap(_8Prime -> fmap(constantly(_8Prime))).fmap(Applicative::coerce).coerce(); } diff --git a/src/main/java/com/jnape/palatable/lambda/functions/recursion/RecursiveResult.java b/src/main/java/com/jnape/palatable/lambda/functions/recursion/RecursiveResult.java index 29ddc08c8..c21c62908 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/recursion/RecursiveResult.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/recursion/RecursiveResult.java @@ -78,8 +78,7 @@ public RecursiveResult discardR(Applicative> @Override public , TravB extends Traversable>, - AppB extends Applicative, - AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + AppTrav extends Applicative> AppTrav traverse(Fn1> fn, Fn1 pure) { return match(__ -> pure.apply(coerce()), b -> fn.apply(b).fmap(this::pure).fmap(RecursiveResult::coerce).coerce()); diff --git a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Const.java b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Const.java index 279d04595..73e974ede 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Const.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Const.java @@ -103,8 +103,7 @@ public Const flatMap(Fn1>> f */ @Override public , TravB extends Traversable>, - AppB extends Applicative, - AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + AppTrav extends Applicative> AppTrav traverse(Fn1> fn, Fn1 pure) { return pure.apply(coerce()); } diff --git a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Identity.java b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Identity.java index bb298596c..dba617294 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Identity.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Identity.java @@ -92,8 +92,7 @@ public Identity discardR(Applicative> appB) { @Override @SuppressWarnings("unchecked") public , TravB extends Traversable>, - AppB extends Applicative, - AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + AppTrav extends Applicative> AppTrav traverse(Fn1> fn, Fn1 pure) { return (AppTrav) fn.apply(runIdentity()).fmap(Identity::new); } diff --git a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Lazy.java b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Lazy.java index c79a4c0c7..fff6acc72 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Lazy.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Lazy.java @@ -50,8 +50,7 @@ public Lazy flatMap(Fn1>> f) { @Override @SuppressWarnings("unchecked") public , TravB extends Traversable>, - AppB extends Applicative, - AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + AppTrav extends Applicative> AppTrav traverse(Fn1> fn, Fn1 pure) { return fn.apply(value()).fmap(b -> (TravB) lazy(b)).coerce(); } diff --git a/src/main/java/com/jnape/palatable/lambda/traversable/LambdaIterable.java b/src/main/java/com/jnape/palatable/lambda/traversable/LambdaIterable.java index b59ccfcc4..6fe5f4a38 100644 --- a/src/main/java/com/jnape/palatable/lambda/traversable/LambdaIterable.java +++ b/src/main/java/com/jnape/palatable/lambda/traversable/LambdaIterable.java @@ -112,8 +112,7 @@ public LambdaIterable flatMap(Fn1, TravB extends Traversable>, - AppB extends Applicative, - AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + AppTrav extends Applicative> AppTrav traverse(Fn1> fn, Fn1 pure) { return FoldRight.foldRight( (a, lglb) -> fn.apply(a) diff --git a/src/main/java/com/jnape/palatable/lambda/traversable/LambdaMap.java b/src/main/java/com/jnape/palatable/lambda/traversable/LambdaMap.java index 81f6dd953..f8e8c7fd2 100644 --- a/src/main/java/com/jnape/palatable/lambda/traversable/LambdaMap.java +++ b/src/main/java/com/jnape/palatable/lambda/traversable/LambdaMap.java @@ -47,15 +47,14 @@ public LambdaMap fmap(Fn1 fn) { @Override @SuppressWarnings("unchecked") public , TravC extends Traversable>, - AppC extends Applicative, - AppTrav extends Applicative> AppTrav traverse(Fn1 fn, + AppTrav extends Applicative> AppTrav traverse(Fn1> fn, Fn1 pure) { return foldLeft(curried(appTrav -> into((k, appV) -> (AppTrav) appTrav.zip(appV.fmap(v -> m -> { ((LambdaMap) m).unwrap().put(k, v); return m; })))), pure.apply((TravC) LambdaMap.wrap(new HashMap<>())), - this.fmap(fn).unwrap().entrySet()); + this.fmap(fn).unwrap().entrySet()); } @Override diff --git a/src/main/java/com/jnape/palatable/lambda/traversable/Traversable.java b/src/main/java/com/jnape/palatable/lambda/traversable/Traversable.java index 91d0a66c6..d9f24621c 100644 --- a/src/main/java/com/jnape/palatable/lambda/traversable/Traversable.java +++ b/src/main/java/com/jnape/palatable/lambda/traversable/Traversable.java @@ -38,15 +38,14 @@ public interface Traversable> extends Functor the resulting element type * @param the result applicative type * @param this Traversable instance over B - * @param the result applicative instance over B * @param the full inferred resulting type from the traversal * @param fn the function to apply * @param pure the applicative pure function * @return the traversed Traversable, wrapped inside an applicative */ - , TravB extends Traversable, AppB extends Applicative, + , TravB extends Traversable, AppTrav extends Applicative> AppTrav traverse( - Fn1 fn, Fn1 pure); + Fn1> fn, Fn1 pure); @Override default Traversable fmap(Fn1 fn) { From a929f92a5affec62cc3e4afaa5db86b60b95d2aa Mon Sep 17 00:00:00 2001 From: jnape Date: Fri, 17 May 2019 19:02:50 -0500 Subject: [PATCH 57/69] Sequence#sequence requires 2 fewer type parameters --- .../functions/builtin/fn2/Sequence.java | 66 ++++++++----------- .../functions/builtin/fn2/SequenceTest.java | 5 ++ 2 files changed, 33 insertions(+), 38 deletions(-) diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Sequence.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Sequence.java index 2237966c3..bed18e1aa 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Sequence.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Sequence.java @@ -24,82 +24,72 @@ * @param the Traversable element type * @param the Applicative unification parameter * @param the Traversable unification parameter - * @param the Applicative instance wrapped in the input Traversable * @param the Traversable instance wrapped in the output Applicative * @param the concrete parametrized output Applicative type - * @param the concrete parametrized input Traversable type */ public final class Sequence, Trav extends Traversable, - AppA extends Applicative, TravA extends Traversable, - AppTrav extends Applicative, - TravApp extends Traversable> implements Fn2, AppTrav> { + AppTrav extends Applicative> implements + Fn2, Trav>, Fn1, AppTrav> { - private static final Sequence INSTANCE = new Sequence<>(); + private static final Sequence INSTANCE = new Sequence<>(); private Sequence() { } @Override - public AppTrav checkedApply(TravApp traversable, Fn1 pure) { + public AppTrav checkedApply(Traversable, Trav> traversable, + Fn1 pure) { return traversable.traverse(id(), pure); } @SuppressWarnings("unchecked") public static , Trav extends Traversable, - AppA extends Applicative, TravA extends Traversable, - AppTrav extends Applicative, - TravApp extends Traversable> Sequence sequence() { - return (Sequence) INSTANCE; + AppTrav extends Applicative> Sequence sequence() { + return (Sequence) INSTANCE; } public static , Trav extends Traversable, - AppA extends Applicative, TravA extends Traversable, - AppTrav extends Applicative, - TravApp extends Traversable> Fn1, AppTrav> sequence( - TravApp traversable) { - return Sequence.sequence().apply(traversable); + AppTrav extends Applicative> Fn1, AppTrav> sequence( + Traversable, Trav> traversable) { + return Sequence.sequence().apply(traversable); } public static , Trav extends Traversable, TravA extends Traversable, - AppA extends Applicative, - AppTrav extends Applicative, - TravApp extends Traversable> AppTrav sequence(TravApp traversable, - Fn1 pure) { - return Sequence.sequence(traversable).apply(pure); + AppTrav extends Applicative> AppTrav sequence( + Traversable, Trav> traversable, + Fn1 pure) { + return Sequence.sequence(traversable).apply(pure); } @SuppressWarnings({"unchecked", "RedundantTypeArguments"}) - public static , AppA extends Applicative, - AppIterable extends Applicative, App>, - IterableApp extends Iterable> - Fn1, ? extends AppIterable>, AppIterable> sequence(IterableApp iterableApp) { - return pure -> (AppIterable) Sequence., LambdaIterable, AppA, Applicative, App>, LambdaIterable>sequence( + public static , AppIterable extends Applicative, App>> + Fn1, ? extends AppIterable>, AppIterable> sequence( + Iterable> iterableApp) { + return pure -> (AppIterable) Sequence., LambdaIterable, Applicative, App>>sequence( LambdaIterable.wrap(iterableApp), x -> pure.apply(x.unwrap()).fmap(LambdaIterable::wrap)) .fmap(LambdaIterable::unwrap); } - public static , AppA extends Applicative, - AppIterable extends Applicative, App>, IterableApp extends Iterable> - AppIterable sequence(IterableApp iterableApp, Fn1, ? extends AppIterable> pure) { - return Sequence.sequence(iterableApp).apply(pure); + public static , AppIterable extends Applicative, App>> + AppIterable sequence(Iterable> iterableApp, + Fn1, ? extends AppIterable> pure) { + return Sequence.sequence(iterableApp).apply(pure); } @SuppressWarnings({"unchecked", "RedundantTypeArguments"}) - public static , AppB extends Applicative, - AppMap extends Applicative, App>, MapApp extends Map> - Fn1, ? extends AppMap>, AppMap> sequence(MapApp mapApp) { - return pure -> (AppMap) Sequence., LambdaMap, AppB, Applicative, App>, LambdaMap>sequence( + public static , AppMap extends Applicative, App>> + Fn1, ? extends AppMap>, AppMap> sequence(Map> mapApp) { + return pure -> (AppMap) Sequence., LambdaMap, Applicative, App>>sequence( LambdaMap.wrap(mapApp), x -> pure.apply(x.unwrap()).fmap(LambdaMap::wrap)) .fmap(LambdaMap::unwrap); } - public static , AppB extends Applicative, - AppMap extends Applicative, App>, MapApp extends Map> - AppMap sequence(MapApp mapApp, Fn1, ? extends AppMap> pure) { - return Sequence.sequence(mapApp).apply(pure); + public static , AppMap extends Applicative, App>> + AppMap sequence(Map> mapApp, Fn1, ? extends AppMap> pure) { + return Sequence.sequence(mapApp).apply(pure); } } diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/SequenceTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/SequenceTest.java index b2e65864e..cec572406 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/SequenceTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/SequenceTest.java @@ -7,6 +7,8 @@ import com.jnape.palatable.lambda.functor.builtin.Identity; import org.junit.Test; +import java.util.Map; + import static com.jnape.palatable.lambda.adt.Either.right; import static com.jnape.palatable.lambda.adt.Maybe.just; import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id; @@ -68,5 +70,8 @@ public void compilation() { Maybe> d = sequence(asList(just(1), just(2)), Maybe::just); assertThat(d.orElseThrow(AssertionError::new), iterates(1, 2)); + + Either> e = sequence(singletonMap("foo", right(1)), Either::right); + assertEquals(right(singletonMap("foo", 1)), e); } } \ No newline at end of file From bbb97ae97f80cf558afe74bcc89a8384f3596aff Mon Sep 17 00:00:00 2001 From: jnape Date: Sun, 19 May 2019 18:36:08 -0500 Subject: [PATCH 58/69] Prism is a Monad; ProtoOptic offers implicit Profunctor/Identity optic --- .../jnape/palatable/lambda/optics/Prism.java | 108 +++++++++++++++--- .../palatable/lambda/optics/ProtoOptic.java | 16 ++- .../palatable/lambda/optics/PrismTest.java | 14 +++ 3 files changed, 119 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/jnape/palatable/lambda/optics/Prism.java b/src/main/java/com/jnape/palatable/lambda/optics/Prism.java index d83f01774..f90635c63 100644 --- a/src/main/java/com/jnape/palatable/lambda/optics/Prism.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/Prism.java @@ -7,16 +7,27 @@ import com.jnape.palatable.lambda.adt.hlist.Tuple2; import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functions.specialized.Pure; +import com.jnape.palatable.lambda.functor.Applicative; import com.jnape.palatable.lambda.functor.Cocartesian; import com.jnape.palatable.lambda.functor.Functor; import com.jnape.palatable.lambda.functor.Profunctor; import com.jnape.palatable.lambda.functor.builtin.Identity; +import com.jnape.palatable.lambda.functor.builtin.Lazy; import com.jnape.palatable.lambda.functor.builtin.Market; +import com.jnape.palatable.lambda.monad.Monad; import com.jnape.palatable.lambda.optics.functions.Matching; import com.jnape.palatable.lambda.optics.functions.Pre; import com.jnape.palatable.lambda.optics.functions.Re; import com.jnape.palatable.lambda.optics.functions.View; +import static com.jnape.palatable.lambda.adt.Either.left; +import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; +import static com.jnape.palatable.lambda.functions.builtin.fn1.Downcast.downcast; +import static com.jnape.palatable.lambda.functions.builtin.fn1.Upcast.upcast; +import static com.jnape.palatable.lambda.optics.Prism.Simple.adapt; +import static com.jnape.palatable.lambda.optics.functions.Matching.matching; +import static com.jnape.palatable.lambda.optics.functions.Re.re; + /** * Prisms are {@link Iso Isos} that can fail in one direction. Example: *
@@ -42,10 +53,23 @@
  * @param  the input that guarantees its output
  */
 @FunctionalInterface
-public interface Prism extends
-        ProtoOptic, S, T, A, B>,
-        Optic, Identity, S, T, A, B> {
+public interface Prism extends ProtoOptic, S, T, A, B>, Monad> {
 
+    /**
+     * Recover the two mappings encapsulated by this {@link Prism} by sending it through a {@link Market}.
+     *
+     * @return a {@link Tuple2 tuple} of the two mappings encapsulated by this {@link Prism}
+     */
+    default Tuple2, Fn1>> unPrism() {
+        return Tuple2.fill(this., Identity, Identity, Identity,
+                Market>, Market>>apply(
+                new Market<>(Identity::new, Either::right)).fmap(Identity::runIdentity))
+                .biMap(Market::bt, Market::sta);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
     @Override
     default >,
             CoF extends Functor>,
@@ -58,15 +82,62 @@ public interface Prism extends
     }
 
     /**
-     * Recover the two mappings encapsulated by this {@link Prism} by sending it through a {@link Market}.
-     *
-     * @return a {@link Tuple2 tuple} of the two mappings encapsulated by this {@link Prism}
+     * {@inheritDoc}
      */
-    default Tuple2, Fn1>> unPrism() {
-        return Tuple2.fill(this., Identity, Identity, Identity,
-                Market>, Market>>apply(
-                new Market<>(Identity::new, Either::right)).fmap(Identity::runIdentity))
-                .biMap(Market::bt, Market::sta);
+    @Override
+    default  Prism pure(U u) {
+        return prism(constantly(left(u)), constantly(u));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    default  Prism flatMap(Fn1>> f) {
+        return unPrism().into((bt, seta) -> prism(
+                s -> seta.apply(s).match(t -> matching(f.apply(t).>coerce(), s), Either::right),
+                b -> View.view(re(f.apply(bt.apply(b)).coerce())).apply(b)));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    default  Prism fmap(Fn1 fn) {
+        return Monad.super.fmap(fn).coerce();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    default  Prism zip(Applicative, Prism> appFn) {
+        return Monad.super.zip(appFn).coerce();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    default  Lazy> lazyZip(
+            Lazy, Prism>> lazyAppFn) {
+        return Monad.super.lazyZip(lazyAppFn).fmap(Monad>::coerce);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    default  Prism discardL(Applicative> appB) {
+        return Monad.super.discardL(appB).coerce();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    default  Prism discardR(Applicative> appB) {
+        return Monad.super.discardR(appB).coerce();
     }
 
     /**
@@ -85,8 +156,7 @@ static  Prism prism(Fn1 bt) {
         return new Prism() {
             @Override
-            public > Optic, F, S, T, A, B> toOptic(
-                    Pure pure) {
+            public > Optic, F, S, T, A, B> toOptic(Pure pure) {
                 return Optic.,
                         F,
                         S, T, A, B,
@@ -113,8 +183,7 @@ static  Prism prism(Fn1 Prism prism(ProtoOptic, S, T, A, B> protoOptic) {
         return new Prism() {
             @Override
-            public > Optic, F, S, T, A, B> toOptic(
-                    Pure pure) {
+            public > Optic, F, S, T, A, B> toOptic(Pure pure) {
                 Optic, F, S, T, A, B> optic = protoOptic.toOptic(pure);
                 return Optic.reframe(optic);
             }
@@ -138,8 +207,7 @@ static  Prism prism(
             Optic, ? super Functor, S, T, A, B> optic) {
         return new Prism() {
             @Override
-            public > Optic, F, S, T, A, B> toOptic(
-                    Pure pure) {
+            public > Optic, F, S, T, A, B> toOptic(Pure pure) {
                 return Optic.reframe(optic);
             }
         };
@@ -160,6 +228,12 @@ static  Prism.Simple simplePrism(Fn1>
         return Prism.prism(s -> sMaybeA.apply(s).toEither(() -> s), as)::toOptic;
     }
 
+
+    static  Prism.Simple fromPartial(Fn1 partialSa,
+                                                 Fn1 as) {
+        return adapt(prism(partialSa.diMap(downcast(), upcast()).choose(), as));
+    }
+
     /**
      * A convenience type with a simplified type signature for common {@link Prism prism} with unified S/T
      * and A/B types.
diff --git a/src/main/java/com/jnape/palatable/lambda/optics/ProtoOptic.java b/src/main/java/com/jnape/palatable/lambda/optics/ProtoOptic.java
index 1d38ef807..57fc5ffbc 100644
--- a/src/main/java/com/jnape/palatable/lambda/optics/ProtoOptic.java
+++ b/src/main/java/com/jnape/palatable/lambda/optics/ProtoOptic.java
@@ -1,8 +1,10 @@
 package com.jnape.palatable.lambda.optics;
 
 import com.jnape.palatable.lambda.functions.specialized.Pure;
+import com.jnape.palatable.lambda.functor.Applicative;
 import com.jnape.palatable.lambda.functor.Functor;
 import com.jnape.palatable.lambda.functor.Profunctor;
+import com.jnape.palatable.lambda.functor.builtin.Identity;
 
 /**
  * A generic supertype representation for a profunctor {@link Optic} that requires a {@link Pure} implementation to
@@ -14,7 +16,9 @@
  * @param  the left side of the input profunctor
  * @param  the right side's functor embedding of the input profunctor
  */
-public interface ProtoOptic

, S, T, A, B> { +@FunctionalInterface +public interface ProtoOptic

, S, T, A, B> + extends Optic, S, T, A, B> { /** * Given a {@link Pure} lifting function, fix this {@link ProtoOptic} to the given {@link Functor} and promote it to @@ -24,5 +28,13 @@ public interface ProtoOptic

, S, T, A, B> * @param the {@link Functor} bound * @return the {@link Optic} */ - > Optic toOptic(Pure pure); + > Optic toOptic(Pure pure); + + @Override + default , CoF extends Functor>, + FB extends Functor, FT extends Functor, + PAFB extends Profunctor, + PSFT extends Profunctor> PSFT apply(PAFB pafb) { + return toOptic(Pure.>pure(Identity::new)).apply(pafb); + } } diff --git a/src/test/java/com/jnape/palatable/lambda/optics/PrismTest.java b/src/test/java/com/jnape/palatable/lambda/optics/PrismTest.java index 81b74b14e..b2080bb0b 100644 --- a/src/test/java/com/jnape/palatable/lambda/optics/PrismTest.java +++ b/src/test/java/com/jnape/palatable/lambda/optics/PrismTest.java @@ -3,7 +3,14 @@ import com.jnape.palatable.lambda.adt.Either; import com.jnape.palatable.lambda.adt.coproduct.CoProduct2; import com.jnape.palatable.lambda.functions.Fn1; +import com.jnape.palatable.traitor.annotations.TestTraits; +import com.jnape.palatable.traitor.runners.Traits; import org.junit.Test; +import org.junit.runner.RunWith; +import testsupport.EquatableM; +import testsupport.traits.ApplicativeLaws; +import testsupport.traits.FunctorLaws; +import testsupport.traits.MonadLaws; import static com.jnape.palatable.lambda.adt.Either.left; import static com.jnape.palatable.lambda.adt.Either.right; @@ -16,10 +23,17 @@ import static com.jnape.palatable.lambda.optics.functions.View.view; import static org.junit.Assert.assertEquals; +@RunWith(Traits.class) public class PrismTest { private static final Fn1 PARSE_INT = Fn1.fn1(Integer::parseInt); + @TestTraits({FunctorLaws.class, ApplicativeLaws.class, MonadLaws.class}) + public EquatableM, String> testSubject() { + return new EquatableM<>(Prism.fromPartial(Integer::parseInt, Object::toString), + prism -> matching(prism, "foo")); + } + @Test public void prismLaws() { Prism prism = prism(PARSE_INT.choose(), Object::toString); From a1ba4b7c9015ba14c1dfa70ecc9c7cbb7a56efd8 Mon Sep 17 00:00:00 2001 From: jnape Date: Sun, 19 May 2019 18:36:40 -0500 Subject: [PATCH 59/69] EitherLens#left/right prefixed with underscore to avoid future ambiguity --- .../jnape/palatable/lambda/optics/lenses/EitherLens.java | 6 +++--- .../palatable/lambda/optics/lenses/EitherLensTest.java | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/jnape/palatable/lambda/optics/lenses/EitherLens.java b/src/main/java/com/jnape/palatable/lambda/optics/lenses/EitherLens.java index 0aa4b86a3..8463d0eb1 100644 --- a/src/main/java/com/jnape/palatable/lambda/optics/lenses/EitherLens.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/lenses/EitherLens.java @@ -8,7 +8,7 @@ import static com.jnape.palatable.lambda.optics.Lens.simpleLens; /** - * Lenses that operate on {@link Either}s. + * Lenses for {@link Either}. */ public final class EitherLens { @@ -26,7 +26,7 @@ private EitherLens() { * @param the right parameter type * @return a lens that focuses on right values */ - public static Lens.Simple, Maybe> right() { + public static Lens.Simple, Maybe> _right() { return simpleLens(CoProduct2::projectB, (lOrR, maybeR) -> maybeR.>fmap(Either::right).orElse(lOrR)); } @@ -41,7 +41,7 @@ public static Lens.Simple, Maybe> right() { * @param the right parameter type * @return a lens that focuses on left values */ - public static Lens.Simple, Maybe> left() { + public static Lens.Simple, Maybe> _left() { return simpleLens(CoProduct2::projectA, (lOrR, maybeL) -> maybeL.>fmap(Either::left).orElse(lOrR)); } } diff --git a/src/test/java/com/jnape/palatable/lambda/optics/lenses/EitherLensTest.java b/src/test/java/com/jnape/palatable/lambda/optics/lenses/EitherLensTest.java index 1d300f389..ef9aee18d 100644 --- a/src/test/java/com/jnape/palatable/lambda/optics/lenses/EitherLensTest.java +++ b/src/test/java/com/jnape/palatable/lambda/optics/lenses/EitherLensTest.java @@ -17,7 +17,7 @@ public class EitherLensTest { @Test public void rightFocusesOnRightValues() { - Lens.Simple, Maybe> right = EitherLens.right(); + Lens.Simple, Maybe> right = EitherLens._right(); assertEquals(just(1), view(right, right(1))); assertEquals(nothing(), view(right, left("fail"))); @@ -29,7 +29,7 @@ public void rightFocusesOnRightValues() { @Test public void leftFocusesOnLeftValues() { - Lens.Simple, Maybe> left = EitherLens.left(); + Lens.Simple, Maybe> left = EitherLens._left(); assertEquals(just("fail"), view(left, left("fail"))); assertEquals(nothing(), view(left, right(1))); From 733b41d7fcc78841b5e7084f6e543b081c5f91ee Mon Sep 17 00:00:00 2001 From: jnape Date: Sun, 19 May 2019 18:36:52 -0500 Subject: [PATCH 60/69] Cleaning up Optic javadoc --- src/main/java/com/jnape/palatable/lambda/optics/Optic.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/jnape/palatable/lambda/optics/Optic.java b/src/main/java/com/jnape/palatable/lambda/optics/Optic.java index be518ad7a..fb6ec0e59 100644 --- a/src/main/java/com/jnape/palatable/lambda/optics/Optic.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/Optic.java @@ -10,8 +10,7 @@ * Precisely stated, for some {@link Profunctor} P and some {@link Functor} F, and for the * types S T A B, an * {@link Optic}<P, F, S, T, A, B> is a polymorphic function - * (P<A, F<B>> -> P<S, F<T>>) (existentially-quantified allowing for - * covariance). + * P<A, F<B>> -> P<S, F<T>>. * * @param

the {@link Profunctor} bound * @param the {@link Functor} bound From 1820d9e8631d749ab7fe2cacad1ed3b3874c381d Mon Sep 17 00:00:00 2001 From: jnape Date: Sun, 19 May 2019 18:37:29 -0500 Subject: [PATCH 61/69] Cleaning up MapLens javadoc; SetLens#intersection removed (not lawful) --- .../lambda/optics/lenses/MapLens.java | 4 +- .../lambda/optics/lenses/SetLens.java | 40 ------------------- 2 files changed, 2 insertions(+), 42 deletions(-) diff --git a/src/main/java/com/jnape/palatable/lambda/optics/lenses/MapLens.java b/src/main/java/com/jnape/palatable/lambda/optics/lenses/MapLens.java index 7016716e7..729ca0b23 100644 --- a/src/main/java/com/jnape/palatable/lambda/optics/lenses/MapLens.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/lenses/MapLens.java @@ -68,11 +68,11 @@ public static Lens.Simple, Map> asCopy() { * A lens that focuses on a value at a key in a map, as a {@link Maybe}, and produces a subtype M on * the way back out. * + * @param copyFn the copy function + * @param k the key to focus on * @param the map subtype * @param the key type * @param the value type - * @param k the key to focus on - * @param copyFn the copy function * @return a lens that focuses on the value at key, as a {@link Maybe} */ public static , K, V> Lens, M, Maybe, Maybe> valueAt( diff --git a/src/main/java/com/jnape/palatable/lambda/optics/lenses/SetLens.java b/src/main/java/com/jnape/palatable/lambda/optics/lenses/SetLens.java index 6b66649ed..75c7ab756 100644 --- a/src/main/java/com/jnape/palatable/lambda/optics/lenses/SetLens.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/lenses/SetLens.java @@ -3,7 +3,6 @@ import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.optics.Lens; -import java.util.Collection; import java.util.HashSet; import java.util.Set; @@ -17,45 +16,6 @@ public final class SetLens { private SetLens() { } - /** - * A lens that focuses on whether a {@link Set} contains all values in as. Note that - * copyFn is used to avoid mutating the {@link Set} in question. - * - * @param copyFn the copy function - * @param as the values in question - * @param the value type - * @param the set to focus on - * @return a lens that focuses on the inclusion of a {@link Collection} of values in a given {@link Set} - */ - public static > Lens.Simple intersection( - Fn1 copyFn, - Set as) { - return simpleLens(setA -> { - SetA intersection = copyFn.apply(setA); - intersection.retainAll(as); - return intersection; - }, - (setA, setB) -> { - SetA copy = copyFn.apply(setA); - copy.retainAll(setB); - copy.retainAll(as); - return copy; - }); - } - - /** - * A lens that focuses on whether a {@link Set} contains some value a. Like - * {@link #intersection(Fn1, Set)} )} but with an implicit copy function that produces - * {@link HashSet}s. - * - * @param as the values in question - * @param the value type - * @return a lens that focuses on the inclusion of a {@link Collection} of values in a given {@link Set} - */ - public static Lens.Simple, Set> intersection(Set as) { - return intersection(HashSet::new, as); - } - /** * A lens that focuses on whether a {@link Set} contains some value a. Note that copyFn is * used to avoid mutating the {@link Set} in question. From 24a12ecb225477f7d9cdf19f624865acb0682400 Mon Sep 17 00:00:00 2001 From: jnape Date: Sun, 19 May 2019 18:37:52 -0500 Subject: [PATCH 62/69] Adding default prisms for Either, Maybe, Maps, and UUIDs --- .../lambda/optics/prisms/EitherPrism.java | 38 ++++++++ .../lambda/optics/prisms/MapPrism.java | 49 +++++++++++ .../lambda/optics/prisms/MaybePrism.java | 41 +++++++++ .../lambda/optics/prisms/UUIDPrism.java | 22 +++++ .../lambda/optics/prisms/EitherPrismTest.java | 26 ++++++ .../lambda/optics/prisms/MapPrismTest.java | 33 +++++++ .../lambda/optics/prisms/MaybePrismTest.java | 27 ++++++ .../lambda/optics/prisms/UUIDPrismTest.java | 20 +++++ .../testsupport/assertion/PrismAssert.java | 86 +++++++++++++++++++ 9 files changed, 342 insertions(+) create mode 100644 src/main/java/com/jnape/palatable/lambda/optics/prisms/EitherPrism.java create mode 100644 src/main/java/com/jnape/palatable/lambda/optics/prisms/MapPrism.java create mode 100644 src/main/java/com/jnape/palatable/lambda/optics/prisms/MaybePrism.java create mode 100644 src/main/java/com/jnape/palatable/lambda/optics/prisms/UUIDPrism.java create mode 100644 src/test/java/com/jnape/palatable/lambda/optics/prisms/EitherPrismTest.java create mode 100644 src/test/java/com/jnape/palatable/lambda/optics/prisms/MapPrismTest.java create mode 100644 src/test/java/com/jnape/palatable/lambda/optics/prisms/MaybePrismTest.java create mode 100644 src/test/java/com/jnape/palatable/lambda/optics/prisms/UUIDPrismTest.java create mode 100644 src/test/java/testsupport/assertion/PrismAssert.java diff --git a/src/main/java/com/jnape/palatable/lambda/optics/prisms/EitherPrism.java b/src/main/java/com/jnape/palatable/lambda/optics/prisms/EitherPrism.java new file mode 100644 index 000000000..462f30b0a --- /dev/null +++ b/src/main/java/com/jnape/palatable/lambda/optics/prisms/EitherPrism.java @@ -0,0 +1,38 @@ +package com.jnape.palatable.lambda.optics.prisms; + +import com.jnape.palatable.lambda.adt.Either; +import com.jnape.palatable.lambda.adt.coproduct.CoProduct2; +import com.jnape.palatable.lambda.optics.Prism; + +import static com.jnape.palatable.lambda.optics.Prism.simplePrism; + +/** + * {@link Prism Prisms} for {@link Either}. + */ +public final class EitherPrism { + + private EitherPrism() { + } + + /** + * A {@link Prism} that focuses on the {@link Either#left(Object) left} value of an {@link Either}. + * + * @param the left type + * @param the right type + * @return the {@link Prism} + */ + public static Prism.Simple, L> _left() { + return simplePrism(CoProduct2::projectA, Either::left); + } + + /** + * A {@link Prism} that focuses on the {@link Either#right(Object) right} value of an {@link Either}. + * + * @param the left type + * @param the right type + * @return the {@link Prism} + */ + public static Prism.Simple, R> _right() { + return simplePrism(CoProduct2::projectB, Either::right); + } +} diff --git a/src/main/java/com/jnape/palatable/lambda/optics/prisms/MapPrism.java b/src/main/java/com/jnape/palatable/lambda/optics/prisms/MapPrism.java new file mode 100644 index 000000000..2d1ee7930 --- /dev/null +++ b/src/main/java/com/jnape/palatable/lambda/optics/prisms/MapPrism.java @@ -0,0 +1,49 @@ +package com.jnape.palatable.lambda.optics.prisms; + +import com.jnape.palatable.lambda.functions.Fn1; +import com.jnape.palatable.lambda.optics.Prism; + +import java.util.HashMap; +import java.util.Map; + +import static com.jnape.palatable.lambda.adt.Maybe.maybe; +import static com.jnape.palatable.lambda.optics.Prism.Simple.adapt; +import static com.jnape.palatable.lambda.optics.Prism.prism; +import static java.util.Collections.singletonMap; + +/** + * {@link Prism Prisms} for {@link Map Maps}. + */ +public final class MapPrism { + private MapPrism() { + } + + /** + * A {@link Prism} that focuses on the value at a key in a {@link Map}, and produces an instance of M + * on the way back out. + * + * @param copyFn the copy function + * @param k the key to focus on + * @param the {@link Map} subtype + * @param the key type + * @param the value type + * @return the {@link Prism} + */ + public static , K, V> Prism, M, V, V> valueAt(Fn1, M> copyFn, K k) { + return prism(m -> maybe(m.get(k)).toEither(copyFn.thunk(m)), + v -> copyFn.apply(singletonMap(k, v))); + } + + /** + * A {@link Prism} that focuses on the value at a key in a {@link Map} making no guarantees about the {@link Map} + * interface. + * + * @param k the key to focus on + * @param the key type + * @param the value type + * @return the {@link Prism} + */ + public static Prism.Simple, V> valueAt(K k) { + return adapt(valueAt(HashMap::new, k)); + } +} diff --git a/src/main/java/com/jnape/palatable/lambda/optics/prisms/MaybePrism.java b/src/main/java/com/jnape/palatable/lambda/optics/prisms/MaybePrism.java new file mode 100644 index 000000000..eaf5ed0f1 --- /dev/null +++ b/src/main/java/com/jnape/palatable/lambda/optics/prisms/MaybePrism.java @@ -0,0 +1,41 @@ +package com.jnape.palatable.lambda.optics.prisms; + +import com.jnape.palatable.lambda.adt.Maybe; +import com.jnape.palatable.lambda.adt.Unit; +import com.jnape.palatable.lambda.adt.coproduct.CoProduct2; +import com.jnape.palatable.lambda.optics.Prism; + +import static com.jnape.palatable.lambda.adt.Maybe.nothing; +import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; +import static com.jnape.palatable.lambda.optics.Prism.prism; +import static com.jnape.palatable.lambda.optics.Prism.simplePrism; + +/** + * {@link Prism Prisms} for {@link Maybe}. + */ +public final class MaybePrism { + + private MaybePrism() { + } + + /** + * A {@link Prism} that focuses on present values in a {@link Maybe}. + * + * @param {@link Maybe} the input value + * @param {@link Maybe} the output value + * @return the {@link Prism} + */ + public static Prism, Maybe, A, B> _just() { + return prism(maybeA -> maybeA.toEither(Maybe::nothing), Maybe::just); + } + + /** + * A {@link Prism} that focuses on absent values in a {@link Maybe}, for symmetry. + * + * @param {@link Maybe} the input and output value + * @return the {@link Prism} + */ + public static Prism.Simple, Unit> _nothing() { + return simplePrism(CoProduct2::projectA, constantly(nothing())); + } +} diff --git a/src/main/java/com/jnape/palatable/lambda/optics/prisms/UUIDPrism.java b/src/main/java/com/jnape/palatable/lambda/optics/prisms/UUIDPrism.java new file mode 100644 index 000000000..c9a70080e --- /dev/null +++ b/src/main/java/com/jnape/palatable/lambda/optics/prisms/UUIDPrism.java @@ -0,0 +1,22 @@ +package com.jnape.palatable.lambda.optics.prisms; + +import com.jnape.palatable.lambda.optics.Prism; + +import java.util.UUID; + +/** + * {@link Prism Prisms} for {@link UUID}. + */ +public final class UUIDPrism { + private UUIDPrism() { + } + + /** + * A {@link Prism} that focuses on a {@link String} as a {@link UUID}. + * + * @return the {@link Prism} + */ + public static Prism.Simple uuid() { + return Prism.fromPartial(UUID::fromString, UUID::toString); + } +} diff --git a/src/test/java/com/jnape/palatable/lambda/optics/prisms/EitherPrismTest.java b/src/test/java/com/jnape/palatable/lambda/optics/prisms/EitherPrismTest.java new file mode 100644 index 000000000..cb1e09357 --- /dev/null +++ b/src/test/java/com/jnape/palatable/lambda/optics/prisms/EitherPrismTest.java @@ -0,0 +1,26 @@ +package com.jnape.palatable.lambda.optics.prisms; + +import org.junit.Test; + +import static com.jnape.palatable.lambda.adt.Either.left; +import static com.jnape.palatable.lambda.adt.Either.right; +import static java.util.Arrays.asList; +import static java.util.Collections.singleton; +import static testsupport.assertion.PrismAssert.assertPrismLawfulness; + +public class EitherPrismTest { + + @Test + public void _right() { + assertPrismLawfulness(EitherPrism._right(), + asList(left("foo"), right(1)), + singleton(1)); + } + + @Test + public void _left() { + assertPrismLawfulness(EitherPrism._left(), + asList(left("foo"), right(1)), + singleton("foo")); + } +} \ No newline at end of file diff --git a/src/test/java/com/jnape/palatable/lambda/optics/prisms/MapPrismTest.java b/src/test/java/com/jnape/palatable/lambda/optics/prisms/MapPrismTest.java new file mode 100644 index 000000000..7ba1dd09f --- /dev/null +++ b/src/test/java/com/jnape/palatable/lambda/optics/prisms/MapPrismTest.java @@ -0,0 +1,33 @@ +package com.jnape.palatable.lambda.optics.prisms; + +import org.junit.Test; + +import java.util.HashMap; +import java.util.LinkedHashMap; + +import static java.util.Arrays.asList; +import static java.util.Collections.singleton; +import static java.util.Collections.singletonMap; +import static testsupport.assertion.PrismAssert.assertPrismLawfulness; + +public class MapPrismTest { + + @Test + public void valueAtWithConstructor() { + assertPrismLawfulness(MapPrism.valueAt(LinkedHashMap::new, "foo"), + asList(new LinkedHashMap<>(), + new LinkedHashMap<>(singletonMap("foo", 1)), + new LinkedHashMap<>(singletonMap("bar", 2))), + singleton(1)); + } + + @Test + public void valueAtWithoutConstructor() { + assertPrismLawfulness(MapPrism.valueAt("foo"), + asList(new HashMap<>(), + new HashMap<>(singletonMap("foo", 1)), + new HashMap<>(singletonMap("bar", 2))), + singleton(1)); + } + +} \ No newline at end of file diff --git a/src/test/java/com/jnape/palatable/lambda/optics/prisms/MaybePrismTest.java b/src/test/java/com/jnape/palatable/lambda/optics/prisms/MaybePrismTest.java new file mode 100644 index 000000000..5d772a6c5 --- /dev/null +++ b/src/test/java/com/jnape/palatable/lambda/optics/prisms/MaybePrismTest.java @@ -0,0 +1,27 @@ +package com.jnape.palatable.lambda.optics.prisms; + +import org.junit.Test; + +import static com.jnape.palatable.lambda.adt.Maybe.just; +import static com.jnape.palatable.lambda.adt.Maybe.nothing; +import static com.jnape.palatable.lambda.adt.Unit.UNIT; +import static java.util.Arrays.asList; +import static java.util.Collections.singleton; +import static testsupport.assertion.PrismAssert.assertPrismLawfulness; + +public class MaybePrismTest { + + @Test + public void _just() { + assertPrismLawfulness(MaybePrism._just(), + asList(just(1), nothing()), + singleton(1)); + } + + @Test + public void _nothing() { + assertPrismLawfulness(MaybePrism._nothing(), + asList(just(1), nothing()), + singleton(UNIT)); + } +} \ No newline at end of file diff --git a/src/test/java/com/jnape/palatable/lambda/optics/prisms/UUIDPrismTest.java b/src/test/java/com/jnape/palatable/lambda/optics/prisms/UUIDPrismTest.java new file mode 100644 index 000000000..24bf6421a --- /dev/null +++ b/src/test/java/com/jnape/palatable/lambda/optics/prisms/UUIDPrismTest.java @@ -0,0 +1,20 @@ +package com.jnape.palatable.lambda.optics.prisms; + +import org.junit.Test; + +import java.util.UUID; + +import static java.util.Arrays.asList; +import static java.util.Collections.singleton; +import static testsupport.assertion.PrismAssert.assertPrismLawfulness; + +public class UUIDPrismTest { + + @Test + public void uuid() { + UUID uuid = UUID.randomUUID(); + assertPrismLawfulness(UUIDPrism.uuid(), + asList("", "123", uuid.toString()), + singleton(uuid)); + } +} \ No newline at end of file diff --git a/src/test/java/testsupport/assertion/PrismAssert.java b/src/test/java/testsupport/assertion/PrismAssert.java new file mode 100644 index 000000000..9794678de --- /dev/null +++ b/src/test/java/testsupport/assertion/PrismAssert.java @@ -0,0 +1,86 @@ +package testsupport.assertion; + +import com.jnape.palatable.lambda.adt.Maybe; +import com.jnape.palatable.lambda.adt.hlist.Tuple2; +import com.jnape.palatable.lambda.functions.Fn2; +import com.jnape.palatable.lambda.functions.builtin.fn2.Map; +import com.jnape.palatable.lambda.io.IO; +import com.jnape.palatable.lambda.monoid.builtin.Present; +import com.jnape.palatable.lambda.optics.Prism; + +import java.util.Objects; + +import static com.jnape.palatable.lambda.adt.Either.left; +import static com.jnape.palatable.lambda.adt.Maybe.just; +import static com.jnape.palatable.lambda.adt.Maybe.nothing; +import static com.jnape.palatable.lambda.functions.Fn2.fn2; +import static com.jnape.palatable.lambda.functions.builtin.fn1.CatMaybes.catMaybes; +import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; +import static com.jnape.palatable.lambda.functions.builtin.fn2.CartesianProduct.cartesianProduct; +import static com.jnape.palatable.lambda.functions.builtin.fn2.Into.into; +import static com.jnape.palatable.lambda.functions.builtin.fn2.ReduceLeft.reduceLeft; +import static com.jnape.palatable.lambda.optics.functions.Matching.matching; +import static com.jnape.palatable.lambda.optics.functions.Pre.pre; +import static com.jnape.palatable.lambda.optics.functions.Re.re; +import static com.jnape.palatable.lambda.optics.functions.View.view; +import static java.lang.String.format; +import static java.lang.String.join; +import static java.util.Arrays.asList; + +public final class PrismAssert { + + public static void assertPrismLawfulness(Prism prism, + Iterable ss, + Iterable bs) { + Iterable> cases = cartesianProduct(ss, bs); + Present.present((x, y) -> join("\n\n", x, y)) + .reduceLeft(asList(falsify("The result of a review can always be successfully previewed:", + (s, b) -> view(pre(prism), view(re(prism), b)), (s, b) -> just(b), cases), + falsify("If I can preview a value from an input, I can review the input to the value", + (s, b) -> new PrismResult<>(view(pre(prism), s).fmap(constantly(s))), + (s, b) -> new PrismResult<>(just(view(re(prism), b))), cases), + falsify("A non-match result can always be converted back to an input", + (s, b) -> new PrismResult<>(matching(prism, s).projectA().fmap(matching(prism))), + (s, b) -> new PrismResult<>(just(left(s))), cases))) + .peek(failures -> IO.throwing(new AssertionError("Lens law failures\n\n" + failures))); + } + + private static Maybe falsify(String label, Fn2 l, Fn2 r, + Iterable> cases) { + return Map., Maybe>map(into((s, b) -> { + X x = l.apply(s, b); + X y = r.apply(s, b); + return Objects.equals(x, y) ? nothing() : just(format("S <%s>, B <%s> (%s != %s)", s, b, x, y)); + })) + .fmap(catMaybes()) + .fmap(reduceLeft((x, y) -> x + "\n\t - " + y)) + .fmap(maybeFailures -> maybeFailures.fmap(failures -> "\"" + label + "\" failed for the following cases:\n\n\t - " + failures)) + .apply(cases); + } + + private static final class PrismResult { + private final Maybe maybeS; + + private PrismResult(Maybe maybeS) { + this.maybeS = maybeS; + } + + @Override + public boolean equals(Object other) { + if (other instanceof PrismResult) { + return maybeS.zip(((PrismResult) other).maybeS.fmap(fn2(Objects::equals))).orElse(true); + } + return false; + } + + @Override + public int hashCode() { + return Objects.hash(maybeS); + } + + @Override + public String toString() { + return maybeS.toString(); + } + } +} From 3259969772c5751de5f305b7a19649677e8c6892 Mon Sep 17 00:00:00 2001 From: jnape Date: Sun, 19 May 2019 18:41:54 -0500 Subject: [PATCH 63/69] Intersection is a Semigroup --- .../builtin/fn2 => semigroup/builtin}/Intersection.java | 6 +++--- .../com/jnape/palatable/lambda/traversable/Traversable.java | 3 +++ .../builtin/fn2 => semigroup/builtin}/IntersectionTest.java | 4 ++-- 3 files changed, 8 insertions(+), 5 deletions(-) rename src/main/java/com/jnape/palatable/lambda/{functions/builtin/fn2 => semigroup/builtin}/Intersection.java (88%) rename src/test/java/com/jnape/palatable/lambda/{functions/builtin/fn2 => semigroup/builtin}/IntersectionTest.java (92%) diff --git a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Intersection.java b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Intersection.java similarity index 88% rename from src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Intersection.java rename to src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Intersection.java index e7965d9ae..cf33e9b3a 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/Intersection.java +++ b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Intersection.java @@ -1,8 +1,8 @@ -package com.jnape.palatable.lambda.functions.builtin.fn2; +package com.jnape.palatable.lambda.semigroup.builtin; import com.jnape.palatable.lambda.functions.Fn1; -import com.jnape.palatable.lambda.functions.Fn2; import com.jnape.palatable.lambda.functions.builtin.fn1.Distinct; +import com.jnape.palatable.lambda.semigroup.Semigroup; import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; import static com.jnape.palatable.lambda.functions.builtin.fn1.Distinct.distinct; @@ -16,7 +16,7 @@ * * @param the {@link Iterable} element type */ -public final class Intersection implements Fn2, Iterable, Iterable> { +public final class Intersection implements Semigroup> { private static final Intersection INSTANCE = new Intersection<>(); diff --git a/src/main/java/com/jnape/palatable/lambda/traversable/Traversable.java b/src/main/java/com/jnape/palatable/lambda/traversable/Traversable.java index d9f24621c..54caa1317 100644 --- a/src/main/java/com/jnape/palatable/lambda/traversable/Traversable.java +++ b/src/main/java/com/jnape/palatable/lambda/traversable/Traversable.java @@ -47,6 +47,9 @@ public interface Traversable> extends Functor> AppTrav traverse( Fn1> fn, Fn1 pure); + /** + * {@inheritDoc} + */ @Override default Traversable fmap(Fn1 fn) { return traverse(a -> new Identity(fn.apply(a)), Identity::new).runIdentity(); diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/IntersectionTest.java b/src/test/java/com/jnape/palatable/lambda/semigroup/builtin/IntersectionTest.java similarity index 92% rename from src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/IntersectionTest.java rename to src/test/java/com/jnape/palatable/lambda/semigroup/builtin/IntersectionTest.java index 13c16ace3..0ecd33c71 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/IntersectionTest.java +++ b/src/test/java/com/jnape/palatable/lambda/semigroup/builtin/IntersectionTest.java @@ -1,4 +1,4 @@ -package com.jnape.palatable.lambda.functions.builtin.fn2; +package com.jnape.palatable.lambda.semigroup.builtin; import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.traitor.annotations.TestTraits; @@ -10,7 +10,7 @@ import testsupport.traits.InfiniteIterableSupport; import testsupport.traits.Laziness; -import static com.jnape.palatable.lambda.functions.builtin.fn2.Intersection.intersection; +import static com.jnape.palatable.lambda.semigroup.builtin.Intersection.intersection; import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; From 9ae0f1451b93e68aa9e34de584893358f7f33594 Mon Sep 17 00:00:00 2001 From: jnape Date: Sun, 19 May 2019 18:47:09 -0500 Subject: [PATCH 64/69] Adding the Trivial Unit monoid for when composition demands it --- .../lambda/monoid/builtin/Trivial.java | 41 +++++++++++++++++++ .../lambda/monoid/builtin/TrivialTest.java | 16 ++++++++ 2 files changed, 57 insertions(+) create mode 100644 src/main/java/com/jnape/palatable/lambda/monoid/builtin/Trivial.java create mode 100644 src/test/java/com/jnape/palatable/lambda/monoid/builtin/TrivialTest.java diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Trivial.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Trivial.java new file mode 100644 index 000000000..bf77b65f1 --- /dev/null +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Trivial.java @@ -0,0 +1,41 @@ +package com.jnape.palatable.lambda.monoid.builtin; + +import com.jnape.palatable.lambda.adt.Unit; +import com.jnape.palatable.lambda.functions.Fn1; +import com.jnape.palatable.lambda.functions.builtin.fn1.Constantly; +import com.jnape.palatable.lambda.monoid.Monoid; + +import static com.jnape.palatable.lambda.adt.Unit.UNIT; + +/** + * The trivial {@link Unit} {@link Monoid} formed under {@link Constantly constantly}. + */ +public final class Trivial implements Monoid { + + private static final Trivial INSTANCE = new Trivial(); + + private Trivial() { + } + + @Override + public Unit identity() { + return UNIT; + } + + @Override + public Unit checkedApply(Unit x, Unit y) throws Throwable { + return y; + } + + public static Trivial trivial() { + return INSTANCE; + } + + public static Fn1 trivial(Unit x) { + return trivial().apply(x); + } + + public static Unit trivial(Unit x, Unit y) { + return trivial(x).apply(y); + } +} diff --git a/src/test/java/com/jnape/palatable/lambda/monoid/builtin/TrivialTest.java b/src/test/java/com/jnape/palatable/lambda/monoid/builtin/TrivialTest.java new file mode 100644 index 000000000..da28c59f6 --- /dev/null +++ b/src/test/java/com/jnape/palatable/lambda/monoid/builtin/TrivialTest.java @@ -0,0 +1,16 @@ +package com.jnape.palatable.lambda.monoid.builtin; + +import org.junit.Test; + +import static com.jnape.palatable.lambda.adt.Unit.UNIT; +import static com.jnape.palatable.lambda.monoid.builtin.Trivial.trivial; +import static org.junit.Assert.assertEquals; + +public class TrivialTest { + + @Test + public void triviality() { + assertEquals(UNIT, trivial().identity()); + assertEquals(UNIT, trivial().apply(UNIT, UNIT)); + } +} \ No newline at end of file From a14042c08ca7b15ac1544d05bf369660074c789f Mon Sep 17 00:00:00 2001 From: jnape Date: Sun, 19 May 2019 18:52:21 -0500 Subject: [PATCH 65/69] Fixing javadocs --- src/main/java/com/jnape/palatable/lambda/adt/Try.java | 1 + src/main/java/com/jnape/palatable/lambda/functions/Effect.java | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/main/java/com/jnape/palatable/lambda/adt/Try.java b/src/main/java/com/jnape/palatable/lambda/adt/Try.java index 40a678339..bdc2ec040 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/Try.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/Try.java @@ -122,6 +122,7 @@ public final A orThrow() throws T { * If this is a success value, return it. Otherwise, transform the captured failure with fn and throw * the result. * + * @param fn the {@link Throwable} transformation * @param the type of the thrown {@link Throwable} * @return possibly the success value * @throws T the transformation output diff --git a/src/main/java/com/jnape/palatable/lambda/functions/Effect.java b/src/main/java/com/jnape/palatable/lambda/functions/Effect.java index 077935f49..648c42eab 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Effect.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Effect.java @@ -95,6 +95,7 @@ static Effect fromConsumer(Consumer consumer) { * Create an {@link Effect} from a {@link SideEffect}; * * @param sideEffect the {@link SideEffect} + * @param any desired input type * @return the {@link Effect} */ static Effect effect(SideEffect sideEffect) { @@ -104,6 +105,7 @@ static Effect effect(SideEffect sideEffect) { /** * Create an {@link Effect} that accepts an input and does nothing; * + * @param any desired input type * @return the noop {@link Effect} */ @SuppressWarnings("unused") From bc366576d65c81827a9b17a0cbc187a3b02abc7a Mon Sep 17 00:00:00 2001 From: jnape Date: Sun, 19 May 2019 18:59:40 -0500 Subject: [PATCH 66/69] CompletableFuture#thenCompose isn't stack-safe, so c-switch zips for now --- src/main/java/com/jnape/palatable/lambda/io/IO.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/jnape/palatable/lambda/io/IO.java b/src/main/java/com/jnape/palatable/lambda/io/IO.java index a42181bd2..c86fcbc59 100644 --- a/src/main/java/com/jnape/palatable/lambda/io/IO.java +++ b/src/main/java/com/jnape/palatable/lambda/io/IO.java @@ -312,10 +312,10 @@ public CompletableFuture unsafePerformAsyncIO(Executor executor) { @SuppressWarnings("unchecked") CompletableFuture future = (CompletableFuture) deforest(new LinkedList<>()) .into((source, compositions) -> foldLeft( - (io, composition) -> composition + (ioFuture, composition) -> composition .match(zip -> zip.unsafePerformAsyncIO(executor) - .thenCompose(f -> io.thenApply(f.toFunction())), - flatMap -> io.thenComposeAsync(obj -> flatMap.apply(obj) + .thenComposeAsync(f -> ioFuture.thenApply(f.toFunction()), executor), + flatMap -> ioFuture.thenComposeAsync(obj -> flatMap.apply(obj) .unsafePerformAsyncIO(executor), executor)), source.unsafePerformAsyncIO(executor), compositions)); From 03eca049ece575991f43ba12d6befc17f19b2447 Mon Sep 17 00:00:00 2001 From: jnape Date: Sun, 19 May 2019 19:19:09 -0500 Subject: [PATCH 67/69] Bumping version to 4.0.0-SNAPSHOT; removing apache-commons test dep --- pom.xml | 12 +++--------- .../java/testsupport/matchers/IterableMatcher.java | 4 ++-- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/pom.xml b/pom.xml index 00b717374..a913949f3 100644 --- a/pom.xml +++ b/pom.xml @@ -1,5 +1,6 @@ - + 4.0.0 @@ -9,7 +10,7 @@ lambda - 3.3.1-SNAPSHOT + 4.0.0-SNAPSHOT jar Lambda @@ -53,7 +54,6 @@ - 3.1 1.2 3.3 1.3 @@ -81,12 +81,6 @@ ${traitor.version} test - - org.apache.commons - commons-lang3 - ${commons-lang3.version} - test - diff --git a/src/test/java/testsupport/matchers/IterableMatcher.java b/src/test/java/testsupport/matchers/IterableMatcher.java index 5478e46e3..f5f196aba 100644 --- a/src/test/java/testsupport/matchers/IterableMatcher.java +++ b/src/test/java/testsupport/matchers/IterableMatcher.java @@ -5,9 +5,9 @@ import java.util.ArrayList; import java.util.Iterator; +import java.util.Objects; import static java.util.Arrays.asList; -import static org.apache.commons.lang3.builder.EqualsBuilder.reflectionEquals; public class IterableMatcher extends BaseMatcher> { @@ -48,7 +48,7 @@ private boolean iterablesIterateSameElementsInOrder(Iterable expected, Iterab if (nextExpected instanceof Iterable && nextActual instanceof Iterable) { if (!iterablesIterateSameElementsInOrder((Iterable) nextExpected, (Iterable) nextActual)) return false; - } else if (!reflectionEquals(nextExpected, nextActual)) + } else if (!Objects.equals(nextExpected, nextActual)) return false; } From bde58127064cb8c2b96c74304fd72ab6bb736e5b Mon Sep 17 00:00:00 2001 From: jnape Date: Mon, 20 May 2019 23:36:49 -0500 Subject: [PATCH 68/69] Prisms are Profunctors --- .../jnape/palatable/lambda/optics/Prism.java | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/jnape/palatable/lambda/optics/Prism.java b/src/main/java/com/jnape/palatable/lambda/optics/Prism.java index f90635c63..d89ad3bfb 100644 --- a/src/main/java/com/jnape/palatable/lambda/optics/Prism.java +++ b/src/main/java/com/jnape/palatable/lambda/optics/Prism.java @@ -53,7 +53,10 @@ * @param the input that guarantees its output */ @FunctionalInterface -public interface Prism extends ProtoOptic, S, T, A, B>, Monad> { +public interface Prism extends + ProtoOptic, S, T, A, B>, + Monad>, + Profunctor> { /** * Recover the two mappings encapsulated by this {@link Prism} by sending it through a {@link Market}. @@ -140,6 +143,39 @@ default Prism discardR(Applicative> appB) { return Monad.super.discardR(appB).coerce(); } + /** + * {@inheritDoc} + */ + @Override + default Prism diMap(Fn1 lFn, + Fn1 rFn) { + return unPrism().into((bt, seta) -> prism(seta.diMap(lFn, tOrA -> tOrA.biMapL(rFn)), bt.fmap(rFn))); + } + + /** + * {@inheritDoc} + */ + @Override + default Prism diMapL(Fn1 fn) { + return (Prism) Profunctor.super.diMapL(fn); + } + + /** + * {@inheritDoc} + */ + @Override + default Prism diMapR(Fn1 fn) { + return (Prism) Profunctor.super.diMapR(fn); + } + + /** + * {@inheritDoc} + */ + @Override + default Prism contraMap(Fn1 fn) { + return (Prism) Profunctor.super.contraMap(fn); + } + /** * Static factory method for creating a {@link Prism} given a mapping from * S -> {@link Either}<T, A> and a mapping from B -> T. From 2feae8164ec31f784af55121e5ff15beb18af1b2 Mon Sep 17 00:00:00 2001 From: jnape Date: Mon, 20 May 2019 23:45:32 -0500 Subject: [PATCH 69/69] [maven-release-plugin] prepare release lambda-4.0.0 --- pom.xml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index a913949f3..ddf6ce35a 100644 --- a/pom.xml +++ b/pom.xml @@ -1,6 +1,5 @@ - + 4.0.0 @@ -10,7 +9,7 @@ lambda - 4.0.0-SNAPSHOT + 4.0.0 jar Lambda

, F extends Functor, FB extends Functor, FT extends Functor, PAFB extends Profunctor, @@ -110,23 +110,27 @@ default Iso pure(U u) { } @Override - default Iso zip(Applicative, LensLike> appFn) { + default Iso zip( + Applicative, LensLike>> appFn) { return LensLike.super.zip(appFn).coerce(); } @Override - default Iso discardL(Applicative> appB) { + default Iso discardL(Applicative>> appB) { return LensLike.super.discardL(appB).coerce(); } @Override - default Iso discardR(Applicative> appB) { + default Iso discardR(Applicative>> appB) { return LensLike.super.discardR(appB).coerce(); } @Override - default Iso flatMap(Function>> fn) { - return unIso().fmap(bt -> Fn2.fn2(fn1(bt.andThen(fn.>andThen(Applicative::coerce)) + @SuppressWarnings("RedundantTypeArguments") + default Iso flatMap( + Function>>> fn) { + return unIso().fmap(bt -> Fn2.fn2(fn1(bt.andThen( + fn.>andThen(Monad>>::coerce)) .andThen(Iso::unIso) .andThen(Tuple2::_2) .andThen(Fn1::fn1)))) @@ -255,7 +259,7 @@ static Iso.Simple simpleIso(Function f, Fun * @param the type of both "smaller" values */ @FunctionalInterface - interface Simple extends Iso, LensLike.Simple { + interface Simple extends Iso, LensLike.Simple> { /** * Compose two simple isos from right to left. @@ -264,6 +268,7 @@ interface Simple extends Iso, LensLike.Simple { * @param the other simple iso' larger type * @return the composed simple iso */ + @SuppressWarnings("overloads") default Iso.Simple compose(Iso.Simple g) { return Iso.Simple.adapt(Iso.super.compose(g)); } @@ -275,6 +280,7 @@ default Iso.Simple compose(Iso.Simple g) { * @param the other simple iso' smaller type * @return the composed simple iso */ + @SuppressWarnings("overloads") default Iso.Simple andThen(Iso.Simple f) { return adapt(f.compose(this)); } @@ -290,7 +296,7 @@ default Lens.Simple toLens() { } @Override - default Iso.Simple discardR(Applicative> appB) { + default Iso.Simple discardR(Applicative>> appB) { return adapt(Iso.super.discardR(appB)); } diff --git a/src/main/java/com/jnape/palatable/lambda/lens/Lens.java b/src/main/java/com/jnape/palatable/lambda/lens/Lens.java index ba74b982a..edcb93650 100644 --- a/src/main/java/com/jnape/palatable/lambda/lens/Lens.java +++ b/src/main/java/com/jnape/palatable/lambda/lens/Lens.java @@ -137,7 +137,7 @@ * @param the type of the "smaller" update value */ @FunctionalInterface -public interface Lens extends LensLike { +public interface Lens extends LensLike> { @Override default Lens fmap(Function fn) { @@ -150,22 +150,24 @@ default Lens pure(U u) { } @Override - default Lens zip(Applicative, LensLike> appFn) { + default Lens zip( + Applicative, LensLike>> appFn) { return LensLike.super.zip(appFn).coerce(); } @Override - default Lens discardL(Applicative> appB) { + default Lens discardL(Applicative>> appB) { return LensLike.super.discardL(appB).coerce(); } @Override - default Lens discardR(Applicative> appB) { + default Lens discardR(Applicative>> appB) { return LensLike.super.discardR(appB).coerce(); } @Override - default Lens flatMap(Function>> f) { + default Lens flatMap( + Function>>> f) { return lens(view(this), (s, b) -> set(f.apply(set(this, b, s)).>coerce(), b, s)); } @@ -307,7 +309,7 @@ static Lens.Simple> both(Lens.Simple f, Lens.Sim * @param the type of both "smaller" values */ @FunctionalInterface - interface Simple extends Lens, LensLike.Simple { + interface Simple extends Lens, LensLike.Simple> { default Lens.Simple compose(LensLike.Simple g) { return Lens.Simple.adapt(Lens.super.compose(g)); diff --git a/src/main/java/com/jnape/palatable/lambda/lens/LensLike.java b/src/main/java/com/jnape/palatable/lambda/lens/LensLike.java index 4975544ba..d0c4647f1 100644 --- a/src/main/java/com/jnape/palatable/lambda/lens/LensLike.java +++ b/src/main/java/com/jnape/palatable/lambda/lens/LensLike.java @@ -20,7 +20,7 @@ * @see Lens * @see Iso */ -public interface LensLike extends +public interface LensLike> extends Monad>, Profunctor> { @@ -138,7 +138,7 @@ default LensLike contraMap(Function * @param the "smaller" type * @param the concrete lens subtype */ - interface Simple extends LensLike { + interface Simple> extends LensLike { /** * Compose two simple lenses from right to left. diff --git a/src/main/java/com/jnape/palatable/lambda/lens/lenses/CollectionLens.java b/src/main/java/com/jnape/palatable/lambda/lens/lenses/CollectionLens.java index b43c0e596..10c54dca9 100644 --- a/src/main/java/com/jnape/palatable/lambda/lens/lenses/CollectionLens.java +++ b/src/main/java/com/jnape/palatable/lambda/lens/lenses/CollectionLens.java @@ -63,9 +63,10 @@ public static > Lens.Simple> asSet( * @param the type of the collection * @return a lens that focuses on a Collection as a stream. */ + @SuppressWarnings("RedundantTypeArguments") public static > Lens.Simple> asStream( Function copyFn) { - return simpleLens(Collection::stream, (xsL, xsS) -> { + return simpleLens(Collection::stream, (xsL, xsS) -> { CX updated = copyFn.apply(xsL); updated.clear(); xsS.forEach(updated::add); diff --git a/src/main/java/com/jnape/palatable/lambda/monad/Monad.java b/src/main/java/com/jnape/palatable/lambda/monad/Monad.java index ef1e26a2b..1b251f51a 100644 --- a/src/main/java/com/jnape/palatable/lambda/monad/Monad.java +++ b/src/main/java/com/jnape/palatable/lambda/monad/Monad.java @@ -62,9 +62,11 @@ default Monad zip(Applicative, M> app /** * {@inheritDoc} + * @param lazyAppFn */ @Override - default Lazy> lazyZip(Lazy, M>> lazyAppFn) { + default Lazy> lazyZip( + Lazy, M>> lazyAppFn) { return Applicative.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); } diff --git a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Present.java b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Present.java index cccf15d1b..2fc0731d5 100644 --- a/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Present.java +++ b/src/main/java/com/jnape/palatable/lambda/monoid/builtin/Present.java @@ -29,7 +29,7 @@ */ public final class Present implements MonoidFactory, Maybe> { - private static final Present INSTANCE = new Present<>(); + private static final Present INSTANCE = new Present<>(); private Present() { } @@ -42,7 +42,7 @@ public Monoid> apply(Semigroup aSemigroup) { @SuppressWarnings("unchecked") public static Present present() { - return INSTANCE; + return (Present) INSTANCE; } public static Monoid> present(Semigroup semigroup) { diff --git a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Absent.java b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Absent.java index f2991e238..1e8c6ef1c 100644 --- a/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Absent.java +++ b/src/main/java/com/jnape/palatable/lambda/semigroup/builtin/Absent.java @@ -25,7 +25,7 @@ */ public final class Absent implements SemigroupFactory, Maybe> { - private static final Absent INSTANCE = new Absent<>(); + private static final Absent INSTANCE = new Absent<>(); private Absent() { } @@ -37,7 +37,7 @@ public Semigroup> apply(Semigroup aSemigroup) { @SuppressWarnings("unchecked") public static Absent absent() { - return INSTANCE; + return (Absent) INSTANCE; } public static Semigroup> absent(Semigroup semigroup) { diff --git a/src/main/java/com/jnape/palatable/lambda/traversable/LambdaIterable.java b/src/main/java/com/jnape/palatable/lambda/traversable/LambdaIterable.java index 81928dc81..5ef35da8e 100644 --- a/src/main/java/com/jnape/palatable/lambda/traversable/LambdaIterable.java +++ b/src/main/java/com/jnape/palatable/lambda/traversable/LambdaIterable.java @@ -73,13 +73,15 @@ public LambdaIterable zip(Applicative, L /** * {@inheritDoc} + * + * @param lazyAppFn */ @Override public Lazy> lazyZip( - Lazy, LambdaIterable>> lazyAppFn) { + Lazy, LambdaIterable>> lazyAppFn) { return Empty.empty(as) ? lazy(LambdaIterable.empty()) - : Monad.super.lazyZip(lazyAppFn).fmap(Applicative::coerce); + : Monad.super.lazyZip(lazyAppFn).fmap(Monad>::coerce); } /** @@ -129,7 +131,7 @@ AppTrav extends Applicative> AppTrav traverse(Function xs = as.iterator(); - Iterator ys = ((LambdaIterable) other).as.iterator(); + Iterator ys = ((LambdaIterable) other).as.iterator(); while (xs.hasNext() && ys.hasNext()) if (!Objects.equals(xs.next(), ys.next())) diff --git a/src/main/java/com/jnape/palatable/lambda/traversable/LambdaMap.java b/src/main/java/com/jnape/palatable/lambda/traversable/LambdaMap.java index 5b683de69..9c9152f87 100644 --- a/src/main/java/com/jnape/palatable/lambda/traversable/LambdaMap.java +++ b/src/main/java/com/jnape/palatable/lambda/traversable/LambdaMap.java @@ -53,7 +53,7 @@ AppTrav extends Applicative> AppTrav traverse(Function, AppTrav>fn2( appTrav -> into((k, appV) -> (AppTrav) appTrav.zip(appV.fmap(v -> m -> { ((LambdaMap) m).unwrap().put(k, v); - return (TravC) m; + return m; })))).toBiFunction(), pure.apply((TravC) LambdaMap.wrap(new HashMap<>())), this.fmap(fn).unwrap().entrySet()); diff --git a/src/test/java/com/jnape/palatable/lambda/adt/hlist/SingletonHListTest.java b/src/test/java/com/jnape/palatable/lambda/adt/hlist/SingletonHListTest.java index 56d3c19d5..aae10e80e 100644 --- a/src/test/java/com/jnape/palatable/lambda/adt/hlist/SingletonHListTest.java +++ b/src/test/java/com/jnape/palatable/lambda/adt/hlist/SingletonHListTest.java @@ -25,7 +25,7 @@ public void setUp() { } @TestTraits({FunctorLaws.class, ApplicativeLaws.class, MonadLaws.class, TraversableLaws.class}) - public SingletonHList testSubject() { + public SingletonHList testSubject() { return singletonHList("one"); } diff --git a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple2Test.java b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple2Test.java index a5e86f825..a72f4843a 100644 --- a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple2Test.java +++ b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple2Test.java @@ -34,7 +34,7 @@ public void setUp() { } @TestTraits({FunctorLaws.class, ApplicativeLaws.class, MonadLaws.class, BifunctorLaws.class, TraversableLaws.class}) - public Tuple2 testSubject() { + public Tuple2 testSubject() { return tuple("one", 2); } @@ -93,6 +93,7 @@ public void setValueIsNotSupported() { } @Test + @SuppressWarnings("serial") public void staticFactoryMethodFromMapEntry() { Map.Entry stringIntEntry = new HashMap() {{ put("string", 1); diff --git a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple3Test.java b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple3Test.java index 0730a97a9..8ca30d9af 100644 --- a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple3Test.java +++ b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple3Test.java @@ -31,7 +31,7 @@ public void setUp() { } @TestTraits({FunctorLaws.class, ApplicativeLaws.class, MonadLaws.class, BifunctorLaws.class, TraversableLaws.class}) - public Tuple3 testSubject() { + public Tuple3 testSubject() { return tuple("one", 2, 3d); } diff --git a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple4Test.java b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple4Test.java index 44a6ba8dc..7eff60484 100644 --- a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple4Test.java +++ b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple4Test.java @@ -31,7 +31,7 @@ public void setUp() { } @TestTraits({FunctorLaws.class, ApplicativeLaws.class, MonadLaws.class, BifunctorLaws.class, TraversableLaws.class}) - public Tuple4 testSubject() { + public Tuple4 testSubject() { return tuple("one", 2, 3d, 4f); } diff --git a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple5Test.java b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple5Test.java index 248dd03e1..22d30223d 100644 --- a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple5Test.java +++ b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple5Test.java @@ -32,7 +32,7 @@ public void setUp() { } @TestTraits({FunctorLaws.class, ApplicativeLaws.class, MonadLaws.class, BifunctorLaws.class, TraversableLaws.class}) - public Tuple5 testSubject() { + public Tuple5 testSubject() { return tuple("one", 2, 3d, 4f, '5'); } diff --git a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple6Test.java b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple6Test.java index bd31aca1a..af12149e6 100644 --- a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple6Test.java +++ b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple6Test.java @@ -32,7 +32,7 @@ public void setUp() { } @TestTraits({FunctorLaws.class, ApplicativeLaws.class, MonadLaws.class, BifunctorLaws.class, TraversableLaws.class}) - public Tuple6 testSubject() { + public Tuple6 testSubject() { return tuple("one", 2, 3d, 4f, '5', (byte) 6); } diff --git a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple7Test.java b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple7Test.java index a62a36691..f4fd5442e 100644 --- a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple7Test.java +++ b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple7Test.java @@ -32,7 +32,7 @@ public void setUp() { } @TestTraits({FunctorLaws.class, ApplicativeLaws.class, MonadLaws.class, BifunctorLaws.class, TraversableLaws.class}) - public Tuple7 testSubject() { + public Tuple7 testSubject() { return tuple("one", 2, 3d, 4f, '5', (byte) 6, 7L); } diff --git a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple8Test.java b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple8Test.java index c19ee8a58..327fb8fe3 100644 --- a/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple8Test.java +++ b/src/test/java/com/jnape/palatable/lambda/adt/hlist/Tuple8Test.java @@ -32,7 +32,7 @@ public void setUp() { } @TestTraits({FunctorLaws.class, ApplicativeLaws.class, MonadLaws.class, BifunctorLaws.class, TraversableLaws.class}) - public Tuple8 testSubject() { + public Tuple8 testSubject() { return tuple("one", 2, 3d, 4f, '5', (byte) 6, 7L, (short) 65535); } diff --git a/src/test/java/com/jnape/palatable/lambda/adt/hmap/HMapTest.java b/src/test/java/com/jnape/palatable/lambda/adt/hmap/HMapTest.java index 0c93ecb3f..9c2456ab8 100644 --- a/src/test/java/com/jnape/palatable/lambda/adt/hmap/HMapTest.java +++ b/src/test/java/com/jnape/palatable/lambda/adt/hmap/HMapTest.java @@ -156,11 +156,12 @@ public void demandForAbsentKey() { } @Test + @SuppressWarnings("serial") public void toMap() { TypeSafeKey stringKey = typeSafeKey(); TypeSafeKey intKey = typeSafeKey(); - assertEquals(new HashMap() {{ + assertEquals(new HashMap, Object>() {{ put(stringKey, "string"); put(intKey, 1); }}, hMap(stringKey, "string", @@ -263,7 +264,6 @@ public void convenienceStaticFactoryMethods() { } @Test - @SuppressWarnings("EqualsWithItself") public void equality() { assertEquals(emptyHMap(), emptyHMap()); diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/CycleTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/CycleTest.java index f9acf8d22..d9c04a459 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/CycleTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/CycleTest.java @@ -17,7 +17,7 @@ public class CycleTest { @TestTraits({Laziness.class, ImmutableIteration.class, InfiniteIteration.class}) - public Cycle createTestSubject() { + public Cycle createTestSubject() { return cycle(); } diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/DistinctTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/DistinctTest.java index 4755af103..b535e381c 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/DistinctTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/DistinctTest.java @@ -19,7 +19,7 @@ public class DistinctTest { @TestTraits({Laziness.class, InfiniteIterableSupport.class, EmptyIterableSupport.class, FiniteIteration.class, ImmutableIteration.class}) - public Distinct testSubject() { + public Distinct testSubject() { return distinct(); } diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/InitTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/InitTest.java index dde20b9fe..b27b65903 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/InitTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/InitTest.java @@ -23,7 +23,7 @@ public class InitTest { @TestTraits({EmptyIterableSupport.class, InfiniteIterableSupport.class, Laziness.class, ImmutableIteration.class, FiniteIteration.class}) - public Fn1 testSubject() { + public Fn1, ? extends Iterable> testSubject() { return init(); } diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/InitsTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/InitsTest.java index 191425e2c..50b417d58 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/InitsTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/InitsTest.java @@ -22,7 +22,7 @@ public class InitsTest { @TestTraits({Laziness.class, EmptyIterableSupport.class, InfiniteIterableSupport.class, FiniteIteration.class, ImmutableIteration.class}) - public Fn1 testSubject() { + public Fn1, ? extends Iterable> testSubject() { return inits(); } diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/OccurrencesTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/OccurrencesTest.java index bb11d5782..290fa2736 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/OccurrencesTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/OccurrencesTest.java @@ -2,17 +2,18 @@ import org.junit.Test; +import java.util.Collections; import java.util.HashMap; import static com.jnape.palatable.lambda.functions.builtin.fn1.Occurrences.occurrences; import static java.util.Arrays.asList; import static java.util.Collections.emptyList; -import static java.util.Collections.emptyMap; import static org.junit.Assert.assertEquals; public class OccurrencesTest { @Test + @SuppressWarnings("serial") public void occurrencesOfIndividualElements() { assertEquals(new HashMap() {{ put("foo", 2L); @@ -23,6 +24,6 @@ public void occurrencesOfIndividualElements() { @Test public void emptyIterableHasNoOccurrences() { - assertEquals(emptyMap(), occurrences(emptyList())); + assertEquals(Collections.emptyMap(), occurrences(emptyList())); } } diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/RepeatTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/RepeatTest.java index 80112707f..de34c53b4 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/RepeatTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/RepeatTest.java @@ -17,7 +17,7 @@ public class RepeatTest { @TestTraits({Laziness.class, ImmutableIteration.class, InfiniteIteration.class}) - public Repeat createTestSubject() { + public Repeat createTestSubject() { return repeat(); } diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/ReverseTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/ReverseTest.java index 308b9123e..434ed4ba2 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/ReverseTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/ReverseTest.java @@ -24,7 +24,7 @@ public class ReverseTest { @TestTraits({Laziness.class, ImmutableIteration.class, FiniteIteration.class, EmptyIterableSupport.class}) - public Reverse createTestSubject() { + public Reverse createTestSubject() { return reverse(); } diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/SizeTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/SizeTest.java index 7ee079443..a0039dc3e 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/SizeTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/SizeTest.java @@ -21,6 +21,7 @@ public void countsElementsInIterable() { } @Test + @SuppressWarnings("serial") public void optimizesForCollections() { Collection collection = spy(new ArrayList() {{ add(1); diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/TailTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/TailTest.java index 055cd9c9b..57a854456 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/TailTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/TailTest.java @@ -20,7 +20,7 @@ public class TailTest { @TestTraits({Laziness.class, EmptyIterableSupport.class, FiniteIteration.class, ImmutableIteration.class}) - public Fn1 createTraitsTestSubject() { + public Fn1, ?> createTraitsTestSubject() { return tail(); } diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/TailsTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/TailsTest.java index 45b3a1b25..a384d21cc 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/TailsTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/TailsTest.java @@ -27,7 +27,7 @@ public class TailsTest { @TestTraits({EmptyIterableSupport.class, InfiniteIterableSupport.class, FiniteIteration.class, ImmutableIteration.class, Laziness.class}) - public Fn1 testSubject() { + public Fn1, ? extends Iterable> testSubject() { return tails(); } diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/UnconsTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/UnconsTest.java index b3c8ece22..115ba8164 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/UnconsTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn1/UnconsTest.java @@ -19,7 +19,7 @@ public class UnconsTest { @TestTraits({EmptyIterableSupport.class}) - public Uncons testSubject() { + public Uncons testSubject() { return uncons(); } diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/FilterTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/FilterTest.java index 27e5fa0bd..73ca133bc 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/FilterTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/FilterTest.java @@ -25,7 +25,7 @@ public class FilterTest { @TestTraits({Laziness.class, EmptyIterableSupport.class, FiniteIteration.class, ImmutableIteration.class}) - public Fn1 testSubject() { + public Fn1, ?> testSubject() { return filter(constantly(true)); } diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/GroupByTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/GroupByTest.java index 02f8e8bf2..b04ea7999 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/GroupByTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/GroupByTest.java @@ -2,6 +2,7 @@ import org.junit.Test; +import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -13,6 +14,7 @@ import static java.util.Collections.singletonList; import static org.junit.Assert.assertEquals; +@SuppressWarnings("serial") public class GroupByTest { @Test @@ -25,6 +27,6 @@ public void grouping() { @Test public void emptyIterableProducesEmptyMap() { - assertEquals(emptyMap(), groupBy(id(), emptyList())); + assertEquals(Collections.>emptyMap(), groupBy(id(), emptyList())); } } \ No newline at end of file diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/IterateTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/IterateTest.java index 961aa0d15..564290452 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/IterateTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/IterateTest.java @@ -21,7 +21,7 @@ public class IterateTest { @TestTraits({Laziness.class, InfiniteIteration.class, ImmutableIteration.class}) - public Fn1 createTestSubject() { + public Fn1, ? extends Iterable> createTestSubject() { return iterate(constantly(new ArrayList<>())); } diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/MapTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/MapTest.java index 92a6e725b..4e7f8967c 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/MapTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/MapTest.java @@ -21,7 +21,7 @@ public class MapTest { @TestTraits({Laziness.class, EmptyIterableSupport.class, InfiniteIterableSupport.class, FiniteIteration.class, ImmutableIteration.class}) - public Fn1 createTraitsTestSubject() { + public Fn1, ?> createTraitsTestSubject() { return map(id()); } diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/PartitionTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/PartitionTest.java index 05366dfb4..8aad38db7 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/PartitionTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/PartitionTest.java @@ -29,7 +29,7 @@ public class PartitionTest { @TestTraits({Laziness.class, EmptyIterableSupport.class, FiniteIteration.class, ImmutableIteration.class}) - public Subjects> createTraitsTestSubject() { + public Subjects, ?>> createTraitsTestSubject() { return subjects(partition(constantly(a(1))).andThen(Tuple2::_1), partition(constantly(b(1))).andThen(Tuple2::_2)); } diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToMapTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToMapTest.java index 21ab43c8d..2573212f6 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToMapTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/ToMapTest.java @@ -13,6 +13,7 @@ public class ToMapTest { @Test + @SuppressWarnings("serial") public void collectsEntriesIntoMap() { Map expected = new HashMap() {{ put("foo", 1); diff --git a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/UnfoldrTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/UnfoldrTest.java index 95b0cf7c1..4c876912b 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/UnfoldrTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/UnfoldrTest.java @@ -23,7 +23,7 @@ public class UnfoldrTest { @TestTraits({Laziness.class, InfiniteIteration.class, ImmutableIteration.class}) - public Fn1 createTestSubject() { + public Fn1, ? extends Iterable> createTestSubject() { return unfoldr(x -> just(tuple(x, x))); } diff --git a/src/test/java/com/jnape/palatable/lambda/functor/builtin/ConstTest.java b/src/test/java/com/jnape/palatable/lambda/functor/builtin/ConstTest.java index 45588a462..da90a8592 100644 --- a/src/test/java/com/jnape/palatable/lambda/functor/builtin/ConstTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functor/builtin/ConstTest.java @@ -13,7 +13,7 @@ public class ConstTest { @TestTraits({FunctorLaws.class, ApplicativeLaws.class, MonadLaws.class, BifunctorLaws.class, TraversableLaws.class}) - public Const testSubject() { + public Const testSubject() { return new Const<>(1); } } \ No newline at end of file diff --git a/src/test/java/com/jnape/palatable/lambda/functor/builtin/IdentityTest.java b/src/test/java/com/jnape/palatable/lambda/functor/builtin/IdentityTest.java index 7a46afd1d..242a5aaa0 100644 --- a/src/test/java/com/jnape/palatable/lambda/functor/builtin/IdentityTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functor/builtin/IdentityTest.java @@ -12,7 +12,7 @@ public class IdentityTest { @TestTraits({FunctorLaws.class, ApplicativeLaws.class, MonadLaws.class, TraversableLaws.class}) - public Identity testSubject() { + public Identity testSubject() { return new Identity<>(""); } } \ No newline at end of file diff --git a/src/test/java/com/jnape/palatable/lambda/lens/IsoTest.java b/src/test/java/com/jnape/palatable/lambda/lens/IsoTest.java index 003c7bda7..de5557f15 100644 --- a/src/test/java/com/jnape/palatable/lambda/lens/IsoTest.java +++ b/src/test/java/com/jnape/palatable/lambda/lens/IsoTest.java @@ -1,6 +1,7 @@ package com.jnape.palatable.lambda.lens; import com.jnape.palatable.lambda.adt.Maybe; +import com.jnape.palatable.lambda.functor.Functor; import com.jnape.palatable.lambda.functor.builtin.Const; import com.jnape.palatable.traitor.annotations.TestTraits; import com.jnape.palatable.traitor.runners.Traits; @@ -28,8 +29,12 @@ public class IsoTest { iso(Integer::parseInt, dbl -> dbl.toString().chars().mapToObj(x -> (char) x).collect(toList())); @TestTraits({FunctorLaws.class, ApplicativeLaws.class, MonadLaws.class}) - public EquatableM, ?> testSubject() { - return new EquatableM<>(ISO, iso -> iso.apply(Const::new, "123")); + public EquatableM>, List> testSubject() { + return new EquatableM<>(ISO, iso -> { + @SuppressWarnings("UnnecessaryLocalVariable") + Functor> result = iso.apply(Const::new, "123"); + return result; + }); } @Test diff --git a/src/test/java/com/jnape/palatable/lambda/lens/LensTest.java b/src/test/java/com/jnape/palatable/lambda/lens/LensTest.java index 7d609e980..4ab9622a9 100644 --- a/src/test/java/com/jnape/palatable/lambda/lens/LensTest.java +++ b/src/test/java/com/jnape/palatable/lambda/lens/LensTest.java @@ -41,7 +41,7 @@ public class LensTest { LENS = lens(xs -> xs.get(0), (xs, i) -> singleton(i)); @TestTraits({FunctorLaws.class, ApplicativeLaws.class, MonadLaws.class}) - public EquatableM, ?, Integer, String, Lens>, ?> testSubject() { + public EquatableM, ?, Integer, String, Lens>, ?> testSubject() { return new EquatableM<>(lens(m -> m.get("foo"), (m, s) -> singletonList(m.get(s))), l -> view(l, emptyMap())); } diff --git a/src/test/java/com/jnape/palatable/lambda/lens/lenses/MapLensTest.java b/src/test/java/com/jnape/palatable/lambda/lens/lenses/MapLensTest.java index 7a83e934a..800dcb876 100644 --- a/src/test/java/com/jnape/palatable/lambda/lens/lenses/MapLensTest.java +++ b/src/test/java/com/jnape/palatable/lambda/lens/lenses/MapLensTest.java @@ -29,6 +29,7 @@ import static testsupport.assertion.LensAssert.assertLensLawfulness; import static testsupport.matchers.IterableMatcher.iterates; +@SuppressWarnings("serial") public class MapLensTest { @Test diff --git a/src/test/java/com/jnape/palatable/lambda/monoid/builtin/AddAllTest.java b/src/test/java/com/jnape/palatable/lambda/monoid/builtin/AddAllTest.java index 8a997382b..c1aaf214f 100644 --- a/src/test/java/com/jnape/palatable/lambda/monoid/builtin/AddAllTest.java +++ b/src/test/java/com/jnape/palatable/lambda/monoid/builtin/AddAllTest.java @@ -13,6 +13,7 @@ public class AddAllTest { @Test + @SuppressWarnings("serial") public void monoid() { Monoid> addAll = addAll(HashSet::new); diff --git a/src/test/java/com/jnape/palatable/lambda/traversable/LambdaMapTest.java b/src/test/java/com/jnape/palatable/lambda/traversable/LambdaMapTest.java index 9cffe9efb..2be8673f7 100644 --- a/src/test/java/com/jnape/palatable/lambda/traversable/LambdaMapTest.java +++ b/src/test/java/com/jnape/palatable/lambda/traversable/LambdaMapTest.java @@ -15,6 +15,7 @@ @RunWith(Traits.class) public class LambdaMapTest { + @SuppressWarnings("serial") @TestTraits({FunctorLaws.class, TraversableLaws.class}) public Subjects> testSubject() { return subjects(LambdaMap.empty(), diff --git a/src/test/java/testsupport/EquatableM.java b/src/test/java/testsupport/EquatableM.java index 72feb443d..ad4272ed8 100644 --- a/src/test/java/testsupport/EquatableM.java +++ b/src/test/java/testsupport/EquatableM.java @@ -55,4 +55,9 @@ public boolean equals(Object other) { } return false; } + + @Override + public int hashCode() { + return super.hashCode(); + } } diff --git a/src/test/java/testsupport/traits/EmptyIterableSupport.java b/src/test/java/testsupport/traits/EmptyIterableSupport.java index a0d2d029a..d30b57a3e 100644 --- a/src/test/java/testsupport/traits/EmptyIterableSupport.java +++ b/src/test/java/testsupport/traits/EmptyIterableSupport.java @@ -5,12 +5,12 @@ import java.util.ArrayList; -public class EmptyIterableSupport implements Trait> { +public class EmptyIterableSupport implements Trait, ?>> { @Override - public void test(Fn1 testSubject) { + public void test(Fn1, ?> testSubject) { try { - testSubject.apply(new ArrayList()); + testSubject.apply(new ArrayList<>()); } catch (Exception e) { throw new AssertionError("Expected support for empty iterable arguments", e); } diff --git a/src/test/java/testsupport/traits/FiniteIteration.java b/src/test/java/testsupport/traits/FiniteIteration.java index 882632f17..03168d2b6 100644 --- a/src/test/java/testsupport/traits/FiniteIteration.java +++ b/src/test/java/testsupport/traits/FiniteIteration.java @@ -8,11 +8,11 @@ import static org.hamcrest.core.Is.is; import static testsupport.matchers.FiniteIterableMatcher.finitelyIterable; -public class FiniteIteration implements Trait> { +public class FiniteIteration implements Trait, Iterable>> { @Override - public void test(Fn1 testSubject) { - Iterable result = testSubject.apply(asList(1, 2, 3)); + public void test(Fn1, Iterable> testSubject) { + Iterable result = testSubject.apply(asList(1, 2, 3)); assertThat(result, is(finitelyIterable())); } } diff --git a/src/test/java/testsupport/traits/ImmutableIteration.java b/src/test/java/testsupport/traits/ImmutableIteration.java index ce6e7db55..d6a74737e 100644 --- a/src/test/java/testsupport/traits/ImmutableIteration.java +++ b/src/test/java/testsupport/traits/ImmutableIteration.java @@ -7,11 +7,11 @@ import static org.junit.Assert.fail; -public class ImmutableIteration implements Trait> { +public class ImmutableIteration implements Trait, Iterable>> { @Override - public void test(Fn1 testSubject) { - Iterable result = testSubject.apply(new ArrayList()); + public void test(Fn1, Iterable> testSubject) { + Iterable result = testSubject.apply(new ArrayList<>()); try { result.iterator().remove(); fail("Expected remove() to throw Exception, but it didn't."); diff --git a/src/test/java/testsupport/traits/InfiniteIterableSupport.java b/src/test/java/testsupport/traits/InfiniteIterableSupport.java index 3c870f1ad..3c1131341 100644 --- a/src/test/java/testsupport/traits/InfiniteIterableSupport.java +++ b/src/test/java/testsupport/traits/InfiniteIterableSupport.java @@ -9,10 +9,10 @@ import static java.util.concurrent.TimeUnit.SECONDS; import static org.junit.Assert.fail; -public class InfiniteIterableSupport implements Trait> { +public class InfiniteIterableSupport implements Trait, Iterable>> { @Override - public void test(Fn1 testSubject) { + public void test(Fn1, Iterable> testSubject) { CountDownLatch latch = new CountDownLatch(1); new Thread(() -> { testSubject.apply(repeat(0)).iterator().next(); diff --git a/src/test/java/testsupport/traits/InfiniteIteration.java b/src/test/java/testsupport/traits/InfiniteIteration.java index 12072fe78..085907ce2 100644 --- a/src/test/java/testsupport/traits/InfiniteIteration.java +++ b/src/test/java/testsupport/traits/InfiniteIteration.java @@ -9,11 +9,11 @@ import static org.hamcrest.core.Is.is; import static testsupport.matchers.FiniteIterableMatcher.finitelyIterable; -public class InfiniteIteration implements Trait> { +public class InfiniteIteration implements Trait, Iterable>> { @Override - public void test(Fn1 testSubject) { - Iterable result = testSubject.apply(asList(1, 2, 3)); + public void test(Fn1, Iterable> testSubject) { + Iterable result = testSubject.apply(asList(1, 2, 3)); assertThat(result, is(not(finitelyIterable()))); } } diff --git a/src/test/java/testsupport/traits/Laziness.java b/src/test/java/testsupport/traits/Laziness.java index 216201df7..cd0a58b6c 100644 --- a/src/test/java/testsupport/traits/Laziness.java +++ b/src/test/java/testsupport/traits/Laziness.java @@ -7,11 +7,11 @@ import static testsupport.Mocking.mockIterable; import static testsupport.matchers.ZeroInvocationsMatcher.wasNeverInteractedWith; -public class Laziness implements Trait> { +public class Laziness implements Trait, Iterable>> { @Override - public void test(Fn1 testSubject) { - Iterable iterable = mockIterable(); + public void test(Fn1, Iterable> testSubject) { + Iterable iterable = mockIterable(); testSubject.apply(iterable); assertThat(iterable, wasNeverInteractedWith()); From 96ed8c0fafbc26efe6fbc176ab86a16e27555a86 Mon Sep 17 00:00:00 2001 From: jnape Date: Sun, 14 Apr 2019 18:51:08 -0500 Subject: [PATCH 11/69] Compose lazyZip defers to outer applicative's lazyZip --- .../palatable/lambda/functor/builtin/Compose.java | 13 ++++++++++++- .../lambda/functor/builtin/ComposeTest.java | 12 ++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Compose.java b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Compose.java index df6d857c2..b7dcbe209 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/builtin/Compose.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/builtin/Compose.java @@ -5,6 +5,8 @@ import java.util.Objects; import java.util.function.Function; +import static com.jnape.palatable.lambda.functions.builtin.fn1.Upcast.upcast; + /** * A functor representing the type-level composition of two {@link Applicative} functors; useful for preserving nested * type-level transformations during traversal of a {@link com.jnape.palatable.lambda.traversable.Traversable}. @@ -60,7 +62,16 @@ public Compose zip(Applicative, Co @Override public Lazy> lazyZip( Lazy, Compose>> lazyAppFn) { - return Applicative.super.lazyZip(lazyAppFn).fmap(Applicative>::coerce); + @SuppressWarnings("RedundantTypeArguments") + Lazy, G>, F>> lazyAppFnCoerced = + lazyAppFn + .>>fmap( + Applicative, Compose>::coerce) + .fmap(Compose>::getCompose); + + return fga.>fmap(upcast()) + .>lazyZip(lazyAppFnCoerced.fmap(fgf -> fgf.fmap(gf -> ga -> ga.zip(gf)))) + .fmap(Compose::new); } /** diff --git a/src/test/java/com/jnape/palatable/lambda/functor/builtin/ComposeTest.java b/src/test/java/com/jnape/palatable/lambda/functor/builtin/ComposeTest.java index 66303c375..dc994a3b0 100644 --- a/src/test/java/com/jnape/palatable/lambda/functor/builtin/ComposeTest.java +++ b/src/test/java/com/jnape/palatable/lambda/functor/builtin/ComposeTest.java @@ -9,8 +9,10 @@ import testsupport.traits.ApplicativeLaws; import testsupport.traits.FunctorLaws; +import static com.jnape.palatable.lambda.adt.Either.left; import static com.jnape.palatable.lambda.adt.Either.right; import static com.jnape.palatable.lambda.adt.Maybe.just; +import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy; import static org.junit.Assert.assertEquals; @RunWith(Traits.class) @@ -26,4 +28,14 @@ public void inference() { Either> a = new Compose<>(right(just(1))).fmap(x -> x + 1).getCompose(); assertEquals(right(just(2)), a); } + + @Test + public void lazyZip() { + assertEquals(new Compose<>(right(just(2))), + new Compose<>(right(just(1))).lazyZip(lazy(new Compose<>(right(just(x -> x + 1))))).value()); + assertEquals(new Compose<>(left("foo")), + new Compose<>(left("foo")).lazyZip(lazy(() -> { + throw new AssertionError(); + })).value()); + } } \ No newline at end of file From b006704e6a70e51f6270f208f233d5a26456bd55 Mon Sep 17 00:00:00 2001 From: jnape Date: Sun, 14 Apr 2019 19:59:04 -0500 Subject: [PATCH 12/69] MaybeT, a monad transformer for Maybe, and general MonadT --- CHANGELOG.md | 2 + .../jnape/palatable/lambda/monad/Monad.java | 1 - .../lambda/monad/transformer/MaybeT.java | 129 ++++++++++++++++++ .../lambda/monad/transformer/MonadT.java | 101 ++++++++++++++ .../lambda/monad/transformer/MaybeTTest.java | 41 ++++++ 5 files changed, 273 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/jnape/palatable/lambda/monad/transformer/MaybeT.java create mode 100644 src/main/java/com/jnape/palatable/lambda/monad/transformer/MonadT.java create mode 100644 src/test/java/com/jnape/palatable/lambda/monad/transformer/MaybeTTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index ec8477ed1..bf372699b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ might need to be reworked, and subtyping is obviously no longer supported. - `Lazy`, a monad supporting stack-safe lazy evaluation - `LazyRec`, a function for writing stack-safe recursive algorithms embedded in `Lazy` - `Applicative#lazyZip`, for zipping two applicatives in a way that might not require evaluation of one applicative +- `MonadT`, a general interface representing monad transformers +- `MaybeT`, a monad transformer for `Maybe` ## [3.3.0] - 2019-02-18 ### Added diff --git a/src/main/java/com/jnape/palatable/lambda/monad/Monad.java b/src/main/java/com/jnape/palatable/lambda/monad/Monad.java index 1b251f51a..00aca101c 100644 --- a/src/main/java/com/jnape/palatable/lambda/monad/Monad.java +++ b/src/main/java/com/jnape/palatable/lambda/monad/Monad.java @@ -62,7 +62,6 @@ default Monad zip(Applicative, M> app /** * {@inheritDoc} - * @param lazyAppFn */ @Override default Lazy> lazyZip( diff --git a/src/main/java/com/jnape/palatable/lambda/monad/transformer/MaybeT.java b/src/main/java/com/jnape/palatable/lambda/monad/transformer/MaybeT.java new file mode 100644 index 000000000..afbf56721 --- /dev/null +++ b/src/main/java/com/jnape/palatable/lambda/monad/transformer/MaybeT.java @@ -0,0 +1,129 @@ +package com.jnape.palatable.lambda.monad.transformer; + +import com.jnape.palatable.lambda.adt.Maybe; +import com.jnape.palatable.lambda.functor.Applicative; +import com.jnape.palatable.lambda.functor.builtin.Compose; +import com.jnape.palatable.lambda.functor.builtin.Lazy; +import com.jnape.palatable.lambda.monad.Monad; + +import java.util.Objects; +import java.util.function.Function; + +import static com.jnape.palatable.lambda.adt.Maybe.just; +import static com.jnape.palatable.lambda.adt.Maybe.nothing; +import static com.jnape.palatable.lambda.functions.builtin.fn1.Constantly.constantly; + +/** + * A {@link MonadT monad transformer} for {@link Maybe}. + * + * @param the outer {@link Monad} + * @param the carrier type + */ +public final class MaybeT, A> implements MonadT, A> { + + private final Monad, M> mma; + + private MaybeT(Monad, M> mma) { + this.mma = mma; + } + + /** + * {@inheritDoc} + */ + @Override + public >, FGA extends Monad> FGA run() { + return mma.fmap(Applicative::coerce).coerce(); + } + + /** + * {@inheritDoc} + */ + @Override + public MaybeT fmap(Function fn) { + return MonadT.super.fmap(fn).coerce(); + } + + /** + * {@inheritDoc} + */ + @Override + public MaybeT pure(B b) { + return maybeT(mma.pure(just(b))); + } + + /** + * {@inheritDoc} + */ + @Override + public MaybeT zip(Applicative, MonadT, ?>> appFn) { + return MonadT.super.zip(appFn).coerce(); + } + + /** + * {@inheritDoc} + */ + @Override + public Lazy> lazyZip( + Lazy, MonadT, ?>>> lazyAppFn) { + return new Compose<>(mma) + .lazyZip(lazyAppFn.fmap(maybeT -> new Compose<>( + maybeT.>>coerce().>, Monad>, M>>run()))) + .fmap(compose -> maybeT(compose.getCompose())); + } + + /** + * {@inheritDoc} + */ + @Override + public MaybeT flatMap(Function, ?>>> f) { + return maybeT(mma.flatMap(ma -> ma + .match(constantly(mma.pure(nothing())), + a -> f.apply(a).>coerce().run()))); + } + + /** + * {@inheritDoc} + */ + @Override + public MaybeT discardL(Applicative, ?>> appB) { + return MonadT.super.discardL(appB).coerce(); + } + + /** + * {@inheritDoc} + */ + @Override + public MaybeT discardR(Applicative, ?>> appB) { + return MonadT.super.discardR(appB).coerce(); + } + + @Override + public boolean equals(Object other) { + return other instanceof MaybeT && Objects.equals(mma, ((MaybeT) other).mma); + } + + @Override + public int hashCode() { + return Objects.hash(mma); + } + + @Override + public String toString() { + return "MaybeT{" + + "mma=" + mma + + '}'; + } + + /** + * Static factory method for lifting a {@link Monad}<{@link Maybe}<A>> into a + * {@link MaybeT}. + * + * @param mma the {@link Monad}<{@link Maybe}<A>> + * @param the outer {@link Monad} unification parameter + * @param the carrier type + * @return the {@link MaybeT} + */ + public static , A> MaybeT maybeT(Monad, M> mma) { + return new MaybeT<>(mma); + } +} diff --git a/src/main/java/com/jnape/palatable/lambda/monad/transformer/MonadT.java b/src/main/java/com/jnape/palatable/lambda/monad/transformer/MonadT.java new file mode 100644 index 000000000..8098d2ba6 --- /dev/null +++ b/src/main/java/com/jnape/palatable/lambda/monad/transformer/MonadT.java @@ -0,0 +1,101 @@ +package com.jnape.palatable.lambda.monad.transformer; + +import com.jnape.palatable.lambda.functor.Applicative; +import com.jnape.palatable.lambda.functor.builtin.Lazy; +import com.jnape.palatable.lambda.monad.Monad; + +import java.util.function.Function; + +/** + * An interface representing a {@link Monad} transformer. + *

, F extends Functor, FB extends Functor, + FT extends Functor, PAFB extends Profunctor, + PSFT extends Profunctor> PSFT apply(PAFB pafb) { + return composed.apply(pafb); } @Override @@ -105,8 +107,9 @@ interface Simple extends TypeSafeKey { @Override @SuppressWarnings("unchecked") - default