Skip to content
  • Sponsor
  • Notifications You must be signed in to change notification settings
  • Fork 85
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Java 17 #129

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 7 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -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()));
}
}
```

4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -91,8 +91,8 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<source>17</source>
<target>17</target>
<compilerArgs>
<compilerArg>-Xlint:all</compilerArg>
<compilerArg>-Werror</compilerArg>
116 changes: 41 additions & 75 deletions src/main/java/com/jnape/palatable/lambda/adt/Maybe.java
Original file line number Diff line number Diff line change
@@ -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,22 +37,20 @@
* @param <A> the optional parameter type
* @see Optional
*/
public abstract class Maybe<A> implements
public sealed interface Maybe<A> extends
CoProduct2<Unit, A, Maybe<A>>,
MonadError<Unit, A, Maybe<?>>,
MonadRec<A, Maybe<?>>,
Traversable<A, Maybe<?>> {
Traversable<A, Maybe<?>> permits Just, Nothing {

private Maybe() {
}

/**
* If the value is present, return it; otherwise, return the value supplied by <code>otherSupplier</code>.
*
* @param otherFn0 the supplier for the other value
* @return this value, or the supplied other value
*/
public final A orElseGet(Fn0<A> otherFn0) {
default A orElseGet(Fn0<A> otherFn0) {
return match(__ -> otherFn0.apply(), id());
}

@@ -63,7 +60,7 @@ public final A orElseGet(Fn0<A> 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 <E extends Throwable> A orElseThrow(Fn0<? extends E> throwableSupplier) throws E {
default <E extends Throwable> A orElseThrow(Fn0<? extends E> throwableSupplier) throws E {
return orElseGet(fn0(() -> {
throw throwableSupplier.apply();
}));
@@ -89,23 +86,23 @@ public final <E extends Throwable> 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<A> filter(Fn1<? super A, ? extends Boolean> predicate) {
default Maybe<A> filter(Fn1<? super A, ? extends Boolean> predicate) {
return flatMap(a -> predicate.apply(a) ? just(a) : nothing());
}

/**
* {@inheritDoc}
*/
@Override
public Maybe<A> throwError(Unit unit) {
default Maybe<A> throwError(Unit unit) {
return nothing();
}

/**
* {@inheritDoc}
*/
@Override
public Maybe<A> catchError(Fn1<? super Unit, ? extends Monad<A, Maybe<?>>> recoveryFn) {
default Maybe<A> catchError(Fn1<? super Unit, ? extends Monad<A, Maybe<?>>> recoveryFn) {
return match(recoveryFn, Maybe::just).coerce();
}

@@ -117,7 +114,7 @@ public Maybe<A> catchError(Fn1<? super Unit, ? extends Monad<A, Maybe<?>>> 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 <L> Either<L, A> toEither(Fn0<L> lFn0) {
default <L> Either<L, A> toEither(Fn0<L> lFn0) {
return fmap(Either::<L, A>right).orElseGet(() -> left(lFn0.apply()));
}

@@ -126,7 +123,7 @@ public final <L> Either<L, A> toEither(Fn0<L> lFn0) {
*
* @return the Optional
*/
public final Optional<A> toOptional() {
default Optional<A> toOptional() {
return fmap(Optional::of).orElseGet(Optional::empty);
}

@@ -138,7 +135,7 @@ public final Optional<A> toOptional() {
* @return Just b
*/
@Override
public final <B> Maybe<B> pure(B b) {
default <B> Maybe<B> pure(B b) {
return just(b);
}

@@ -149,15 +146,15 @@ public final <B> Maybe<B> pure(B b) {
* {@link Maybe#nothing}.
*/
@Override
public final <B> Maybe<B> fmap(Fn1<? super A, ? extends B> fn) {
default <B> Maybe<B> fmap(Fn1<? super A, ? extends B> fn) {
return MonadError.super.<B>fmap(fn).coerce();
}

/**
* {@inheritDoc}
*/
@Override
public final <B> Maybe<B> zip(Applicative<Fn1<? super A, ? extends B>, Maybe<?>> appFn) {
default <B> Maybe<B> zip(Applicative<Fn1<? super A, ? extends B>, Maybe<?>> appFn) {
return MonadError.super.zip(appFn).coerce();
}

@@ -169,7 +166,7 @@ public final <B> Maybe<B> zip(Applicative<Fn1<? super A, ? extends B>, Maybe<?>>
* @return the zipped {@link Maybe}
*/
@Override
public <B> Lazy<Maybe<B>> lazyZip(Lazy<? extends Applicative<Fn1<? super A, ? extends B>, Maybe<?>>> lazyAppFn) {
default <B> Lazy<Maybe<B>> lazyZip(Lazy<? extends Applicative<Fn1<? super A, ? extends B>, Maybe<?>>> lazyAppFn) {
return match(constantly(lazy(nothing())),
a -> lazyAppFn.fmap(maybeF -> maybeF.<B>fmap(f -> f.apply(a)).coerce()));
}
@@ -178,15 +175,15 @@ public <B> Lazy<Maybe<B>> lazyZip(Lazy<? extends Applicative<Fn1<? super A, ? ex
* {@inheritDoc}
*/
@Override
public final <B> Maybe<B> discardL(Applicative<B, Maybe<?>> appB) {
default <B> Maybe<B> discardL(Applicative<B, Maybe<?>> appB) {
return MonadError.super.discardL(appB).coerce();
}

/**
* {@inheritDoc}
*/
@Override
public final <B> Maybe<A> discardR(Applicative<B, Maybe<?>> appB) {
default <B> Maybe<A> discardR(Applicative<B, Maybe<?>> appB) {
return MonadError.super.discardR(appB).coerce();
}

@@ -195,15 +192,15 @@ public final <B> Maybe<A> discardR(Applicative<B, Maybe<?>> appB) {
*/
@SuppressWarnings("RedundantTypeArguments")
@Override
public final <B> Maybe<B> flatMap(Fn1<? super A, ? extends Monad<B, Maybe<?>>> f) {
default <B> Maybe<B> flatMap(Fn1<? super A, ? extends Monad<B, Maybe<?>>> f) {
return match(constantly(nothing()), f.fmap(Monad<B, Maybe<?>>::coerce));
}

/**
* {@inheritDoc}
*/
@Override
public <B> Maybe<B> trampolineM(Fn1<? super A, ? extends MonadRec<RecursiveResult<A, B>, Maybe<?>>> fn) {
default <B> Maybe<B> trampolineM(Fn1<? super A, ? extends MonadRec<RecursiveResult<A, B>, Maybe<?>>> fn) {
return match(constantly(nothing()), trampoline(a -> fn.apply(a).<Maybe<RecursiveResult<A, B>>>coerce()
.match(constantly(terminate(nothing())),
aOrB -> aOrB.fmap(Maybe::just))));
@@ -213,23 +210,23 @@ public <B> Maybe<B> trampolineM(Fn1<? super A, ? extends MonadRec<RecursiveResul
* {@inheritDoc}
*/
@Override
public <B> Choice3<Unit, A, B> diverge() {
default <B> Choice3<Unit, A, B> diverge() {
return match(Choice3::a, Choice3::b);
}

/**
* {@inheritDoc}
*/
@Override
public Tuple2<Maybe<Unit>, Maybe<A>> project() {
default Tuple2<Maybe<Unit>, Maybe<A>> project() {
return CoProduct2.super.project().into(HList::tuple);
}

/**
* {@inheritDoc}
*/
@Override
public Choice2<A, Unit> invert() {
default Choice2<A, Unit> invert() {
return match(Choice2::b, Choice2::a);
}

@@ -241,13 +238,13 @@ public Choice2<A, Unit> invert() {
* @deprecated in favor of {@link Maybe#match(Fn1, Fn1) matching} into an {@link IO} and explicitly running it
*/
@Deprecated
public final Maybe<A> peek(Fn1<? super A, ? extends IO<?>> effect) {
default Maybe<A> 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 <B, App extends Applicative<?, App>, TravB extends Traversable<B, Maybe<?>>,
default <B, App extends Applicative<?, App>, TravB extends Traversable<B, Maybe<?>>,
AppTrav extends Applicative<TravB, App>> AppTrav traverse(Fn1<? super A, ? extends Applicative<B, App>> fn,
Fn1<? super TravB, ? extends AppTrav> pure) {
return match(__ -> pure.apply((TravB) Maybe.<B>nothing()), a -> (AppTrav) fn.apply(a).fmap(Maybe::just));
@@ -261,7 +258,7 @@ AppTrav extends Applicative<TravB, App>> AppTrav traverse(Fn1<? super A, ? exten
* @param <A> the potential right value
* @return "Just" the right value, or nothing
*/
public static <A> Maybe<A> fromEither(Either<?, A> either) {
static <A> Maybe<A> fromEither(Either<?, A> either) {
return either.toMaybe();
}

@@ -272,7 +269,7 @@ public static <A> Maybe<A> fromEither(Either<?, A> either) {
* @param <A> the optional parameter type
* @return the equivalent Maybe instance
*/
public static <A> Maybe<A> fromOptional(Optional<? extends A> optional) {
static <A> Maybe<A> fromOptional(Optional<? extends A> optional) {
return optional.map(Maybe::<A>just).orElse(Maybe.nothing());
}

@@ -284,7 +281,7 @@ public static <A> Maybe<A> fromOptional(Optional<? extends A> optional) {
* @param <A> the value parameter type
* @return "Just" the value, or nothing
*/
public static <A> Maybe<A> maybe(A a) {
static <A> Maybe<A> maybe(A a) {
return a == null ? nothing() : just(a);
}

@@ -297,7 +294,7 @@ public static <A> Maybe<A> maybe(A a) {
* @return "Just" the value
* @throws NullPointerException if a is null
*/
public static <A> Maybe<A> just(A a) {
static <A> Maybe<A> just(A a) {
if (a == null)
throw new NullPointerException();
return new Just<>(a);
@@ -310,7 +307,7 @@ public static <A> Maybe<A> just(A a) {
* @return nothing
*/
@SuppressWarnings("unchecked")
public static <A> Maybe<A> nothing() {
static <A> Maybe<A> nothing() {
return (Maybe<A>) Nothing.INSTANCE;
}

@@ -319,53 +316,22 @@ public static <A> Maybe<A> nothing() {
*
* @return the {@link Pure} instance
*/
public static Pure<Maybe<?>> pureMaybe() {
static Pure<Maybe<?>> pureMaybe() {
return Maybe::just;
}
}
record Nothing<A>() implements Maybe<A> {
static final Nothing<?> INSTANCE = new Nothing<>();

private static final class Nothing<A> extends Maybe<A> {
private static final Nothing<?> INSTANCE = new Nothing<>();

private Nothing() {
}

@Override
public <R> 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> R match(Fn1<? super Unit, ? extends R> aFn, Fn1<? super A, ? extends R> bFn) {
return aFn.apply(UNIT);
}
}

private static final class Just<A> extends Maybe<A> {

private final A a;

private Just(A a) {
this.a = a;
}

@Override
public <R> 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 a) implements Maybe<A> {
@Override
public <R> R match(Fn1<? super Unit, ? extends R> aFn, Fn1<? super A, ? extends R> bFn) {
return bFn.apply(a);
}
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
3 changes: 1 addition & 2 deletions src/main/java/com/jnape/palatable/lambda/adt/hmap/HMap.java
Original file line number Diff line number Diff line change
@@ -162,8 +162,7 @@ public Collection<Object> values() {

@Override
public boolean equals(Object other) {
if (other instanceof HMap) {
HMap that = (HMap) other;
if (other instanceof HMap that) {
return Objects.equals(this.table, that.table);
}
return false;
Original file line number Diff line number Diff line change
@@ -12,20 +12,15 @@
* @param <S> the larger viewing value of an {@link Iso}
* @param <T> the larger viewed value of an {@link Iso}
*/
public final class Exchange<A, B, S, T> implements Profunctor<S, T, Exchange<A, B, ?, ?>> {
private final Fn1<? super S, ? extends A> sa;
private final Fn1<? super B, ? extends T> bt;

public Exchange(Fn1<? super S, ? extends A> sa, Fn1<? super B, ? extends T> bt) {
this.sa = sa;
this.bt = bt;
}
public record Exchange<A, B, S, T>(Fn1<? super S, ? extends A> sa,
Fn1<? super B, ? extends T> bt) implements Profunctor<S, T, Exchange<A, B, ?, ?>> {

/**
* Extract the mapping <code>S -&gt; A</code>.
*
* @return an <code>{@link Fn1}&lt;S, A&gt;</code>
*/
@Override
public Fn1<? super S, ? extends A> sa() {
return sa;
}
@@ -35,6 +30,7 @@ public Exchange(Fn1<? super S, ? extends A> sa, Fn1<? super B, ? extends T> bt)
*
* @return an <code>{@link Fn1}&lt;B, T&gt;</code>
*/
@Override
public Fn1<? super B, ? extends T> bt() {
return bt;
}
Original file line number Diff line number Diff line change
@@ -182,8 +182,7 @@ public A value() {
tuple((Lazy<Object>) this, new LinkedList<>());
@SuppressWarnings("unchecked")
A a = (A) trampoline(into((source, flatMaps) -> {
if (source instanceof Compose<?>) {
Compose<?> nested = (Compose<?>) source;
if (source instanceof Compose<?> nested) {
flatMaps.push(nested.flatMap);
return recurse(tuple(nested.source, flatMaps));
}
Original file line number Diff line number Diff line change
@@ -28,13 +28,10 @@
* @param <S> the input that might fail to map to its output
* @param <T> the guaranteed output
*/
public final class Market<A, B, S, T> implements
public record Market<A, B, S, T>(Fn1<? super B, ? extends T> bt, Fn1<? super S, ? extends Either<T, A>> sta) implements
MonadRec<T, Market<A, B, S, ?>>,
Cocartesian<S, T, Market<A, B, ?, ?>> {

private final Fn1<? super B, ? extends T> bt;
private final Fn1<? super S, ? extends Either<T, A>> sta;

public Market(Fn1<? super B, ? extends T> bt, Fn1<? super S, ? extends Either<T, A>> sta) {
this.bt = fn1(bt);
this.sta = fn1(sta);
@@ -45,6 +42,7 @@ public Market(Fn1<? super B, ? extends T> bt, Fn1<? super S, ? extends Either<T,
*
* @return a <code>{@link Fn1}&lt;B, T&gt;</code>
*/
@Override
public Fn1<? super B, ? extends T> bt() {
return bt;
}
@@ -54,6 +52,7 @@ public Market(Fn1<? super B, ? extends T> bt, Fn1<? super S, ? extends Either<T,
*
* @return a <code>{@link Fn1}&lt;S, {@link Either}&lt;T, A&gt;&gt;</code>
*/
@Override
public Fn1<? super S, ? extends Either<T, A>> sta() {
return sta;
}
@@ -72,9 +71,9 @@ public <U> Market<A, B, S, U> pure(U u) {
@Override
public <U> Market<A, B, S, U> flatMap(Fn1<? super T, ? extends Monad<U, Market<A, B, S, ?>>> f) {
return new Market<>(b -> f.apply(bt().apply(b)).<Market<A, B, S, U>>coerce().bt().apply(b),
s -> sta().apply(s).invert()
.flatMap(t -> f.apply(t).<Market<A, B, S, U>>coerce().sta()
.apply(s).invert()).invert());
s -> sta().apply(s).invert()
.flatMap(t -> f.apply(t).<Market<A, B, S, U>>coerce().sta()
.apply(s).invert()).invert());
}

/**
@@ -89,7 +88,7 @@ public <U> Market<A, B, S, U> trampolineM(
trampoline(t -> fn.apply(t).<Market<A, B, S, RecursiveResult<T, U>>>coerce()
.sta.apply(s)
.match(tOrU -> tOrU.match(RecursiveResult::recurse, u -> terminate(left(u))),
a -> terminate(right(a)))),
a -> terminate(right(a)))),
Either::right)));
return new Market<>(bu, sua);
}
@@ -101,7 +100,7 @@ public <U> Market<A, B, S, U> trampolineM(
public <U> Market<A, B, S, U> zip(Applicative<Fn1<? super T, ? extends U>, Market<A, B, S, ?>> appFn) {
Market<A, B, S, Fn1<? super T, ? extends U>> marketF = appFn.coerce();
return new Market<>(b -> marketF.bt().apply(b).apply(bt().apply(b)),
s -> sta().apply(s).invert().zip(marketF.sta().apply(s).invert()).invert());
s -> sta().apply(s).invert().zip(marketF.sta().apply(s).invert()).invert());
}

/**
@@ -118,8 +117,8 @@ public <U> Market<A, B, S, U> fmap(Fn1<? super T, ? extends U> fn) {
@Override
public <C> Market<A, B, Choice2<C, S>, Choice2<C, T>> cocartesian() {
return new Market<>(bt.fmap(Choice2::b),
cs -> cs.fmap(sta).match(c -> left(a(c)),
tOrA -> tOrA.match(t -> left(b(t)), Either::right)));
cs -> cs.fmap(sta).match(c -> left(a(c)),
tOrA -> tOrA.match(t -> left(b(t)), Either::right)));
}

/**
Original file line number Diff line number Diff line change
@@ -7,8 +7,7 @@ public final class DroppingIterable<A> implements Iterable<A> {
private final Iterable<A> as;

public DroppingIterable(int n, Iterable<A> as) {
while (as instanceof DroppingIterable) {
DroppingIterable<A> nested = (DroppingIterable<A>) as;
while (as instanceof DroppingIterable<A> nested) {
as = nested.as;
n += nested.n;
}
Original file line number Diff line number Diff line change
@@ -15,8 +15,7 @@ public final class FilteringIterable<A> implements Iterable<A> {

public FilteringIterable(Fn1<? super A, ? extends Boolean> predicate, Iterable<A> as) {
List<Fn1<? super A, ? extends Boolean>> predicates = new ArrayList<>(singletonList(predicate));
while (as instanceof FilteringIterable) {
FilteringIterable<A> nested = (FilteringIterable<A>) as;
while (as instanceof FilteringIterable<A> nested) {
predicates.addAll(0, nested.predicates);
as = nested.as;
}
Original file line number Diff line number Diff line change
@@ -16,8 +16,7 @@ public final class MappingIterable<A, B> implements Iterable<B> {
@SuppressWarnings("unchecked")
public MappingIterable(Fn1<? super A, ? extends B> fn, Iterable<A> as) {
List<Fn1<?, ?>> mappers = new ArrayList<>(singletonList(fn));
while (as instanceof MappingIterable<?, ?>) {
MappingIterable<?, ?> nested = (MappingIterable<?, ?>) as;
while (as instanceof MappingIterable<?, ?> nested) {
as = (Iterable<A>) nested.as;
mappers.addAll(0, nested.mappers);
}
Original file line number Diff line number Diff line change
@@ -11,8 +11,7 @@ public final class PredicatedDroppingIterable<A> implements Iterable<A> {

public PredicatedDroppingIterable(Fn1<? super A, ? extends Boolean> predicate, Iterable<A> as) {
ImmutableQueue<Fn1<? super A, ? extends Boolean>> predicates = ImmutableQueue.singleton(predicate);
while (as instanceof PredicatedDroppingIterable) {
PredicatedDroppingIterable<A> nested = (PredicatedDroppingIterable<A>) as;
while (as instanceof PredicatedDroppingIterable<A> nested) {
as = nested.as;
predicates = nested.predicates.concat(predicates);
}
Original file line number Diff line number Diff line change
@@ -15,8 +15,7 @@ public final class PredicatedTakingIterable<A> implements Iterable<A> {

public PredicatedTakingIterable(Fn1<? super A, ? extends Boolean> predicate, Iterable<A> as) {
List<Fn1<? super A, ? extends Boolean>> predicates = new ArrayList<>(singletonList(predicate));
while (as instanceof PredicatedTakingIterable) {
PredicatedTakingIterable<A> nested = (PredicatedTakingIterable<A>) as;
while (as instanceof PredicatedTakingIterable<A> nested) {
predicates.addAll(0, nested.predicates);
as = nested.as;
}
Original file line number Diff line number Diff line change
@@ -15,8 +15,7 @@ public final class RateLimitingIterable<A> implements Iterable<A> {

public RateLimitingIterable(Iterable<A> as, Set<Tuple3<Long, Duration, Fn0<Instant>>> rateLimits) {
Set<Tuple3<Long, Duration, Fn0<Instant>>> combinedRateLimits = new HashSet<>(rateLimits);
if (as instanceof RateLimitingIterable) {
RateLimitingIterable<A> inner = (RateLimitingIterable<A>) as;
if (as instanceof RateLimitingIterable<A> inner) {
combinedRateLimits.addAll(inner.rateLimits);
as = inner.as;
}
Original file line number Diff line number Diff line change
@@ -8,8 +8,7 @@ public final class ReversingIterable<A> implements Iterable<A> {

public ReversingIterable(Iterable<A> as) {
boolean reverse = true;
while (as instanceof ReversingIterable) {
ReversingIterable<A> nested = (ReversingIterable<A>) as;
while (as instanceof ReversingIterable<A> nested) {
as = nested.as;
reverse = !nested.reverse;
}
Original file line number Diff line number Diff line change
@@ -12,8 +12,7 @@ public final class SnocIterable<A> implements Iterable<A> {

public SnocIterable(A a, Iterable<A> as) {
Iterable<A> snocs = cons(a, Collections::emptyIterator);
while (as instanceof SnocIterable) {
SnocIterable<A> nested = ((SnocIterable<A>) as);
while (as instanceof SnocIterable<A> nested) {
as = nested.as;
snocs = concat(nested.snocs, snocs);
}
Original file line number Diff line number Diff line change
@@ -9,8 +9,7 @@ public final class TakingIterable<A> implements Iterable<A> {
private final Iterable<A> as;

public TakingIterable(int n, Iterable<A> as) {
while (as instanceof TakingIterable) {
TakingIterable<A> nested = (TakingIterable<A>) as;
while (as instanceof TakingIterable<A> nested) {
n = min(n, nested.n);
as = nested.as;
}
6 changes: 2 additions & 4 deletions src/main/java/com/jnape/palatable/lambda/io/IO.java
Original file line number Diff line number Diff line change
@@ -430,8 +430,7 @@ private Compose(IO<?> source, Choice2<IO<?>, Fn1<Object, IO<?>>> composition) {
public A unsafePerformIO() {
Lazy<Object> lazyA = LazyRec.<IO<?>, Object>lazyRec(
(f, io) -> {
if (io instanceof IO.Compose<?>) {
Compose<?> compose = (Compose<?>) io;
if (io instanceof Compose<?> compose) {
Lazy<Object> head = f.apply(compose.source);
return compose.composition
.match(zip -> head.flatMap(x -> f.apply(zip)
@@ -450,8 +449,7 @@ public A unsafePerformIO() {
public CompletableFuture<A> unsafePerformAsyncIO(Executor executor) {
Lazy<CompletableFuture<Object>> lazyFuture = LazyRec.<IO<?>, CompletableFuture<Object>>lazyRec(
(f, io) -> {
if (io instanceof IO.Compose<?>) {
Compose<?> compose = (Compose<?>) io;
if (io instanceof Compose<?> compose) {
Lazy<CompletableFuture<Object>> head = f.apply(compose.source);
return compose.composition
.match(zip -> head.flatMap(futureX -> f.apply(zip)
Original file line number Diff line number Diff line change
@@ -176,17 +176,9 @@ public void mappingValuesWithIsoRetainsMapStructureWithMappedValues() {
assertLensLawfulness(mappingValues(iso(Integer::parseInt, Object::toString)),
asList(emptyMap(),
singletonMap("foo", "1"),
unmodifiableMap(new HashMap<String, String>() {{
put("foo", "1");
put("bar", "2");
put("baz", "3");
}})),
Map.of("foo", "1", "bar", "2", "baz", "3")),
asList(emptyMap(),
singletonMap("foo", 1),
unmodifiableMap(new HashMap<String, Integer>() {{
put("foo", 1);
put("bar", 2);
put("baz", 3);
}})));
Map.of("foo", 1, "bar", 2, "baz", 3)));
}
}
28 changes: 9 additions & 19 deletions src/test/java/testsupport/assertion/PrismAssert.java
Original file line number Diff line number Diff line change
@@ -59,29 +59,19 @@ private static <S, A, X> Maybe<String> falsify(String label, Fn2<S, A, X> l, Fn2
.apply(cases);
}

private static final class PrismResult<S> {
private final Maybe<S> maybeS;

private PrismResult(Maybe<S> maybeS) {
this.maybeS = maybeS;
}
private record PrismResult<S>(Maybe<S> maybeS) {

@Override
public boolean equals(Object other) {
if (other instanceof PrismResult) {
return maybeS.zip(((PrismResult<?>) other).maybeS.fmap(fn2(Objects::equals))).orElse(true);
public boolean equals(Object other) {
if (other instanceof PrismResult) {
return maybeS.zip(((PrismResult<?>) other).maybeS.fmap(fn2(Objects::equals))).orElse(true);
}
return false;
}
return false;
}

@Override
public int hashCode() {
return Objects.hash(maybeS);
}

@Override
public String toString() {
return maybeS.toString();
public String toString() {
return maybeS.toString();
}
}
}
}