com.jnape.palatable.lambda.functor.builtin.Compose 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 com.jnape.palatable.lambda.functor.builtin;
import com.jnape.palatable.lambda.functions.Fn1;
import com.jnape.palatable.lambda.functions.specialized.Pure;
import com.jnape.palatable.lambda.functor.Applicative;
import java.util.Objects;
import static com.jnape.palatable.lambda.functions.builtin.fn1.Upcast.upcast;
/**
* A functor representing the type-level composition of two {@link Applicative} functors; useful for preserving nested
* type-level transformations during traversal of a {@link com.jnape.palatable.lambda.traversable.Traversable}.
*
* @param The outer applicative
* @param The inner applicative
* @param The carrier type
*/
public final class Compose, G extends Applicative, G>, A> implements
Applicative> {
private final Applicative extends Applicative, F> fga;
public Compose(Applicative extends Applicative, F> fga) {
this.fga = fga;
}
@SuppressWarnings("RedundantTypeArguments")
public , FGA extends Applicative> FGA getCompose() {
return fga.fmap(Applicative::coerce).coerce();
}
/**
* {@inheritDoc}
*/
@Override
public Compose fmap(Fn1 super A, ? extends B> fn) {
return new Compose<>(fga.fmap(g -> g.fmap(fn)));
}
/**
* {@inheritDoc}
*/
@Override
public Compose pure(B b) {
return new Compose<>(fga.fmap(g -> g.pure(b)));
}
/**
* {@inheritDoc}
*/
@Override
public Compose zip(Applicative, Compose> appFn) {
return new Compose<>(fga.zip(appFn.>>coerce()
.getCompose().fmap(gFn -> g -> g.zip(gFn))));
}
/**
* {@inheritDoc}
*/
@Override
public Lazy> lazyZip(
Lazy extends Applicative, Compose>> lazyAppFn) {
@SuppressWarnings("RedundantTypeArguments")
Lazy, G>, F>> lazyAppFnCoerced =
lazyAppFn
.>>fmap(
Applicative, Compose>::coerce)
.fmap(Compose>::getCompose);
return fga.>fmap(upcast())
.>lazyZip(lazyAppFnCoerced.fmap(fgf -> fgf.fmap(gf -> ga -> ga.zip(gf))))
.fmap(Compose::new);
}
/**
* {@inheritDoc}
*/
@Override
public Compose discardL(Applicative> appB) {
return Applicative.super.discardL(appB).coerce();
}
/**
* {@inheritDoc}
*/
@Override
public Compose discardR(Applicative> appB) {
return Applicative.super.discardR(appB).coerce();
}
@Override
public boolean equals(Object other) {
return other instanceof Compose && Objects.equals(fga, ((Compose) other).fga);
}
@Override
public int hashCode() {
return Objects.hash(fga);
}
@Override
public String toString() {
return "Compose{fga=" + fga + '}';
}
/**
* The canonical {@link Pure} instance for {@link Compose}.
*
* @param pureF the {@link Pure} constructor for the outer {@link Applicative}
* @param pureG the {@link Pure} constructor for the inner {@link Applicative}
* @param the outer {@link Applicative} type
* @param the inner {@link Applicative} type
* @return the {@link Pure} instance
*/
public static , G extends Applicative, G>> Pure> pureCompose(
Pure pureF, Pure pureG) {
return new Pure>() {
@Override
public Compose checkedApply(A a) throws Throwable {
return new Compose<>(pureF., Applicative, F>>apply(pureG.apply(a)));
}
};
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy