From 02683b638a4f1bcfbc51ca94dca9dd152fab6813 Mon Sep 17 00:00:00 2001 From: jnape Date: Sun, 31 Jul 2016 17:59:46 -0500 Subject: [PATCH 1/8] [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 215859eae..7a416f475 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ lambda - 1.3 + 1.4-SNAPSHOT jar Lambda From 4222b4186cdabc046527faf68a7f0ffdd35e4930 Mon Sep 17 00:00:00 2001 From: John Napier Date: Sun, 31 Jul 2016 18:11:18 -0500 Subject: [PATCH 2/8] Adding maven version badge to readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2dd80178d..df53657f7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ λ ====== [![Build Status](https://travis-ci.org/palatable/lambda.svg)](https://travis-ci.org/palatable/lambda) +[![Lambda](https://img.shields.io/maven-central/v/com.jnape.palatable/lambda.svg?maxAge=2592000)](http://search.maven.org/#search%7Cga%7C1%7Ccom.jnape.palatable.lambda) Functional patterns for Java 8 From 1e0be65fbbbd456ab2f6cb1faf3c75aa26c94e33 Mon Sep 17 00:00:00 2001 From: John Napier Date: Sun, 31 Jul 2016 18:36:13 -0500 Subject: [PATCH 3/8] Adding javadoc link to README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index df53657f7..f3bc07eed 100644 --- a/README.md +++ b/README.md @@ -122,7 +122,7 @@ And have fun with 3s: //-> [[3, 6, 9], [12, 15, 18], [21, 24, 27]] ``` -Or check out [the tests](https://github.com/palatable/lambda/tree/master/src/test/java/com/jnape/palatable/lambda/functions/builtin) for more examples. +Check out the [tests](https://github.com/palatable/lambda/tree/master/src/test/java/com/jnape/palatable/lambda/functions/builtin) or [javadoc](http://palatable.github.io/lambda/javadoc/) for more examples. ADTs ---- From ace8e90bc5467c17f9552679a7ae2e4228657be1 Mon Sep 17 00:00:00 2001 From: John Napier Date: Sun, 31 Jul 2016 19:03:36 -0500 Subject: [PATCH 4/8] Adding TOC to Readme --- README.md | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index f3bc07eed..e2793fd5e 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,19 @@ Functional patterns for Java 8 -Background +#### Table of Contents + + - [Background](#background) + - [Installation](#installation) + - [Examples](#examples) + - [ADTs](#adts) + - [HLists](#hlists) + - [Tuples](#tuples) + - [HMaps](#hmaps) + - [Either](#either) + - [License](#license) + +Background ---------- Lambda was born out of a desire to use some of the same canonical functions (e.g. `unfoldr`, `takeWhile`, `zipWith`) and functional patterns (e.g. `Functor` and friends) that are idiomatic in other languages and make them available for Java. @@ -22,7 +34,7 @@ Generally, everything that lambda produces is lazily-evaluated (except for termi Although the library is currently (very) small, these values should always be the driving forces behind future growth. -Installation +Installation ------------ Add the following dependency to your: @@ -44,7 +56,7 @@ Add the following dependency to your: ``` -Examples +Examples -------- First, the obligatory `map`/`filter`/`reduce` example: @@ -124,12 +136,12 @@ And have fun with 3s: Check out the [tests](https://github.com/palatable/lambda/tree/master/src/test/java/com/jnape/palatable/lambda/functions/builtin) or [javadoc](http://palatable.github.io/lambda/javadoc/) for more examples. -ADTs +ADTs ---- In addition to the functions above, lambda also supports a few first-class [algebraic data types](https://www.wikiwand.com/en/Algebraic_data_type). -### Heterogeneous Lists (HLists) +### Heterogeneous Lists (HLists) HLists are type-safe heterogeneous lists, meaning they can store elements of different types in the same list while facilitating certain type-safe interactions. @@ -145,7 +157,7 @@ The following illustrates how the linear expansion of the recursive type signatu //nil.head() won't type-check ``` -#### Tuples +#### Tuples One of the primary downsides to using `HList`s in Java is how quickly the type signature grows. @@ -188,7 +200,7 @@ Finally, all `Tuple*` classes are instances of both `Functor` and `Bifunctor`: System.out.println(mappedTuple3._3()); // prints 2 ``` -### Heterogeneous Maps +### Heterogeneous Maps HMaps are type-safe heterogeneous maps, meaning they can store mappings to different value types in the same map; however, whereas HLists encode value types in their type signatures, HMaps rely on the keys to encode the value type that they point to. @@ -203,7 +215,7 @@ HMaps are type-safe heterogeneous maps, meaning they can store mappings to diffe Optional anotherIntValue = hmap.get(anotherIntKey); // Optional.empty ``` -### Either +### Either Binary tagged unions are represented as `Either`s, which resolve to one of two possible values: a `Left` value wrapping an `L`, or a `Right` value wrapping an `R` (typically an exceptional value or a successful value, respectively). @@ -222,7 +234,7 @@ Rather than supporting explicit value unwrapping, `Either` supports many useful Check out the tests for [more examples](https://github.com/palatable/lambda/blob/master/src/test/java/com/jnape/palatable/lambda/adt/EitherTest.java) of ways to interact with `Either`. -License +License ------- _lambda_ is part of [palatable](http://www.github.com/palatable), which is distributed under [The MIT License](http://choosealicense.com/licenses/mit/). From e6b35f66de01ab29f367a03a6f896bc91468b3c5 Mon Sep 17 00:00:00 2001 From: John Napier Date: Mon, 1 Aug 2016 21:41:29 -0500 Subject: [PATCH 5/8] Adding Notes to README --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index e2793fd5e..52c88d502 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ Functional patterns for Java 8 - [Tuples](#tuples) - [HMaps](#hmaps) - [Either](#either) + - [Notes](#notes) - [License](#license) Background @@ -234,6 +235,13 @@ Rather than supporting explicit value unwrapping, `Either` supports many useful Check out the tests for [more examples](https://github.com/palatable/lambda/blob/master/src/test/java/com/jnape/palatable/lambda/adt/EitherTest.java) of ways to interact with `Either`. +Notes +----- + +Wherever possible, _lambda_ maintains interface compatibility with similar, familiar core Java types. Some examples of where this works well is with both `Fn1` and `Predicate`, which extend `j.u.f.Function` and `j.u.f.Predicate`, respectively. In these examples, they also override any implemented methods to return their _lambda_-specific counterparts (`Fn1.compose` returning `Fn1` instead of `j.u.f.Function` as an example). + +Unfortunately, due to Java's type hierarchy and inheritance inconsistencies, this is not always possible. One surprising example of this is how `Fn1` extends `j.u.f.Function`, but `Fn2` does not extend `j.u.f.BiFunction`. This is because `j.u.f.BiFunction` itself does not extend `j.u.f.Function`, but it does define methods that collide with `j.u.f.Function`. For this reason, both `Fn1` and `Fn2` cannot extend their Java counterparts without sacrificing their own inheritance hierarchy. These types of asymmetries are, unfortunately, not uncommon; however, wherever these situations arise, measures are taken to attempt to ease the transition in and out of core Java types (in the case of `Fn2`, a supplemental `#toBiFunction` method is added). I do not take these inconveniences for granted, and I'm regularly looking for ways to minimize the negative impact of this as much as possible. Suggestions and use cases that highlight particular pain points here are particularly appreciated. + License ------- From b7545199fc3f35411d6b1d8629534becc5eeefcc Mon Sep 17 00:00:00 2001 From: jnape Date: Mon, 1 Aug 2016 21:41:15 -0500 Subject: [PATCH 6/8] For better Java8 compatibility, all lambda input argument types are replaced with Java8 input types where possible - Fn1 argument types become j.u.f.Function - Fn2 argument types become j.u.f.BiFunction - Adding Fn2#toBiFunction - Well, Java8's type hierarchy and javac really worked together on this one. Not only is it not possible for both Fn1 and Fn2 to extend their native Java8 counterparts (j.u.f.Function and j.u.f.BiFunction, respectively), due to Function and BiFunction existing in orthogonal type hierarchies and both defining conflicting methods with the other; it is also not possible to provide overloads for both Fn1 and Function (or Fn2 and BiFunction), since both will be @FunctionInterfaces, and javac will have no opinion about precedence of one over the other. The outcome is that explicit, dreadful type-casts to something like (Fn1) or (BiFunction) would be necessary at the call site of every overload. This is the least acceptable outcome for me, so I'm begrudgingly just typing against native Java8 types for all inputs. I'm sorry. This is why we can't have nice things. --- .../jnape/palatable/lambda/adt/Either.java | 40 +++++++++---------- .../lambda/adt/hlist/SingletonHList.java | 7 ++-- .../palatable/lambda/adt/hlist/Tuple2.java | 12 +++--- .../palatable/lambda/adt/hlist/Tuple3.java | 13 +++--- .../palatable/lambda/adt/hlist/Tuple4.java | 13 +++--- .../palatable/lambda/adt/hlist/Tuple5.java | 13 +++--- .../jnape/palatable/lambda/functions/Fn1.java | 24 +++++------ .../jnape/palatable/lambda/functions/Fn2.java | 12 ++++++ .../lambda/functions/builtin/fn2/All.java | 10 +++-- .../lambda/functions/builtin/fn2/Any.java | 10 +++-- .../functions/builtin/fn2/DropWhile.java | 10 +++-- .../lambda/functions/builtin/fn2/Filter.java | 10 +++-- .../lambda/functions/builtin/fn2/Iterate.java | 13 +++--- .../lambda/functions/builtin/fn2/Map.java | 10 +++-- .../functions/builtin/fn2/Partial2.java | 20 +++++----- .../functions/builtin/fn2/ReduceLeft.java | 11 ++--- .../functions/builtin/fn2/ReduceRight.java | 13 +++--- .../functions/builtin/fn2/TakeWhile.java | 11 ++--- .../lambda/functions/builtin/fn2/Unfoldr.java | 9 +++-- .../lambda/functions/builtin/fn2/Zip.java | 3 +- .../functions/builtin/fn3/FoldLeft.java | 22 +++++----- .../functions/builtin/fn3/FoldRight.java | 24 ++++++----- .../functions/builtin/fn3/ScanLeft.java | 22 +++++----- .../lambda/functions/builtin/fn3/ZipWith.java | 12 +++--- .../functions/specialized/Predicate.java | 2 +- .../palatable/lambda/functor/Bifunctor.java | 16 ++++---- .../palatable/lambda/functor/Functor.java | 6 ++- .../palatable/lambda/functor/Profunctor.java | 16 ++++---- .../lambda/iterators/FilteringIterator.java | 9 ++--- .../lambda/iterators/MappingIterator.java | 9 ++--- .../iterators/PredicatedDroppingIterator.java | 11 +++-- .../iterators/PredicatedTakingIterator.java | 11 +++-- .../lambda/iterators/ScanningIterator.java | 11 +++-- .../lambda/iterators/UnfoldingIterator.java | 9 +++-- .../lambda/iterators/ZippingIterator.java | 11 +++-- .../palatable/lambda/adt/EitherTest.java | 6 +-- .../palatable/lambda/functions/Fn2Test.java | 9 +++++ .../lambda/functions/builtin/fn2/AllTest.java | 4 +- .../lambda/functions/builtin/fn2/AnyTest.java | 4 +- .../functions/builtin/fn2/Partial2Test.java | 6 +-- .../functions/builtin/fn3/ZipWithTest.java | 5 ++- .../lambda/functor/BifunctorTest.java | 6 +-- .../lambda/functor/ProfunctorTest.java | 6 +-- .../iterators/ScanningIteratorTest.java | 4 +- .../lambda/iterators/ZippingIteratorTest.java | 8 ++-- .../InvocationRecordingBifunctor.java | 14 +++---- .../InvocationRecordingProfunctor.java | 12 +++--- .../testsupport/functions/ExplainFold.java | 4 +- 48 files changed, 297 insertions(+), 246 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 371e5d355..4fdd106fd 100644 --- a/src/main/java/com/jnape/palatable/lambda/adt/Either.java +++ b/src/main/java/com/jnape/palatable/lambda/adt/Either.java @@ -1,14 +1,14 @@ package com.jnape.palatable.lambda.adt; -import com.jnape.palatable.lambda.functions.Fn1; -import com.jnape.palatable.lambda.functions.Fn2; import com.jnape.palatable.lambda.functions.specialized.checked.CheckedSupplier; import com.jnape.palatable.lambda.functor.Bifunctor; import com.jnape.palatable.lambda.functor.Functor; import java.util.Objects; import java.util.Optional; +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; @@ -43,7 +43,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(Fn1 recoveryFn) { + public final R recover(Function recoveryFn) { return match(recoveryFn, id()); } @@ -54,7 +54,7 @@ public final R recover(Fn1 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(Fn1 forfeitFn) { + public final L forfeit(Function forfeitFn) { return match(id(), forfeitFn); } @@ -67,7 +67,7 @@ public final L forfeit(Fn1 forfeitFn) { * @return the wrapped value if this is a right * @throws E the result of applying the wrapped left value to throwableFn, if this is a left */ - public final R orThrow(Fn1 throwableFn) throws E { + public final R orThrow(Function throwableFn) throws E { return match(l -> { throw throwableFn.apply(l); }, id()); @@ -84,7 +84,7 @@ public final R orThrow(Fn1 * @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(Fn1 pred, Supplier leftSupplier) { + public final Either filter(Function pred, Supplier leftSupplier) { return flatMap(r -> pred.apply(r) ? right(r) : left(leftSupplier.get())); } @@ -99,7 +99,7 @@ public final Either filter(Fn1 pred, Supplier leftS * @param the new right parameter type * @return the Either resulting from applying rightFn to this right value, or this left value if left */ - public final Either flatMap(Fn1> rightFn) { + public final Either flatMap(Function> rightFn) { return flatMap(Either::left, rightFn); } @@ -114,8 +114,8 @@ public final Either flatMap(Fn1> * @param the new right parameter type * @return the result of either rightFn or leftFn, depending on whether this is a right or a left */ - public final Either flatMap(Fn1> leftFn, - Fn1> rightFn) { + public final Either flatMap(Function> leftFn, + Function> rightFn) { return match(leftFn, rightFn); } @@ -130,8 +130,8 @@ public final Either flatMap(Fn1 merge(Fn2 leftFn, - Fn2 rightFn, + public final Either merge(BiFunction leftFn, + BiFunction rightFn, Either other) { return this.match( l1 -> other.match(l2 -> left(leftFn.apply(l1, l2)), r -> left(l1)), @@ -176,28 +176,28 @@ public Either peek(Consumer leftConsumer, Consumer rightConsumer) { * @param the result type * @return the result of applying the appropriate mapping function to the wrapped value */ - public abstract V match(Fn1 leftFn, Fn1 rightFn); + public abstract V match(Function leftFn, Function rightFn); @Override - public final Either fmap(Fn1 fn) { + public final Either fmap(Function fn) { return biMapR(fn); } @Override @SuppressWarnings("unchecked") - public final Either biMapL(Fn1 fn) { + public final Either biMapL(Function fn) { return (Either) Bifunctor.super.biMapL(fn); } @Override @SuppressWarnings("unchecked") - public final Either biMapR(Fn1 fn) { + public final Either biMapR(Function fn) { return (Either) Bifunctor.super.biMapR(fn); } @Override - public final Either biMap(Fn1 leftFn, - Fn1 rightFn) { + public final Either biMap(Function leftFn, + Function rightFn) { return match(l -> left(leftFn.apply(l)), r -> right(rightFn.apply(r))); } @@ -229,7 +229,7 @@ public static Either fromOptional(Optional optional, Supplier */ @SuppressWarnings("unchecked") public static Either trying(CheckedSupplier supplier, - Fn1 leftFn) { + Function leftFn) { try { return right(supplier.get()); } catch (Exception e) { @@ -282,7 +282,7 @@ private Left(L l) { } @Override - public V match(Fn1 leftFn, Fn1 rightFn) { + public V match(Function leftFn, Function rightFn) { return leftFn.apply(l); } @@ -312,7 +312,7 @@ private Right(R r) { } @Override - public V match(Fn1 leftFn, Fn1 rightFn) { + public V match(Function leftFn, Function rightFn) { return rightFn.apply(r); } 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 f651328a8..6e62e1a66 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,10 +2,9 @@ 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.Functor; -import java.util.RandomAccess; +import java.util.function.Function; /** * A singleton HList. Supports random access. @@ -17,7 +16,7 @@ * @see Tuple4 * @see Tuple5 */ -public class SingletonHList<_1> extends HCons<_1, HNil> implements Functor<_1>, RandomAccess { +public class SingletonHList<_1> extends HCons<_1, HNil> implements Functor<_1> { SingletonHList(_1 _1) { super(_1, nil()); @@ -29,7 +28,7 @@ public <_0> Tuple2<_0, _1> cons(_0 _0) { } @Override - public <_1Prime> SingletonHList<_1Prime> fmap(Fn1 fn) { + public <_1Prime> SingletonHList<_1Prime> fmap(Function fn) { return new SingletonHList<>(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 222fb1f23..b73f57e05 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 @@ -1,11 +1,11 @@ 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.lambda.functor.Bifunctor; import com.jnape.palatable.lambda.functor.Functor; import java.util.Map; +import java.util.function.Function; /** * A 2-element tuple product type, implemented as a specialized HList. Supports random access. @@ -68,25 +68,25 @@ public _2 setValue(_2 value) { } @Override - public <_2Prime> Tuple2<_1, _2Prime> fmap(Fn1 fn) { + public <_2Prime> Tuple2<_1, _2Prime> fmap(Function fn) { return tuple(_1(), fn.apply(_2())); } @Override @SuppressWarnings("unchecked") - public <_1Prime> Tuple2<_1Prime, _2> biMapL(Fn1 fn) { + public <_1Prime> Tuple2<_1Prime, _2> biMapL(Function fn) { return (Tuple2<_1Prime, _2>) Bifunctor.super.biMapL(fn); } @Override @SuppressWarnings("unchecked") - public <_2Prime> Tuple2<_1, _2Prime> biMapR(Fn1 fn) { + public <_2Prime> Tuple2<_1, _2Prime> biMapR(Function fn) { return (Tuple2<_1, _2Prime>) Bifunctor.super.biMapR(fn); } @Override - public <_1Prime, _2Prime> Tuple2<_1Prime, _2Prime> biMap(Fn1 lFn, - Fn1 rFn) { + public <_1Prime, _2Prime> Tuple2<_1Prime, _2Prime> biMap(Function lFn, + Function rFn) { return new Tuple2<>(lFn.apply(_1()), tail().fmap(rFn)); } 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 acc840e06..431eeb375 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 @@ -1,10 +1,11 @@ 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.lambda.functor.Bifunctor; import com.jnape.palatable.lambda.functor.Functor; +import java.util.function.Function; + /** * A 3-element tuple product type, implemented as a specialized HList. Supports random access. * @@ -62,25 +63,25 @@ public _3 _3() { } @Override - public <_3Prime> Tuple3<_1, _2, _3Prime> fmap(Fn1 fn) { + public <_3Prime> Tuple3<_1, _2, _3Prime> fmap(Function fn) { return biMapR(fn); } @Override @SuppressWarnings("unchecked") - public <_2Prime> Tuple3<_1, _2Prime, _3> biMapL(Fn1 fn) { + public <_2Prime> Tuple3<_1, _2Prime, _3> biMapL(Function fn) { return (Tuple3<_1, _2Prime, _3>) Bifunctor.super.biMapL(fn); } @Override @SuppressWarnings("unchecked") - public <_3Prime> Tuple3<_1, _2, _3Prime> biMapR(Fn1 fn) { + public <_3Prime> Tuple3<_1, _2, _3Prime> biMapR(Function fn) { return (Tuple3<_1, _2, _3Prime>) Bifunctor.super.biMapR(fn); } @Override - public <_2Prime, _3Prime> Tuple3<_1, _2Prime, _3Prime> biMap(Fn1 lFn, - Fn1 rFn) { + public <_2Prime, _3Prime> Tuple3<_1, _2Prime, _3Prime> biMap(Function lFn, + Function rFn) { return new Tuple3<>(_1(), tail().biMap(lFn, rFn)); } } 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 38208b713..35effe953 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 @@ -1,10 +1,11 @@ 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.lambda.functor.Bifunctor; import com.jnape.palatable.lambda.functor.Functor; +import java.util.function.Function; + /** * A 4-element tuple product type, implemented as a specialized HList. Supports random access. * @@ -74,25 +75,25 @@ public _4 _4() { } @Override - public <_4Prime> Tuple4<_1, _2, _3, _4Prime> fmap(Fn1 fn) { + public <_4Prime> Tuple4<_1, _2, _3, _4Prime> fmap(Function fn) { return biMapR(fn); } @Override @SuppressWarnings("unchecked") - public <_3Prime> Tuple4<_1, _2, _3Prime, _4> biMapL(Fn1 fn) { + public <_3Prime> Tuple4<_1, _2, _3Prime, _4> biMapL(Function fn) { return (Tuple4<_1, _2, _3Prime, _4>) Bifunctor.super.biMapL(fn); } @Override @SuppressWarnings("unchecked") - public <_4Prime> Tuple4<_1, _2, _3, _4Prime> biMapR(Fn1 fn) { + public <_4Prime> Tuple4<_1, _2, _3, _4Prime> biMapR(Function fn) { return (Tuple4<_1, _2, _3, _4Prime>) Bifunctor.super.biMapR(fn); } @Override - public <_3Prime, _4Prime> Tuple4<_1, _2, _3Prime, _4Prime> biMap(Fn1 lFn, - Fn1 rFn) { + public <_3Prime, _4Prime> Tuple4<_1, _2, _3Prime, _4Prime> biMap(Function lFn, + Function rFn) { return new Tuple4<>(_1(), tail().biMap(lFn, rFn)); } } 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 49cf2c29a..a138f4d76 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 @@ -1,10 +1,11 @@ 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.lambda.functor.Bifunctor; import com.jnape.palatable.lambda.functor.Functor; +import java.util.function.Function; + /** * A 5-element tuple product type, implemented as a specialized HList. Supports random access. * @@ -86,25 +87,25 @@ public _5 _5() { } @Override - public <_5Prime> Tuple5<_1, _2, _3, _4, _5Prime> fmap(Fn1 fn) { + public <_5Prime> Tuple5<_1, _2, _3, _4, _5Prime> fmap(Function fn) { return biMapR(fn); } @Override @SuppressWarnings("unchecked") - public <_4Prime> Tuple5<_1, _2, _3, _4Prime, _5> biMapL(Fn1 fn) { + public <_4Prime> Tuple5<_1, _2, _3, _4Prime, _5> biMapL(Function fn) { return (Tuple5<_1, _2, _3, _4Prime, _5>) Bifunctor.super.biMapL(fn); } @Override @SuppressWarnings("unchecked") - public <_5Prime> Tuple5<_1, _2, _3, _4, _5Prime> biMapR(Fn1 fn) { + public <_5Prime> Tuple5<_1, _2, _3, _4, _5Prime> biMapR(Function fn) { return (Tuple5<_1, _2, _3, _4, _5Prime>) Bifunctor.super.biMapR(fn); } @Override - public <_4Prime, _5Prime> Tuple5<_1, _2, _3, _4Prime, _5Prime> biMap(Fn1 lFn, - Fn1 rFn) { + public <_4Prime, _5Prime> Tuple5<_1, _2, _3, _4Prime, _5Prime> biMap(Function lFn, + Function rFn) { return new Tuple5<>(_1(), tail().biMap(lFn, rFn)); } } 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 a5eda64ea..3443ac535 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn1.java @@ -31,20 +31,20 @@ public interface Fn1 extends Functor, Profunctor, Function * @param the return type of the next function to invoke * @return a function representing the composition of this function and f */ - default Fn1 then(Fn1 f) { + default Fn1 then(Function f) { return fmap(f); } /** * Also left-to-right composition (sadly). * - * @param f the function to invoke with this function's return value * @param the return type of the next function to invoke + * @param f the function to invoke with this function's return value * @return a function representing the composition of this function and f - * @see Fn1#then(Fn1) + * @see Fn1#then(Function) */ @Override - default Fn1 fmap(Fn1 f) { + default Fn1 fmap(Function f) { return a -> f.apply(apply(a)); } @@ -52,12 +52,12 @@ default Fn1 fmap(Fn1 f) { * Contravariantly map over the argument to this function, producing a function that takes the new argument type, * and produces the same result. * - * @param fn the contravariant argument mapping function * @param the new argument type + * @param fn the contravariant argument mapping function * @return a new function from Z (the new argument type) to B (the same result) */ @Override - default Fn1 diMapL(Fn1 fn) { + default Fn1 diMapL(Function fn) { return (Fn1) Profunctor.super.diMapL(fn); } @@ -65,27 +65,27 @@ default Fn1 diMapL(Fn1 fn) { * Covariantly map over the return value of this function, producing a function that takes the same argument, and * produces the new result type. * - * @param fn the covariant result mapping function * @param the new result type + * @param fn the covariant result mapping function * @return a new function from A (the same argument type) to C (the new result type) */ @Override - default Fn1 diMapR(Fn1 fn) { + default Fn1 diMapR(Function fn) { return (Fn1) Profunctor.super.diMapR(fn); } /** * Exercise both diMapL and diMapR over this function in the same invocation. * - * @param lFn the contravariant argument mapping function - * @param rFn the covariant result mapping function * @param the new argument type * @param the new result type + * @param lFn the contravariant argument mapping function + * @param rFn the covariant result mapping function * @return a new function from Z (the new argument type) to C (the new result type) */ @Override - default Fn1 diMap(Fn1 lFn, Fn1 rFn) { - return lFn.andThen(this).andThen(rFn); + default Fn1 diMap(Function lFn, Function rFn) { + return lFn.andThen(this).andThen(rFn)::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 5f9b6677b..4078bfa77 100644 --- a/src/main/java/com/jnape/palatable/lambda/functions/Fn2.java +++ b/src/main/java/com/jnape/palatable/lambda/functions/Fn2.java @@ -2,6 +2,8 @@ import com.jnape.palatable.lambda.adt.hlist.Tuple2; +import java.util.function.BiFunction; + /** * A function taking two arguments. Note that defining Fn2 in terms of Fn1 provides a * reasonable approximation of currying in the form of multiple apply overloads that take different numbers @@ -53,4 +55,14 @@ default Fn2 flip() { default Fn1, C> uncurry() { return (ab) -> apply(ab._1(), ab._2()); } + + /** + * View this Fn2 as a j.u.f.BiFunction. + * + * @return the same logic as a BiFunction + * @see BiFunction + */ + default BiFunction toBiFunction() { + return this::apply; + } } 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 d3d96ccb4..c0a4f2cc7 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,6 +3,8 @@ import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functions.Fn2; +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 @@ -11,13 +13,13 @@ * @param The input Iterable element type * @see Any */ -public final class All implements Fn2, Iterable, Boolean> { +public final class All implements Fn2, Iterable, Boolean> { private All() { } @Override - public Boolean apply(Fn1 predicate, Iterable as) { + public Boolean apply(Function predicate, Iterable as) { for (A a : as) if (!predicate.apply(a)) return false; @@ -29,11 +31,11 @@ public static All all() { return new All<>(); } - public static Fn1, Boolean> all(Fn1 predicate) { + public static Fn1, Boolean> all(Function predicate) { return All.all().apply(predicate); } - public static Boolean all(Fn1 predicate, Iterable as) { + public static Boolean all(Function 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 37a83bbe6..716217884 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 @@ -3,6 +3,8 @@ import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functions.Fn2; +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 @@ -11,13 +13,13 @@ * @param The input Iterable element type * @see All */ -public final class Any implements Fn2, Iterable, Boolean> { +public final class Any implements Fn2, Iterable, Boolean> { private Any() { } @Override - public Boolean apply(Fn1 predicate, Iterable as) { + public Boolean apply(Function predicate, Iterable as) { for (A a : as) if (predicate.apply(a)) return true; @@ -29,11 +31,11 @@ public static Any any() { return new Any<>(); } - public static Fn1, Boolean> any(Fn1 predicate) { + public static Fn1, Boolean> any(Function predicate) { return Any.any().apply(predicate); } - public static Boolean any(Fn1 predicate, Iterable as) { + public static Boolean any(Function predicate, Iterable as) { return Any.any(predicate).apply(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 59be5363e..ceabf8241 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,6 +4,8 @@ import com.jnape.palatable.lambda.functions.Fn2; import com.jnape.palatable.lambda.iterators.PredicatedDroppingIterator; +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. @@ -14,13 +16,13 @@ * @see TakeWhile */ -public final class DropWhile implements Fn2, Iterable, Iterable> { +public final class DropWhile implements Fn2, Iterable, Iterable> { private DropWhile() { } @Override - public Iterable apply(Fn1 predicate, Iterable as) { + public Iterable apply(Function predicate, Iterable as) { return () -> new PredicatedDroppingIterator<>(predicate, as.iterator()); } @@ -28,11 +30,11 @@ public static DropWhile dropWhile() { return new DropWhile<>(); } - public static Fn1, Iterable> dropWhile(Fn1 predicate) { + public static Fn1, Iterable> dropWhile(Function predicate) { return DropWhile.dropWhile().apply(predicate); } - public static Iterable dropWhile(Fn1 predicate, Iterable as) { + public static Iterable dropWhile(Function 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 2b6d7c610..eb0159883 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,6 +4,8 @@ import com.jnape.palatable.lambda.functions.Fn2; import com.jnape.palatable.lambda.iterators.FilteringIterator; +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. @@ -12,13 +14,13 @@ * @see TakeWhile * @see DropWhile */ -public final class Filter implements Fn2, Iterable, Iterable> { +public final class Filter implements Fn2, Iterable, Iterable> { private Filter() { } @Override - public Iterable apply(Fn1 predicate, Iterable as) { + public Iterable apply(Function predicate, Iterable as) { return () -> new FilteringIterator<>(predicate, as.iterator()); } @@ -26,11 +28,11 @@ public static Filter filter() { return new Filter<>(); } - public static Fn1, Iterable> filter(Fn1 predicate) { + public static Fn1, Iterable> filter(Function predicate) { return Filter.filter().apply(predicate); } - public static Iterable filter(Fn1 predicate, Iterable as) { + public static Iterable filter(Function predicate, Iterable as) { return Filter.filter(predicate).apply(as); } } 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 8a7209567..afc132cd8 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 @@ -2,11 +2,12 @@ import com.jnape.palatable.lambda.functions.Fn1; import com.jnape.palatable.lambda.functions.Fn2; -import com.jnape.palatable.lambda.iterators.UnfoldingIterator; import java.util.Optional; +import java.util.function.Function; 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 @@ -15,25 +16,25 @@ * * @param The Iterable element type */ -public final class Iterate implements Fn2, A, Iterable> { +public final class Iterate implements Fn2, A, Iterable> { private Iterate() { } @Override - public Iterable apply(Fn1 fn, A seed) { - return () -> new UnfoldingIterator<>(a -> Optional.of(tuple(a, fn.apply(a))), seed); + public Iterable apply(Function fn, A seed) { + return unfoldr(a -> Optional.of(tuple(a, fn.apply(a))), seed); } public static Iterate iterate() { return new Iterate<>(); } - public static Fn1> iterate(Fn1 fn) { + public static Fn1> iterate(Function fn) { return Iterate.iterate().apply(fn); } - public static Iterable iterate(Fn1 fn, A seed) { + public static Iterable iterate(Function fn, A seed) { return Iterate.iterate(fn).apply(seed); } } 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 3aecce3a5..9805d54af 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,6 +4,8 @@ import com.jnape.palatable.lambda.functions.Fn2; import com.jnape.palatable.lambda.iterators.MappingIterator; +import java.util.function.Function; + /** * Lazily apply a function to each element in an Iterable, producing an Iterable of the mapped * results. @@ -11,13 +13,13 @@ * @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 Map() { } @Override - public Iterable apply(Fn1 fn, Iterable as) { + public Iterable apply(Function fn, Iterable as) { return () -> new MappingIterator<>(fn, as.iterator()); } @@ -25,11 +27,11 @@ public static Map map() { return new Map<>(); } - public static Fn1, Iterable> map(Fn1 fn) { + public static Fn1, Iterable> map(Function fn) { return Map.map().apply(fn); } - public static Iterable map(Fn1 fn, Iterable as) { + public static Iterable map(Function 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 index a7292ad93..f2895b906 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 @@ -3,34 +3,36 @@ 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 Fn2, producing a Fn1 that takes the remaining - * argument. This is isomorphic to calling {@link Fn2#apply(Object)}. + * 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> { +public final class Partial2 implements Fn2, A, Fn1> { private Partial2() { } @Override - public Fn1 apply(Fn2 fn, A a) { - return fn.apply(a); + public Fn1 apply(BiFunction fn, A a) { + return b -> fn.apply(a, b); } - public static Partial2, A, Fn1> partial2() { + public static Partial2, A, Fn1> partial2() { return new Partial2<>(); } - public static Fn1> partial2(Fn2 fn) { - return Partial2.partial2().apply(new Partial2<>(), fn); + public static Fn1> partial2(BiFunction fn) { + return Partial2.partial2().apply(new Partial2().toBiFunction(), fn); } - public static Fn1 partial2(Fn2 fn, A a) { + 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/ReduceLeft.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn2/ReduceLeft.java index b493cf5db..e8f595576 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 @@ -5,11 +5,12 @@ import java.util.Iterator; import java.util.Optional; +import java.util.function.BiFunction; import static com.jnape.palatable.lambda.functions.builtin.fn3.FoldLeft.foldLeft; /** - * Given an Iterable of As and a {@link Fn2}<A, A, A>, iteratively + * Given an Iterable of As and a {@link BiFunction}<A, A, A>, iteratively * accumulate over the Iterable, returning an Optional<A> (if the Iterable * is empty, the result is Optional.empty(); otherwise, the result is wrapped in * Optional.of(). For this reason, null accumulation results are considered erroneous and will @@ -22,13 +23,13 @@ * @see ReduceRight * @see com.jnape.palatable.lambda.functions.builtin.fn3.FoldLeft */ -public final class ReduceLeft implements Fn2, Iterable, Optional> { +public final class ReduceLeft implements Fn2, Iterable, Optional> { private ReduceLeft() { } @Override - public Optional apply(Fn2 fn, Iterable as) { + public Optional apply(BiFunction fn, Iterable as) { Iterator iterator = as.iterator(); if (!iterator.hasNext()) return Optional.empty(); @@ -40,11 +41,11 @@ public static ReduceLeft reduceLeft() { return new ReduceLeft<>(); } - public static Fn1, Optional> reduceLeft(Fn2 fn) { + public static Fn1, Optional> reduceLeft(BiFunction fn) { return ReduceLeft.reduceLeft().apply(fn); } - public static Optional reduceLeft(Fn2 fn, Iterable as) { + public static Optional reduceLeft(BiFunction 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 1a49359cf..b12efe118 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 @@ -4,12 +4,13 @@ import com.jnape.palatable.lambda.functions.Fn2; import java.util.Optional; +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 Iterable of As and a {@link Fn2}<A, A, A>, iteratively + * Given an Iterable of As and a {@link BiFunction}<A, A, A>, iteratively * accumulate over the Iterable, returning an Optional<A> (if the Iterable * is empty, the result is Optional.empty(); otherwise, the result is wrapped in * Optional.of(). For this reason, null accumulation results are considered erroneous and will @@ -22,25 +23,25 @@ * @see ReduceLeft * @see com.jnape.palatable.lambda.functions.builtin.fn3.FoldRight */ -public final class ReduceRight implements Fn2, Iterable, Optional> { +public final class ReduceRight implements Fn2, Iterable, Optional> { private ReduceRight() { } @Override - public final Optional apply(Fn2 fn, Iterable as) { - return reduceLeft(fn.flip(), reverse(as)); + public final Optional apply(BiFunction fn, Iterable as) { + return reduceLeft((b, a) -> fn.apply(a, b), reverse(as)); } public static ReduceRight reduceRight() { return new ReduceRight<>(); } - public static Fn1, Optional> reduceRight(Fn2 fn) { + public static Fn1, Optional> reduceRight(BiFunction fn) { return ReduceRight.reduceRight().apply(fn); } - public static Optional reduceRight(Fn2 fn, Iterable as) { + public static Optional reduceRight(BiFunction fn, Iterable as) { return ReduceRight.reduceRight(fn).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 8cec722e5..595e5112b 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,6 +4,8 @@ import com.jnape.palatable.lambda.functions.Fn2; import com.jnape.palatable.lambda.iterators.PredicatedTakingIterator; +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. @@ -13,13 +15,13 @@ * @see Filter * @see DropWhile */ -public final class TakeWhile implements Fn2, Iterable, Iterable> { +public final class TakeWhile implements Fn2, Iterable, Iterable> { private TakeWhile() { } @Override - public Iterable apply(Fn1 predicate, Iterable as) { + public Iterable apply(Function predicate, Iterable as) { return () -> new PredicatedTakingIterator<>(predicate, as.iterator()); } @@ -27,12 +29,11 @@ public static TakeWhile takeWhile() { return new TakeWhile<>(); } - public static Fn1, Iterable> takeWhile( - Fn1 predicate) { + public static Fn1, Iterable> takeWhile(Function predicate) { return TakeWhile.takeWhile().apply(predicate); } - public static Iterable takeWhile(Fn1 predicate, Iterable as) { + public static Iterable takeWhile(Function predicate, Iterable as) { return TakeWhile.takeWhile(predicate).apply(as); } } 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 6befaf292..3fc3cb2b6 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,6 +6,7 @@ import com.jnape.palatable.lambda.iterators.UnfoldingIterator; import java.util.Optional; +import java.util.function.Function; /** * Given an initial seed value and a function that takes the seed type and produces an Optional<{@link @@ -28,13 +29,13 @@ * @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 Unfoldr() { } @Override - public Iterable apply(Fn1>> fn, B b) { + public Iterable apply(Function>> fn, B b) { return () -> new UnfoldingIterator<>(fn, b); } @@ -42,11 +43,11 @@ public static Unfoldr unfoldr() { return new Unfoldr<>(); } - public static Fn1> unfoldr(Fn1>> fn) { + public static Fn1> unfoldr(Function>> fn) { return Unfoldr.unfoldr().apply(fn); } - public static Iterable unfoldr(Fn1>> fn, B b) { + public static Iterable unfoldr(Function>> 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 1cc8838ca..b9ae36cf6 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,7 +4,6 @@ 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; /** @@ -23,7 +22,7 @@ private Zip() { @Override public Iterable> apply(Iterable as, Iterable bs) { - return zipWith(tupler(), as, bs); + return zipWith(Tupler2.tupler().toBiFunction(), as, bs); } public static Zip zip() { 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 97f5a658c..a64e099ae 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,14 @@ 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 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). + * 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. + * 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). *

* For more information, read about Catamorphisms. @@ -21,29 +23,29 @@ * @param The accumulation type * @see FoldLeft */ -public final class FoldRight implements Fn3, B, Iterable, B> { +public final class FoldRight implements Fn3, B, Iterable, B> { private FoldRight() { } @Override - public B apply(Fn2 fn, B acc, Iterable as) { - return foldLeft(fn.flip(), acc, reverse(as)); + public B apply(BiFunction fn, B acc, Iterable as) { + return foldLeft((b, a) -> fn.apply(a, b), acc, reverse(as)); } public static FoldRight foldRight() { return new FoldRight<>(); } - public static Fn2, B> foldRight(Fn2 fn) { + public static Fn2, B> foldRight(BiFunction fn) { return FoldRight.foldRight().apply(fn); } - public static Fn1, B> foldRight(Fn2 fn, B acc) { + public static Fn1, B> foldRight(BiFunction fn, B acc) { return FoldRight.foldRight(fn).apply(acc); } - public static B foldRight(Fn2 fn, B acc, Iterable as) { + public static B foldRight(BiFunction fn, B acc, Iterable as) { return FoldRight.foldRight(fn, acc).apply(as); } } 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 84a513223..5dcb2a309 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,24 +5,26 @@ import com.jnape.palatable.lambda.functions.Fn3; import com.jnape.palatable.lambda.iterators.ScanningIterator; +import java.util.function.BiFunction; + /** - * 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). + * 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). * * @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 ScanLeft() { } @Override - public Iterable apply(Fn2 fn, B b, Iterable as) { + public Iterable apply(BiFunction fn, B b, Iterable as) { return () -> new ScanningIterator<>(fn, b, as.iterator()); } @@ -30,15 +32,15 @@ public static ScanLeft scanLeft() { return new ScanLeft<>(); } - public static Fn2, Iterable> scanLeft(Fn2 fn) { + public static Fn2, Iterable> scanLeft(BiFunction fn) { return ScanLeft.scanLeft().apply(fn); } - public static Fn1, Iterable> scanLeft(Fn2 fn, B b) { + public static Fn1, Iterable> scanLeft(BiFunction fn, B b) { return ScanLeft.scanLeft(fn).apply(b); } - public static Iterable scanLeft(Fn2 fn, B b, Iterable as) { + public static Iterable scanLeft(BiFunction 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/ZipWith.java b/src/main/java/com/jnape/palatable/lambda/functions/builtin/fn3/ZipWith.java index eb5ea480b..5692295f8 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 @@ -5,6 +5,8 @@ import com.jnape.palatable.lambda.functions.Fn3; import com.jnape.palatable.lambda.iterators.ZippingIterator; +import java.util.function.BiFunction; + /** * Zip together two Iterables by applying a zipping function to the successive elements of each * Iterable until one of them runs out of elements. Returns an Iterable containing the @@ -15,13 +17,13 @@ * @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 ZipWith() { } @Override - public Iterable apply(Fn2 zipper, Iterable as, Iterable bs) { + public Iterable apply(BiFunction zipper, Iterable as, Iterable bs) { return () -> new ZippingIterator<>(zipper, as.iterator(), bs.iterator()); } @@ -30,16 +32,16 @@ public static ZipWith zipWith() { } public static Fn2, Iterable, Iterable> zipWith( - Fn2 zipper) { + BiFunction zipper) { return ZipWith.zipWith().apply(zipper); } - public static Fn1, Iterable> zipWith(Fn2 zipper, + public static Fn1, Iterable> zipWith(BiFunction zipper, Iterable as) { return ZipWith.zipWith(zipper).apply(as); } - public static Iterable zipWith(Fn2 zipper, Iterable as, + public static Iterable zipWith(BiFunction zipper, Iterable as, Iterable bs) { return ZipWith.zipWith(zipper, as).apply(bs); } 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 f9c2037f4..811fcf283 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 @@ -38,7 +38,7 @@ default Predicate compose(Function before) { */ @Override @SuppressWarnings("unchecked") - default Predicate diMapL(Fn1 fn) { + default Predicate diMapL(Function fn) { return Fn1.super.diMapL(fn)::apply; } 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 906c20a8c..496c97021 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 com.jnape.palatable.lambda.functions.Fn1; +import java.util.function.Function; import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id; @@ -21,11 +21,11 @@ public interface Bifunctor { /** * Covariantly map over the left parameter. * - * @param fn the mapping function * @param the new left parameter type + * @param fn the mapping function * @return a bifunctor over C (the new left parameter) and B (the same right parameter) */ - default Bifunctor biMapL(Fn1 fn) { + default Bifunctor biMapL(Function fn) { return biMap(fn, id()); } @@ -33,11 +33,11 @@ default Bifunctor biMapL(Fn1 fn) { * Covariantly map over the right parameter. For all bifunctors that are also functors, it should hold that * biMapR(f) == fmap(f). * - * @param fn the mapping function * @param the new right parameter type + * @param fn the mapping function * @return a bifunctor over A (the same left parameter) and C (the new right parameter) */ - default Bifunctor biMapR(Fn1 fn) { + default Bifunctor biMapR(Function fn) { return biMap(id(), fn); } @@ -45,11 +45,11 @@ default Bifunctor biMapR(Fn1 fn) { * Dually map covariantly over both the left and right parameters. This is isomorphic to * biMapL(lFn).biMapR(rFn). * - * @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 + * @param lFn the left parameter mapping function + * @param rFn the right parameter mapping function * @return a bifunctor over Z (the new left parameter type) and C (the new right parameter type) */ - Bifunctor biMap(Fn1 lFn, Fn1 rFn); + Bifunctor biMap(Function lFn, Function rFn); } 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 2d600d433..ef9b3b308 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/Functor.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/Functor.java @@ -2,6 +2,8 @@ import com.jnape.palatable.lambda.functions.Fn1; +import java.util.function.Function; + /** * 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 @@ -23,9 +25,9 @@ public interface Functor { * Covariantly transmute this functor's parameter using the given mapping function. Generally this method is * specialized to return an instance of the class implementing Functor. * - * @param fn the mapping function * @param the new parameter type + * @param fn the mapping function * @return a functor over B (the new parameter type) */ - Functor fmap(Fn1 fn); + Functor fmap(Function 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 aae917e55..db8562172 100644 --- a/src/main/java/com/jnape/palatable/lambda/functor/Profunctor.java +++ b/src/main/java/com/jnape/palatable/lambda/functor/Profunctor.java @@ -2,6 +2,8 @@ import com.jnape.palatable.lambda.functions.Fn1; +import java.util.function.Function; + import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id; /** @@ -22,11 +24,11 @@ public interface Profunctor { /** * Contravariantly map over the left parameter. * - * @param fn the mapping function * @param the new left parameter type + * @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(Fn1 fn) { + default Profunctor diMapL(Function fn) { return diMap(fn, id()); } @@ -34,11 +36,11 @@ default Profunctor diMapL(Fn1 fn) { * Covariantly map over the right parameter. For all profunctors that are also functors, it should hold that * diMapR(f) == fmap(f). * - * @param fn the mapping function * @param the new right parameter type + * @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(Fn1 fn) { + default Profunctor diMapR(Function fn) { return diMap(id(), fn); } @@ -46,11 +48,11 @@ default Profunctor diMapR(Fn1 fn) { * Dually map contravariantly over the left parameter and covariantly over the right parameter. This is isomorphic * to diMapL(lFn).diMapR(rFn). * - * @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 + * @param lFn the left parameter mapping function + * @param rFn the right parameter mapping function * @return a profunctor over Z (the new left parameter type) and C (the new right parameter tyep) */ - Profunctor diMap(Fn1 lFn, Fn1 rFn); + Profunctor diMap(Function lFn, Function rFn); } diff --git a/src/main/java/com/jnape/palatable/lambda/iterators/FilteringIterator.java b/src/main/java/com/jnape/palatable/lambda/iterators/FilteringIterator.java index 093868e5e..b95f39eda 100644 --- a/src/main/java/com/jnape/palatable/lambda/iterators/FilteringIterator.java +++ b/src/main/java/com/jnape/palatable/lambda/iterators/FilteringIterator.java @@ -1,16 +1,15 @@ package com.jnape.palatable.lambda.iterators; -import com.jnape.palatable.lambda.functions.Fn1; - import java.util.Iterator; import java.util.NoSuchElementException; +import java.util.function.Function; public class FilteringIterator extends ImmutableIterator { - private final Fn1 predicate; - private final RewindableIterator rewindableIterator; + private final Function predicate; + private final RewindableIterator rewindableIterator; - public FilteringIterator(Fn1 predicate, Iterator iterator) { + public FilteringIterator(Function predicate, Iterator iterator) { this.predicate = predicate; rewindableIterator = new RewindableIterator<>(iterator); } diff --git a/src/main/java/com/jnape/palatable/lambda/iterators/MappingIterator.java b/src/main/java/com/jnape/palatable/lambda/iterators/MappingIterator.java index f950ee386..81b46c027 100644 --- a/src/main/java/com/jnape/palatable/lambda/iterators/MappingIterator.java +++ b/src/main/java/com/jnape/palatable/lambda/iterators/MappingIterator.java @@ -1,15 +1,14 @@ package com.jnape.palatable.lambda.iterators; -import com.jnape.palatable.lambda.functions.Fn1; - import java.util.Iterator; +import java.util.function.Function; public class MappingIterator extends ImmutableIterator { - private final Fn1 function; - private final Iterator iterator; + private final Function function; + private final Iterator iterator; - public MappingIterator(Fn1 function, Iterator iterator) { + public MappingIterator(Function function, Iterator iterator) { this.function = function; this.iterator = iterator; } diff --git a/src/main/java/com/jnape/palatable/lambda/iterators/PredicatedDroppingIterator.java b/src/main/java/com/jnape/palatable/lambda/iterators/PredicatedDroppingIterator.java index 02deacbf8..c7f8f279e 100644 --- a/src/main/java/com/jnape/palatable/lambda/iterators/PredicatedDroppingIterator.java +++ b/src/main/java/com/jnape/palatable/lambda/iterators/PredicatedDroppingIterator.java @@ -1,16 +1,15 @@ package com.jnape.palatable.lambda.iterators; -import com.jnape.palatable.lambda.functions.Fn1; - import java.util.Iterator; import java.util.NoSuchElementException; +import java.util.function.Function; public class PredicatedDroppingIterator extends ImmutableIterator { - private final Fn1 predicate; - private final RewindableIterator rewindableIterator; - private boolean finishedDropping; + private final Function predicate; + private final RewindableIterator rewindableIterator; + private boolean finishedDropping; - public PredicatedDroppingIterator(Fn1 predicate, Iterator asIterator) { + public PredicatedDroppingIterator(Function predicate, Iterator asIterator) { this.predicate = predicate; rewindableIterator = new RewindableIterator<>(asIterator); finishedDropping = false; diff --git a/src/main/java/com/jnape/palatable/lambda/iterators/PredicatedTakingIterator.java b/src/main/java/com/jnape/palatable/lambda/iterators/PredicatedTakingIterator.java index 3fbcd5e17..c269ad72b 100644 --- a/src/main/java/com/jnape/palatable/lambda/iterators/PredicatedTakingIterator.java +++ b/src/main/java/com/jnape/palatable/lambda/iterators/PredicatedTakingIterator.java @@ -1,16 +1,15 @@ package com.jnape.palatable.lambda.iterators; -import com.jnape.palatable.lambda.functions.Fn1; - import java.util.Iterator; import java.util.NoSuchElementException; +import java.util.function.Function; public class PredicatedTakingIterator extends ImmutableIterator { - private final Fn1 predicate; - private final RewindableIterator rewindableIterator; - private boolean stillTaking; + private final Function predicate; + private final RewindableIterator rewindableIterator; + private boolean stillTaking; - public PredicatedTakingIterator(Fn1 predicate, + public PredicatedTakingIterator(Function predicate, Iterator asIterator) { this.predicate = predicate; rewindableIterator = new RewindableIterator<>(asIterator); diff --git a/src/main/java/com/jnape/palatable/lambda/iterators/ScanningIterator.java b/src/main/java/com/jnape/palatable/lambda/iterators/ScanningIterator.java index 56e693629..aaaa43fb7 100644 --- a/src/main/java/com/jnape/palatable/lambda/iterators/ScanningIterator.java +++ b/src/main/java/com/jnape/palatable/lambda/iterators/ScanningIterator.java @@ -1,17 +1,16 @@ package com.jnape.palatable.lambda.iterators; -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 Fn2 scanner; - private final Iterator asIterator; - private B b; + private final BiFunction scanner; + private final Iterator asIterator; + private B b; - public ScanningIterator(Fn2 scanner, B b, + public ScanningIterator(BiFunction scanner, B b, Iterator asIterator) { this.scanner = scanner; this.b = b; diff --git a/src/main/java/com/jnape/palatable/lambda/iterators/UnfoldingIterator.java b/src/main/java/com/jnape/palatable/lambda/iterators/UnfoldingIterator.java index 896ca19dd..f329d146b 100644 --- a/src/main/java/com/jnape/palatable/lambda/iterators/UnfoldingIterator.java +++ b/src/main/java/com/jnape/palatable/lambda/iterators/UnfoldingIterator.java @@ -1,16 +1,16 @@ package com.jnape.palatable.lambda.iterators; import com.jnape.palatable.lambda.adt.hlist.Tuple2; -import com.jnape.palatable.lambda.functions.Fn1; import java.util.NoSuchElementException; import java.util.Optional; +import java.util.function.Function; public class UnfoldingIterator extends ImmutableIterator { - private final Fn1>> function; - private Optional> optionalAcc; + private final Function>> function; + private Optional> optionalAcc; - public UnfoldingIterator(Fn1>> function, B b) { + public UnfoldingIterator(Function>> function, B b) { this.function = function; optionalAcc = function.apply(b); } @@ -21,6 +21,7 @@ public boolean hasNext() { } @Override + @SuppressWarnings("OptionalGetWithoutIsPresent") public A next() { if (!hasNext()) throw new NoSuchElementException(); diff --git a/src/main/java/com/jnape/palatable/lambda/iterators/ZippingIterator.java b/src/main/java/com/jnape/palatable/lambda/iterators/ZippingIterator.java index 16d05c146..0372e6fff 100644 --- a/src/main/java/com/jnape/palatable/lambda/iterators/ZippingIterator.java +++ b/src/main/java/com/jnape/palatable/lambda/iterators/ZippingIterator.java @@ -1,15 +1,14 @@ package com.jnape.palatable.lambda.iterators; -import com.jnape.palatable.lambda.functions.Fn2; - import java.util.Iterator; +import java.util.function.BiFunction; public class ZippingIterator extends ImmutableIterator { - private final Fn2 zipper; - private final Iterator asIterator; - private final Iterator bsIterator; + private final BiFunction zipper; + private final Iterator asIterator; + private final Iterator bsIterator; - public ZippingIterator(Fn2 zipper, Iterator asIterator, + public ZippingIterator(BiFunction zipper, Iterator asIterator, Iterator bsIterator) { this.asIterator = asIterator; this.bsIterator = bsIterator; 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 21cd82655..634706372 100644 --- a/src/test/java/com/jnape/palatable/lambda/adt/EitherTest.java +++ b/src/test/java/com/jnape/palatable/lambda/adt/EitherTest.java @@ -1,6 +1,5 @@ package com.jnape.palatable.lambda.adt; -import com.jnape.palatable.lambda.functions.Fn2; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -8,6 +7,7 @@ import java.util.Optional; 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.fromOptional; import static com.jnape.palatable.lambda.adt.Either.left; @@ -98,8 +98,8 @@ public void mergeDuallyLiftsAndCombinesBiasingLeft() { Either left2 = left("bar"); Either right2 = right(2); - Fn2 concat = String::concat; - Fn2 add = (r1, r2) -> r1 + r2; + BiFunction concat = String::concat; + BiFunction add = (r1, r2) -> r1 + r2; assertThat(left1.merge(concat, add, left2), is(left("foobar"))); assertThat(left1.merge(concat, add, right2), is(left1)); 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 12d62c4e2..49d7e9809 100644 --- a/src/test/java/com/jnape/palatable/lambda/functions/Fn2Test.java +++ b/src/test/java/com/jnape/palatable/lambda/functions/Fn2Test.java @@ -3,8 +3,11 @@ import com.jnape.palatable.lambda.functions.builtin.fn1.Id; import org.junit.Test; +import java.util.function.BiFunction; + import static com.jnape.palatable.lambda.adt.hlist.HList.tuple; import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; public class Fn2Test { @@ -44,4 +47,10 @@ public void profunctorProperties() { is("true") ); } + + @Test + public void toBiFunction() { + BiFunction biFunction = CHECK_LENGTH.toBiFunction(); + assertEquals(true, biFunction.apply("abc", 3)); + } } 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 e95465991..d746b0fc1 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,6 +7,8 @@ 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; @@ -17,7 +19,7 @@ @RunWith(Traits.class) public class AllTest { - private static final Fn1 EVEN = x -> x.doubleValue() % 2 == 0; + private static final Function EVEN = x -> x.doubleValue() % 2 == 0; @TestTraits({EmptyIterableSupport.class}) public Fn1, Boolean> createTestSubject() { 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 8c5485d8c..aa8f8a118 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,6 +7,8 @@ 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; @@ -17,7 +19,7 @@ @RunWith(Traits.class) public class AnyTest { - public static final Fn1 EVEN = x -> x % 2 == 0; + public static final Function 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/Partial2Test.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn2/Partial2Test.java index 1e3a05a9a..81598f331 100644 --- 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 @@ -1,8 +1,9 @@ package com.jnape.palatable.lambda.functions.builtin.fn2; -import com.jnape.palatable.lambda.functions.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; @@ -11,8 +12,7 @@ public class Partial2Test { @Test public void partiallyAppliesFunction() { - Fn2 subtract = (minuend, subtrahend) -> minuend - subtrahend; - + 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/fn3/ZipWithTest.java b/src/test/java/com/jnape/palatable/lambda/functions/builtin/fn3/ZipWithTest.java index 0fcc085ad..ee1408417 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 @@ -2,7 +2,6 @@ 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.traitor.annotations.TestTraits; import com.jnape.palatable.traitor.runners.Traits; import org.junit.Test; @@ -11,6 +10,8 @@ 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; @@ -31,7 +32,7 @@ public void zipsTwoIterablesTogetherWithFunction() { Iterable oneThroughFive = asList(1, 2, 3, 4, 5); Iterable sixThroughTen = asList(6, 7, 8, 9, 10); - Fn2 add = (a, b) -> a + b; + BiFunction add = (a, b) -> a + b; Iterable sums = ZipWith.zipWith(add, oneThroughFive, sixThroughTen); assertThat(sums, iterates(7, 9, 11, 13, 15)); 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 6d78c167d..afc3c0a8e 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); assertThat(rightInvocation.get(), is(id())); @@ -22,7 +22,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); 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 63011de85..5e552f7e0 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); assertThat(rightInvocation.get(), is(id())); @@ -22,7 +22,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); assertThat(leftInvocation.get(), is(id())); diff --git a/src/test/java/com/jnape/palatable/lambda/iterators/ScanningIteratorTest.java b/src/test/java/com/jnape/palatable/lambda/iterators/ScanningIteratorTest.java index b082925ab..387bc965e 100644 --- a/src/test/java/com/jnape/palatable/lambda/iterators/ScanningIteratorTest.java +++ b/src/test/java/com/jnape/palatable/lambda/iterators/ScanningIteratorTest.java @@ -1,9 +1,9 @@ package com.jnape.palatable.lambda.iterators; -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 Fn2 ADD = (x, y) -> x + y; + public static final BiFunction ADD = (x, y) -> x + y; @Test public void hasNextAtLeastForB() { diff --git a/src/test/java/com/jnape/palatable/lambda/iterators/ZippingIteratorTest.java b/src/test/java/com/jnape/palatable/lambda/iterators/ZippingIteratorTest.java index e80c53acd..561eb2534 100644 --- a/src/test/java/com/jnape/palatable/lambda/iterators/ZippingIteratorTest.java +++ b/src/test/java/com/jnape/palatable/lambda/iterators/ZippingIteratorTest.java @@ -1,6 +1,5 @@ package com.jnape.palatable.lambda.iterators; -import com.jnape.palatable.lambda.functions.Fn2; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -8,6 +7,7 @@ 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 Fn2 zipper; - @Mock private Iterator as; - @Mock private Iterator bs; + @Mock private BiFunction zipper; + @Mock private Iterator as; + @Mock private Iterator bs; private ZippingIterator zippingIterator; diff --git a/src/test/java/testsupport/applicatives/InvocationRecordingBifunctor.java b/src/test/java/testsupport/applicatives/InvocationRecordingBifunctor.java index 51b2fa24c..2ef23f622 100644 --- a/src/test/java/testsupport/applicatives/InvocationRecordingBifunctor.java +++ b/src/test/java/testsupport/applicatives/InvocationRecordingBifunctor.java @@ -1,24 +1,24 @@ 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 Bifunctor biMap(Fn1 lFn, - Fn1 rFn) { + public Bifunctor biMap(Function lFn, + Function rFn) { leftFn.set(lFn); rightFn.set(rFn); return (Bifunctor) this; diff --git a/src/test/java/testsupport/applicatives/InvocationRecordingProfunctor.java b/src/test/java/testsupport/applicatives/InvocationRecordingProfunctor.java index a5de7891b..dadcec960 100644 --- a/src/test/java/testsupport/applicatives/InvocationRecordingProfunctor.java +++ b/src/test/java/testsupport/applicatives/InvocationRecordingProfunctor.java @@ -1,23 +1,23 @@ 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 Profunctor diMap(Fn1 lFn, Fn1 rFn) { + public Profunctor diMap(Function lFn, Function rFn) { leftFn.set(lFn); rightFn.set(rFn); return (Profunctor) this; diff --git a/src/test/java/testsupport/functions/ExplainFold.java b/src/test/java/testsupport/functions/ExplainFold.java index d59a2378b..a168674e3 100644 --- a/src/test/java/testsupport/functions/ExplainFold.java +++ b/src/test/java/testsupport/functions/ExplainFold.java @@ -1,12 +1,12 @@ 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 Fn2 explainFold() { + public static BiFunction explainFold() { return (acc, x) -> format("(%s + %s)", acc, x); } } From 85d81d56e6e05a325d86226d73088307b43f9ba9 Mon Sep 17 00:00:00 2001 From: John Napier Date: Sun, 7 Aug 2016 15:10:26 -0500 Subject: [PATCH 7/8] Fixing indentation in TOC --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 52c88d502..aa144b856 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,11 @@ Functional patterns for Java 8 - [Background](#background) - [Installation](#installation) - [Examples](#examples) - - [ADTs](#adts) - - [HLists](#hlists) - - [Tuples](#tuples) - - [HMaps](#hmaps) - - [Either](#either) + - [ADTs](#adts) + - [HLists](#hlists) + - [Tuples](#tuples) + - [HMaps](#hmaps) + - [Either](#either) - [Notes](#notes) - [License](#license) From 1714f32ca702713d52466ced64e7d1cfbf1a1b7b Mon Sep 17 00:00:00 2001 From: jnape Date: Mon, 8 Aug 2016 00:58:58 -0500 Subject: [PATCH 8/8] [maven-release-plugin] prepare release lambda-1.4 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7a416f475..b192e8e58 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ lambda - 1.4-SNAPSHOT + 1.4 jar Lambda

* For more information, read about Catamorphisms. @@ -18,13 +20,13 @@ * @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 FoldLeft() { } @Override - public B apply(Fn2 fn, B acc, Iterable as) { + public B apply(BiFunction fn, B acc, Iterable as) { B accumulation = acc; for (A a : as) accumulation = fn.apply(accumulation, a); @@ -35,15 +37,15 @@ public static FoldLeft foldLeft() { return new FoldLeft<>(); } - public static Fn2, B> foldLeft(Fn2 fn) { + public static Fn2, B> foldLeft(BiFunction fn) { return FoldLeft.foldLeft().apply(fn); } - public static Fn1, B> foldLeft(Fn2 fn, B acc) { + public static Fn1, B> foldLeft(BiFunction fn, B acc) { return FoldLeft.foldLeft(fn).apply(acc); } - public static B foldLeft(Fn2 fn, B acc, Iterable as) { + public static B foldLeft(BiFunction 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 c5717a50d..545ee5eb6 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 @@ -4,15 +4,17 @@ import com.jnape.palatable.lambda.functions.Fn2; import com.jnape.palatable.lambda.functions.Fn3; +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; /** - * Given an Iterable of As, a starting value B, and a {@link Fn2}<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 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). *