spike.RecursiveResult Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of lambda Show documentation
Show all versions of lambda Show documentation
Functional patterns for Java
package spike;
import com.jnape.palatable.lambda.adt.coproduct.CoProduct2;
import com.jnape.palatable.lambda.functor.Applicative;
import com.jnape.palatable.lambda.functor.Bifunctor;
import com.jnape.palatable.lambda.monad.Monad;
import com.jnape.palatable.lambda.traversable.Traversable;
import java.util.Objects;
import java.util.function.Function;
/**
* Specialized {@link CoProduct2} representing the possible results of a primitive recursive function.
* Used by {@link Trampoline} to cheat around {@link CoProduct2#match} and quickly unpack values via
* instanceof
checks to package private inner subtypes.
*
* @param the recursive function's input type
* @param the recursive function's output type
* @see Trampoline
*/
public abstract class RecursiveResult implements CoProduct2>, Bifunctor>, Monad>, Traversable> {
private RecursiveResult() {
}
@Override
@SuppressWarnings("unchecked")
public RecursiveResult biMapL(Function super A, ? extends C> fn) {
return (RecursiveResult) Bifunctor.super.biMapL(fn);
}
@Override
@SuppressWarnings("unchecked")
public RecursiveResult biMapR(Function super B, ? extends C> fn) {
return (RecursiveResult) Bifunctor.super.biMapR(fn);
}
@Override
public RecursiveResult biMap(Function super A, ? extends C> lFn,
Function super B, ? extends D> rFn) {
return match(a -> recurse(lFn.apply(a)), b -> terminate(rFn.apply(b)));
}
@Override
public RecursiveResult flatMap(
Function super B, ? extends Monad>> f) {
return match(RecursiveResult::recurse, b -> f.apply(b).coerce());
}
@Override
public RecursiveResult pure(C c) {
return terminate(c);
}
@Override
public RecursiveResult fmap(Function super B, ? extends C> fn) {
return Monad.super.fmap(fn).coerce();
}
@Override
public RecursiveResult zip(
Applicative, RecursiveResult> appFn) {
return Monad.super.zip(appFn).coerce();
}
@Override
public RecursiveResult discardL(Applicative> appB) {
return Monad.super.discardL(appB).coerce();
}
@Override
public RecursiveResult discardR(Applicative> appB) {
return Monad.super.discardR(appB).coerce();
}
@Override
@SuppressWarnings("unchecked")
public Applicative, App> traverse(
Function super B, ? extends Applicative> fn,
Function super Traversable>, ? extends Applicative extends Traversable>, App>> pure) {
return match(__ -> pure.apply(coerce()).fmap(x -> (RecursiveResult) x),
b -> fn.apply(b).fmap(this::pure));
}
public static RecursiveResult recurse(A a) {
return new Recurse<>(a);
}
public static RecursiveResult terminate(B b) {
return new Terminate<>(b);
}
static final class Recurse extends RecursiveResult {
final A a;
private Recurse(A a) {
this.a = a;
}
@Override
public R match(Function super A, ? extends R> aFn, Function super B, ? extends R> bFn) {
return aFn.apply(a);
}
@Override
public boolean equals(Object other) {
return other instanceof Recurse && Objects.equals(a, ((Recurse) other).a);
}
@Override
public int hashCode() {
return Objects.hash(a);
}
@Override
public String toString() {
return "Recurse{" +
"a=" + a +
'}';
}
}
static final class Terminate extends RecursiveResult {
final B b;
private Terminate(B b) {
this.b = b;
}
@Override
public R match(Function super A, ? extends R> aFn, Function super B, ? extends R> bFn) {
return bFn.apply(b);
}
@Override
public boolean equals(Object other) {
return other instanceof Terminate && Objects.equals(b, ((Terminate) other).b);
}
@Override
public int hashCode() {
return Objects.hash(b);
}
@Override
public String toString() {
return "Terminate{" +
"b=" + b +
'}';
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy