package fj;
import fj.control.parallel.Actor;
import fj.control.parallel.Promise;
import fj.control.parallel.Strategy;
import fj.data.Array;
import fj.data.Either;
import fj.data.IterableW;
import fj.data.List;
import fj.data.NonEmptyList;
import fj.data.Option;
import fj.data.Set;
import fj.data.Stream;
import fj.data.Tree;
import fj.data.TreeZipper;
import fj.data.Validation;
import fj.data.Zipper;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.TreeSet;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.SynchronousQueue;
import static fj.data.Option.some;
import static fj.data.Stream.iterableStream;
import static fj.data.Zipper.fromStream;
/**
* A transformation or function from A to B. This type can be represented
* using the Java 7 closure syntax.
*
* @version %build.number%
*/
public abstract class F {
/**
* Transform A to B.
*
* @param a The A to transform.
* @return The result of the transformation.
*/
public abstract B f(A a);
/**
* Function composition
*
* @param g A function to compose with this one.
* @return The composed function such that this function is applied last.
*/
public final F o(final F g) {
return new F() {
public B f(final C c) {
return F.this.f(g.f(c));
}
};
}
/**
* First-class function composition
*
* @return A function that composes this function with another.
*/
public final F, F> o() {
return new F, F>() {
public F f(final F g) {
return F.this.o(g);
}
};
}
/**
* Function composition flipped.
*
* @param g A function with which to compose this one.
* @return The composed function such that this function is applied first.
*/
@SuppressWarnings({"unchecked"})
public final F andThen(final F g) {
return g.o(this);
}
/**
* First-class composition flipped.
*
* @return A function that invokes this function and then a given function on the result.
*/
public final F, F> andThen() {
return new F, F>() {
public F f(final F g) {
return F.this.andThen(g);
}
};
}
/**
* Binds a given function across this function (Reader Monad).
*
* @param g A function that takes the return value of this function as an argument, yielding a new function.
* @return A function that invokes this function on its argument and then the given function on the result.
*/
public final F bind(final F> g) {
return new F() {
@SuppressWarnings({"unchecked"})
public C f(final A a) {
return g.f(F.this.f(a)).f(a);
}
};
}
/**
* First-class function binding.
*
* @return A function that binds another function across this function.
*/
public final F>, F> bind() {
return new F>, F>() {
public F f(final F> g) {
return F.this.bind(g);
}
};
}
/**
* Function application in an environment (Applicative Functor).
*
* @param g A function with the same argument type as this function, yielding a function that takes the return
* value of this function.
* @return A new function that invokes the given function on its argument, yielding a new function that is then
* applied to the result of applying this function to the argument.
*/
public final F apply(final F> g) {
return new F() {
@SuppressWarnings({"unchecked"})
public C f(final A a) {
return g.f(a).f(F.this.f(a));
}
};
}
/**
* First-class function application in an environment.
*
* @return A function that applies a given function within the environment of this function.
*/
public final F>, F> apply() {
return new F>, F>() {
public F f(final F> g) {
return F.this.apply(g);
}
};
}
/**
* Applies this function over the arguments of another function.
*
* @param g The function over whose arguments to apply this function.
* @return A new function that invokes this function on its arguments before invoking the given function.
*/
public final F> on(final F> g) {
return new F>() {
public F f(final A a1) {
return new F() {
@SuppressWarnings({"unchecked"})
public C f(final A a2) {
return g.f(F.this.f(a1)).f(F.this.f(a2));
}
};
}
};
}
/**
* Applies this function over the arguments of another function.
*
* @return A function that applies this function over the arguments of another function.
*/
public final F>, F>> on() {
return new F>, F>>() {
public F> f(final F> g) {
return F.this.on(g);
}
};
}
/**
* Promotes this function so that it returns its result in a product-1. Kleisli arrow for P1.
*
* @return This function promoted to return its result in a product-1.
*/
public final F> lazy() {
return new F>() {
public P1 f(final A a) {
return new P1() {
public B _1() {
return F.this.f(a);
}
};
}
};
}
/**
* Promotes this function to map over a product-1.
*
* @return This function promoted to map over a product-1.
*/
public final F, P1> mapP1() {
return new F, P1>() {
public P1 f(final P1 p) {
return p.map(F.this);
}
};
}
/**
* Promotes this function so that it returns its result in an Option. Kleisli arrow for Option.
*
* @return This function promoted to return its result in an Option.
*/
public final F> optionK() {
return new F>() {
public Option f(final A a) {
return some(F.this.f(a));
}
};
}
/**
* Promotes this function to map over an optional value.
*
* @return This function promoted to map over an optional value.
*/
public final F