diff --git a/README.md b/README.md
index 7d84c6295..2e6aa98db 100644
--- a/README.md
+++ b/README.md
@@ -672,24 +672,15 @@ There are three functions that lambda provides that interface directly with lens
Lenses can be easily created. Consider the following `Person` class:
```Java
-public final class Person {
- private final int age;
+public record Person(int age) {
- public Person(int age) {
- this.age = age;
- }
-
- public int getAge() {
- return age;
- }
+ public Person setAge(int age) {
+ return new Person(age);
+ }
- public Person setAge(int age) {
- return new Person(age);
- }
-
- public Person setAge(LocalDate dob) {
- return setAge((int) YEARS.between(dob, LocalDate.now()));
- }
+ public Person setAge(LocalDate dob) {
+ return setAge((int) YEARS.between(dob, LocalDate.now()));
+ }
}
```
diff --git a/pom.xml b/pom.xml
index bae03b1e3..07e735029 100644
--- a/pom.xml
+++ b/pom.xml
@@ -91,8 +91,8 @@
maven-compiler-plugin
${maven-compiler-plugin.version}
-
- 1.8
+
+ 17
-Xlint:all
-Werror
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 dc5595983..acb463115 100644
--- a/src/main/java/com/jnape/palatable/lambda/adt/Maybe.java
+++ b/src/main/java/com/jnape/palatable/lambda/adt/Maybe.java
@@ -18,7 +18,6 @@
import com.jnape.palatable.lambda.monad.MonadRec;
import com.jnape.palatable.lambda.traversable.Traversable;
-import java.util.Objects;
import java.util.Optional;
import static com.jnape.palatable.lambda.adt.Either.left;
@@ -38,14 +37,12 @@
* @param the optional parameter type
* @see Optional
*/
-public abstract class Maybe implements
+public sealed interface Maybe extends
CoProduct2>,
MonadError>,
MonadRec>,
- Traversable> {
+ Traversable> permits Just, Nothing {
- private Maybe() {
- }
/**
* If the value is present, return it; otherwise, return the value supplied by otherSupplier
.
@@ -53,7 +50,7 @@ private Maybe() {
* @param otherFn0 the supplier for the other value
* @return this value, or the supplied other value
*/
- public final A orElseGet(Fn0 otherFn0) {
+ default A orElseGet(Fn0 otherFn0) {
return match(__ -> otherFn0.apply(), id());
}
@@ -63,7 +60,7 @@ public final A orElseGet(Fn0 otherFn0) {
* @param other the other value
* @return this value, or the other value
*/
- public final A orElse(A other) {
+ default A orElse(A other) {
return orElseGet(() -> other);
}
@@ -76,7 +73,7 @@ public final A orElse(A other) {
* @return the value, if present
* @throws E the throwable, if the value is absent
*/
- public final A orElseThrow(Fn0 extends E> throwableSupplier) throws E {
+ default A orElseThrow(Fn0 extends E> throwableSupplier) throws E {
return orElseGet(fn0(() -> {
throw throwableSupplier.apply();
}));
@@ -89,7 +86,7 @@ public final A orElseThrow(Fn0 extends E> 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(Fn1 super A, ? extends Boolean> predicate) {
+ default Maybe filter(Fn1 super A, ? extends Boolean> predicate) {
return flatMap(a -> predicate.apply(a) ? just(a) : nothing());
}
@@ -97,7 +94,7 @@ public final Maybe filter(Fn1 super A, ? extends Boolean> predicate) {
* {@inheritDoc}
*/
@Override
- public Maybe throwError(Unit unit) {
+ default Maybe throwError(Unit unit) {
return nothing();
}
@@ -105,7 +102,7 @@ public Maybe throwError(Unit unit) {
* {@inheritDoc}
*/
@Override
- public Maybe catchError(Fn1 super Unit, ? extends Monad>> recoveryFn) {
+ default Maybe catchError(Fn1 super Unit, ? extends Monad>> recoveryFn) {
return match(recoveryFn, Maybe::just).coerce();
}
@@ -117,7 +114,7 @@ public Maybe catchError(Fn1 super Unit, ? extends Monad>> recov
* @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(Fn0 lFn0) {
+ default Either toEither(Fn0 lFn0) {
return fmap(Either::right).orElseGet(() -> left(lFn0.apply()));
}
@@ -126,7 +123,7 @@ public final Either toEither(Fn0 lFn0) {
*
* @return the Optional
*/
- public final Optional toOptional() {
+ default Optional toOptional() {
return fmap(Optional::of).orElseGet(Optional::empty);
}
@@ -138,7 +135,7 @@ public final Optional toOptional() {
* @return Just b
*/
@Override
- public final Maybe pure(B b) {
+ default Maybe pure(B b) {
return just(b);
}
@@ -149,7 +146,7 @@ public final Maybe pure(B b) {
* {@link Maybe#nothing}.
*/
@Override
- public final Maybe fmap(Fn1 super A, ? extends B> fn) {
+ default Maybe fmap(Fn1 super A, ? extends B> fn) {
return MonadError.super.fmap(fn).coerce();
}
@@ -157,7 +154,7 @@ public final Maybe fmap(Fn1 super A, ? extends B> fn) {
* {@inheritDoc}
*/
@Override
- public final Maybe zip(Applicative, Maybe>> appFn) {
+ default Maybe zip(Applicative, Maybe>> appFn) {
return MonadError.super.zip(appFn).coerce();
}
@@ -169,7 +166,7 @@ public final Maybe zip(Applicative, Maybe>>
* @return the zipped {@link Maybe}
*/
@Override
- public Lazy> lazyZip(Lazy extends Applicative, Maybe>>> lazyAppFn) {
+ default Lazy> lazyZip(Lazy extends Applicative, Maybe>>> lazyAppFn) {
return match(constantly(lazy(nothing())),
a -> lazyAppFn.fmap(maybeF -> maybeF.fmap(f -> f.apply(a)).coerce()));
}
@@ -178,7 +175,7 @@ public Lazy> lazyZip(Lazy extends Applicative Maybe discardL(Applicative> appB) {
+ default Maybe discardL(Applicative> appB) {
return MonadError.super.discardL(appB).coerce();
}
@@ -186,7 +183,7 @@ public final Maybe discardL(Applicative> appB) {
* {@inheritDoc}
*/
@Override
- public final Maybe discardR(Applicative> appB) {
+ default Maybe discardR(Applicative> appB) {
return MonadError.super.discardR(appB).coerce();
}
@@ -195,7 +192,7 @@ public final Maybe discardR(Applicative> appB) {
*/
@SuppressWarnings("RedundantTypeArguments")
@Override
- public final Maybe flatMap(Fn1 super A, ? extends Monad>> f) {
+ default Maybe flatMap(Fn1 super A, ? extends Monad>> f) {
return match(constantly(nothing()), f.fmap(Monad>::coerce));
}
@@ -203,7 +200,7 @@ public final Maybe flatMap(Fn1 super A, ? extends Monad>> f
* {@inheritDoc}
*/
@Override
- public Maybe trampolineM(Fn1 super A, ? extends MonadRec, Maybe>>> fn) {
+ default Maybe trampolineM(Fn1 super A, ? extends MonadRec, Maybe>>> fn) {
return match(constantly(nothing()), trampoline(a -> fn.apply(a).>>coerce()
.match(constantly(terminate(nothing())),
aOrB -> aOrB.fmap(Maybe::just))));
@@ -213,7 +210,7 @@ public Maybe trampolineM(Fn1 super A, ? extends MonadRec Choice3 diverge() {
+ default Choice3 diverge() {
return match(Choice3::a, Choice3::b);
}
@@ -221,7 +218,7 @@ public Choice3 diverge() {
* {@inheritDoc}
*/
@Override
- public Tuple2, Maybe> project() {
+ default Tuple2, Maybe> project() {
return CoProduct2.super.project().into(HList::tuple);
}
@@ -229,7 +226,7 @@ public Tuple2, Maybe> project() {
* {@inheritDoc}
*/
@Override
- public Choice2 invert() {
+ default Choice2 invert() {
return match(Choice2::b, Choice2::a);
}
@@ -241,13 +238,13 @@ public Choice2 invert() {
* @deprecated in favor of {@link Maybe#match(Fn1, Fn1) matching} into an {@link IO} and explicitly running it
*/
@Deprecated
- public final Maybe peek(Fn1 super A, ? extends IO>> effect) {
+ default Maybe peek(Fn1 super A, ? extends IO>> effect) {
return match(constantly(io(this)), a -> effect.apply(a).fmap(constantly(this))).unsafePerformIO();
}
@Override
@SuppressWarnings("unchecked")
- public final , TravB extends Traversable>,
+ default , TravB extends Traversable>,
AppTrav extends Applicative> AppTrav traverse(Fn1 super A, ? extends Applicative> fn,
Fn1 super TravB, ? extends AppTrav> pure) {
return match(__ -> pure.apply((TravB) Maybe.nothing()), a -> (AppTrav) fn.apply(a).fmap(Maybe::just));
@@ -261,7 +258,7 @@ AppTrav extends Applicative> AppTrav traverse(Fn1 super A, ? exten
* @param the potential right value
* @return "Just" the right value, or nothing
*/
- public static Maybe fromEither(Either, A> either) {
+ static Maybe fromEither(Either, A> either) {
return either.toMaybe();
}
@@ -272,7 +269,7 @@ public static Maybe fromEither(Either, A> either) {
* @param the optional parameter type
* @return the equivalent Maybe instance
*/
- public static Maybe fromOptional(Optional extends A> optional) {
+ static Maybe fromOptional(Optional extends A> optional) {
return optional.map(Maybe::just).orElse(Maybe.nothing());
}
@@ -284,7 +281,7 @@ public static Maybe fromOptional(Optional extends A> optional) {
* @param the value parameter type
* @return "Just" the value, or nothing
*/
- public static Maybe maybe(A a) {
+ static Maybe maybe(A a) {
return a == null ? nothing() : just(a);
}
@@ -297,7 +294,7 @@ public static Maybe maybe(A a) {
* @return "Just" the value
* @throws NullPointerException if a is null
*/
- public static Maybe just(A a) {
+ static Maybe just(A a) {
if (a == null)
throw new NullPointerException();
return new Just<>(a);
@@ -310,7 +307,7 @@ public static Maybe just(A a) {
* @return nothing
*/
@SuppressWarnings("unchecked")
- public static Maybe nothing() {
+ static Maybe nothing() {
return (Maybe) Nothing.INSTANCE;
}
@@ -319,53 +316,22 @@ public static Maybe nothing() {
*
* @return the {@link Pure} instance
*/
- public static Pure> pureMaybe() {
+ static Pure> pureMaybe() {
return Maybe::just;
}
+}
+record Nothing() implements Maybe {
+ static final Nothing> INSTANCE = new Nothing<>();
- private static final class Nothing extends Maybe {
- private static final Nothing> INSTANCE = new Nothing<>();
-
- private Nothing() {
- }
-
- @Override
- public R match(Fn1 super Unit, ? extends R> aFn, Fn1 super A, ? extends R> bFn) {
- return aFn.apply(UNIT);
- }
-
- @Override
- public String toString() {
- return "Nothing";
- }
+ @Override
+ public R match(Fn1 super Unit, ? extends R> aFn, Fn1 super A, ? extends R> bFn) {
+ return aFn.apply(UNIT);
}
+}
- private static final class Just extends Maybe {
-
- private final A a;
-
- private Just(A a) {
- this.a = a;
- }
-
- @Override
- public R match(Fn1 super Unit, ? extends R> aFn, Fn1 super A, ? extends R> bFn) {
- return bFn.apply(a);
- }
-
- @Override
- public boolean equals(Object other) {
- return other instanceof Just && Objects.equals(this.a, ((Just) other).a);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(a);
- }
-
- @Override
- public String toString() {
- return "Just " + a;
- }
+record Just(A a) implements Maybe {
+ @Override
+ public R match(Fn1 super Unit, ? extends R> aFn, Fn1 super A, ? extends R> bFn) {
+ return bFn.apply(a);
}
-}
+}
\ No newline at end of file
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 705e43bad..0dc877fcd 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
@@ -263,8 +263,7 @@ public Tail tail() {
@Override
public final boolean equals(Object other) {
- if (other instanceof HCons) {
- HCons, ?> that = (HCons, ?>) other;
+ if (other instanceof HCons, ?> that) {
return this.head.equals(that.head)
&& this.tail.equals(that.tail);
}
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 62c922ece..db106f410 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
@@ -162,8 +162,7 @@ public Collection