com.jnape.palatable.lambda.traversable.Traversable Maven / Gradle / Ivy
Show all versions of lambda Show documentation
package com.jnape.palatable.lambda.traversable;
import com.jnape.palatable.lambda.functor.Applicative;
import com.jnape.palatable.lambda.functor.Functor;
import com.jnape.palatable.lambda.functor.builtin.Identity;
import java.util.function.Function;
/**
* An interface for a class of data structures that can be "traversed from left to right" in a structure-preserving
* way, successively applying some applicative computation to each element and collapsing the results into a single
* resulting applicative.
*
* The same rules that apply to Functor
apply to Traversable
, along with the following
* additional 3 laws:
*
* - naturality:
t.apply(trav.traverse(f, pure).<Object>fmap(id()).coerce())
* .equals(trav.traverse(t.compose(f), pure2).<Object>fmap(id()).coerce())
* - identity:
trav.traverse(Identity::new, x -> new Identity<>(x)).equals(new
* Identity<>(trav)
* - composition:
trav.traverse(f.andThen(x -> x.fmap(g)).andThen(Compose::new), x ->
* new Compose<>(new Identity<>(new Identity<>(x)))).equals(new Compose<Identity, Identity,
* Traversable<Object, Trav>>(trav.traverse(f, x -> new Identity<>(x)).fmap(t ->
* t.traverse(g, x -> new Identity<>(x)))))
*
*
* For more information, read about
* Traversables.
*
* @param The type of the parameter
* @param The unification parameter
*/
public interface Traversable extends Functor {
/**
* Apply fn
to each element of this traversable from left to right, and collapse the results into
* a single resulting applicative, potentially with the assistance of the applicative's pure function.
*
* @param fn the function to apply
* @param pure the applicative pure function
* @param the resulting element type
* @param the result applicative type
* @return the traversed Traversable, wrapped inside an applicative
*/
Applicative extends Traversable, App> traverse(
Function super A, ? extends Applicative> fn,
Function super Traversable, ? extends Applicative extends Traversable, App>> pure);
@Override
@SuppressWarnings({"Convert2MethodRef", "unchecked"})
default Traversable fmap(Function super A, ? extends B> fn) {
return traverse(a -> new Identity<>(fn.apply(a)), x -> new Identity<>(x))
.fmap(x -> (Traversable) x)
.>>coerce()
.runIdentity();
}
}