Base.java
- package no.motif;
- import static no.motif.Iterate.on;
- import java.util.Collection;
- import java.util.Objects;
- import no.motif.f.Do;
- import no.motif.f.Fn;
- import no.motif.f.Fn0;
- import no.motif.f.Fn2;
- import no.motif.f.Predicate;
- import no.motif.f.Predicate.Always;
- import no.motif.f.combine.Conjunction;
- import no.motif.f.combine.ConjunctionPremise;
- import no.motif.f.combine.Disjunction;
- import no.motif.f.combine.DisjunctionPremise;
- import no.motif.f.combine.DoChain;
- import no.motif.f.combine.Fn2Chain;
- import no.motif.f.combine.FnChain;
- import no.motif.f.combine.RunnableChain;
- import no.motif.f.combine.When;
- import no.motif.f.combine.Where;
- import no.motif.f.impl.Constant;
- import no.motif.f.impl.Throw;
- import no.motif.iter.ExtractingIterable;
- import no.motif.types.Elements;
- /**
- * Basic functions.
- *
- * @see Predicate
- * @see Fn
- */
- public final class Base {
- /**
- * Shorthand for {@link #not(Predicate) not(}{@link #equalTo(Object) equalTo(o))}.
- *
- * @see #not(Predicate)
- * @see #equalTo(Object)
- */
- public static <T> Predicate<T> not(T o) { return not(equalTo(o)); }
- /**
- * Negates a predicate.
- * @param p The predicate to negate.
- * @return The new predicate.
- */
- public static <T> Predicate<T> not(final Predicate<T> p) {
- return new Predicate<T>() { @Override public boolean $(T value) { return !p.$(value); }}; }
- /**
- * Compose a predicate from taking the result of a function and apply it to
- * another predicate.
- *
- * <pre>
- * fn(T) ∈ P
- * p(P) ∈ {true, false}
- * <b>ƒ(T) = p(fn(T)) ∈ {true, false}</b>
- * </pre>
- *
- * <p>
- * This simple composition enables one to focus on writing {@link Fn functions}
- * for your particular domain, and reusing basic predicates provided by <em>Motif</em>.
- * </p>
- *
- * @param <P> The type of the predicate evaluating the function result.
- * @param <T> The type of the resulting predicate.
- * @param fn The function which result will be evaluated by the predicate. Takes
- * an argument of <code>T</code>
- * @param predicate Evaluates the result from the function, i.e. a value of <code>P</code>
- * @return A predicate of <code>T</code>
- */
- public static <T, P> Predicate<T> where(final Fn<T, P> fn, final Predicate<? super P> predicate) {
- return new Where<T, P>(fn, predicate); }
- /**
- * Create a AND-expression of several predicates, starting with the one
- * given to this method.
- *
- * @see Conjunction
- * @see #allOf(Predicate...)
- * @param predicate The first predicate.
- * @return a new predicate which may be used to build up an AND-expression by
- * chaining the {@link Conjunction#and(Predicate) and(anotherPredicate)} method.
- */
- public static <T> Conjunction<T> both(Predicate<T> predicate) {
- return new Conjunction<T>(predicate);
- }
- /**
- * Create a AND-expression of several {@link Fn0 Fn0<Boolean>s}, starting with the one
- * given to this method.
- *
- * @see ConjunctionPremise
- * @param premise The first <code>Fn0<Boolean></code>.
- * @return a new <code>Fn0<Boolean></code> which may be used to build up an AND-expression by
- * chaining the {@link ConjunctionPremise#and(Fn0) and(anotherPremise)} method.
- */
- public static ConjunctionPremise both(Fn0<Boolean> premise) {
- return new ConjunctionPremise(premise);
- }
- /**
- * Compose an AND-expression of several predicates.
- *
- * @see Conjunction
- * @param predicates the predicates.
- * @return a new predicate which is the conjunction (AND) of the given predicates.
- */
- @SafeVarargs
- @SuppressWarnings("varargs")
- public static <T> Conjunction<T> allOf(Predicate<? super T> ... predicates) {
- return new Conjunction<>(predicates);
- }
- /**
- * Compose an AND-expression of several {@link Fn0 Fn0<Boolean>s}.
- *
- * @see ConjunctionPremise
- * @param premises the <code>Fn0<Boolean>s</code>.
- * @return a new <code>Fn0<Boolean></code> which is the conjunction
- * (AND) of the given premises.
- */
- @SafeVarargs
- @SuppressWarnings("varargs")
- public static ConjunctionPremise allOf(Fn0<Boolean> ... premises) {
- return new ConjunctionPremise(premises);
- }
- /**
- * Shorthand for {@link #either(Predicate) either(}{@link #equalTo(Object) equalTo(o))}.
- *
- * @see #either(Predicate)
- * @see Disjunction
- */
- public static <T> Disjunction<T> either(T o) { return either(equalTo(o)); }
- /**
- * Create a OR-expression of several predicates, starting with the one
- * given to this method.
- *
- * @see Disjunction
- * @see #anyOf(Predicate...)
- * @param predicate The first predicate.
- * @return a new predicate which may be used to build up an OR-expression by
- * chaining the {@link Disjunction#or(Predicate) or(anotherPredicate)} method.
- */
- public static <T> Disjunction<T> either(Predicate<T> predicate) {
- return new Disjunction<T>(predicate);
- }
- /**
- * Create a OR-expression of several {@link Fn0 Fn0<Boolean>s},
- * starting with the one given to this method.
- *
- * @see DisjunctionPremise
- * @param premise The first <code>Fn0<Boolean></code>.
- * @return a new <code>Fn0<Boolean></code> which may be used to build up an OR-expression by
- * chaining the {@link DisjunctionPremise#or(Fn0) or(anotherPremise)} method.
- */
- public static DisjunctionPremise either(Fn0<Boolean> premise) {
- return new DisjunctionPremise(premise);
- }
- /**
- * Shorthand for
- * {@link #anyOf(Predicate...) anyOf(}{@link #equalTo(Object) equalTo(o1), equalTo(o2), ..., equalTo(on))}
- *
- * @param objects the candidate objects for equivalence check.
- * @see Disjunction
- */
- @SafeVarargs
- @SuppressWarnings("varargs")
- public static <T> Disjunction<T> anyOf(T ... objects) {
- @SuppressWarnings("unchecked")
- Predicate<T>[] equalToPredicates = on(objects)
- .map(new Fn<T, Predicate<T>>() { @Override public Predicate<T> $(T o) { return equalTo(o); }})
- .collect().toArray(new Predicate[objects.length]);
- return anyOf(equalToPredicates);
- }
- /**
- * Compose an OR-expression of several predicates.
- *
- * @see Disjunction
- * @param predicates the predicates.
- * @return a new predicate which is the disjunction (OR) of the given predicates.
- */
- @SafeVarargs
- @SuppressWarnings("varargs")
- public static <T> Disjunction<T> anyOf(Predicate<? super T> ... predicates) {
- return new Disjunction<>(predicates);
- }
- /**
- * Compose an OR-expression of several {@link Fn0 Fn0<Boolean>s}.
- *
- * @see DisjunctionPremise
- * @param premises the <code>Fn0<Boolean>s</code>.
- * @return a new <code>Fn0<Boolean>s</code> which is the disjunction (OR) of the given premises.
- */
- @SafeVarargs
- @SuppressWarnings("varargs")
- public static DisjunctionPremise anyOf(Fn0<Boolean> ... premises) {
- return new DisjunctionPremise(premises);
- }
- /**
- * Evaluate if all elements satisfies a predicate, i.e. the <em>Universal quantifier function</em>.
- * Note that the predicate
- *
- * @param predicate The predicate which will evaluate all elements.
- * @return a predicate which evaluates to <code>true</code> if all elements evaluates
- * to true by the given predicate, false if any evaluates to <code>false</code>.
- */
- public static <E, I extends Iterable<E>> Predicate<I> all(final Predicate<? super E> predicate) {
- return new Predicate<I>() { @Override public boolean $(I iterable) {
- return on(iterable).filter(not(predicate)).isEmpty(); }};}
- /**
- * Shorthand for {@link #exists(Predicate) exists(}{@link #equalTo(Object) equalTo(element))}
- *
- * @param element The element to look for in an {@link Iterable}.
- * @return a predicate which evaluates to <code>true</code> if an element equal to the given
- * element is found, <code>false</code> otherwise.
- */
- public static <E, I extends Iterable<E>> Predicate<I> exists(E element) { return exists(equalTo(element)); }
- /**
- * Evaluate if an element exists, i.e. the <em>Existential quantifier function</em>.
- *
- * @param element The existance-deciding predicate.
- * @return a predicate which evaluates to <code>true</code> if any element evaluates
- * to true by the given predicate, <code>false</code> otherwise.
- */
- public static <E, I extends Iterable<E>> Predicate<I> exists(final Predicate<? super E> element) {
- return new Predicate<I>() { @Override public boolean $(I iterable) {
- return on(iterable).exists(element); }};}
- /**
- * A synonym for {@link #equalTo(Object)}.
- */
- public static <T> Predicate<T> is(T value) { return equalTo(value); }
- /**
- * Equality predicate, checks if values are equal to the given value.
- *
- * @param value the value the predicate should check for equality against.
- */
- public static <T> Predicate<T> equalTo(final T value) { return equalTo(always(value)); }
- /**
- * Equality predicate, checks if values are equal to the value computed from the given {@link Fn0}.
- *
- * @param value the {@link Fn0} which will compute the value to check for equality against on each
- * application of the predicate.
- */
- public static <T> Predicate<T> equalTo(final Fn0<? super T> value) {
- return new Predicate<T>() { @Override public boolean $(T input) {
- return Objects.equals(input, value.$()); }}; }
- /**
- * Predicate evaluating if values are less than a given value.
- *
- * @param value the right operand, i.e. the predicate will evaluate
- * if values are less than this value.
- * @return the "<em>< value</em>" predicate
- */
- public static <T extends Comparable<? super T>> Predicate<T> lessThan(final T value) {
- return new Predicate<T>() { @Override public boolean $(T candidate) { return candidate.compareTo(value) < 0; }}; }
- /**
- * Predicate evaluating if values are equal to or less than a given value.
- *
- * @param value the right operand, i.e. the predicate will evaluate
- * if values are equal to or less than this value.
- * @return the "<em>=< value</em>" predicate
- */
- public static <T extends Comparable<? super T>> Predicate<T> equalOrLessThan(T value) {
- return either(equalTo(value)).or(lessThan(value)); }
- /**
- * Predicate evaluating if values are greater than a given value.
- *
- * @param value the right operand, i.e. the predicate will evaluate
- * if values are greater than this value.
- * @return the "<em>> value</em>" predicate
- */
- public static <T extends Comparable<? super T>> Predicate<T> greaterThan(final T value) {
- return new Predicate<T>() { @Override public boolean $(T candidate) { return candidate.compareTo(value) > 0; }}; }
- /**
- * Predicate evaluating if values are equal to or greater than a given value.
- *
- * @param value the right operand, i.e. the predicate will evaluate
- * if values are equal to or greater than this value.
- * @return the "<em>>= value</em>" predicate
- */
- public static <T extends Comparable<? super T>> Predicate<T> equalOrGreaterThan(T value) {
- return either(equalTo(value)).or(greaterThan(value)); }
- /**
- * Yields <code>true</code> for <code>null</code> values.
- */
- public static final Predicate<Object> isNull = new Predicate<Object>() {
- @Override public boolean $(Object value) { return value == null; }};
- /**
- * Yields <code>true</code> for all non-<code>null</code> values.
- */
- public static final Predicate<Object> notNull = not(isNull);
- /**
- * A function to extract/derive several values from one object. The result of the
- * extraction is an {@link Elements}s container of the least common supertype of
- * the extractor {@link Fn}s' return types.
- *
- * @param extractors the {@link Fn}s which will extract values from each object passed
- * to the function.
- *
- * @return the composed function which yields.
- */
- @SafeVarargs
- public static <T, E> Fn<T, Elements<E>> extract(final Fn<? super T, ? extends E> ... extractors) {
- return new Fn<T, Elements<E>>() { @Override public Elements<E> $(T value) {
- return on(new ExtractingIterable<T, E>(value, on(extractors))); }}; }
- /**
- * Yields the {@link String#valueOf(Object) string representation} of
- * any object.
- */
- public static final Fn<Object, String> toString = new Fn<Object, String>() {
- @Override public String $(Object value) { return String.valueOf(value); }};
- /**
- * Yields the {@link Object#hashCode() hashCode} for objects, or 0 if <code>null</code>.
- */
- public static final Fn<Object, Integer> hashCode = new Fn<Object, Integer>() {
- @Override public Integer $(Object o) { return o != null ? o.hashCode() : 0; }};
- /**
- * Creates a "guarded" {@link Fn} using a {@link Predicate} to evaluate if the
- * argument should be passed to the wrapped <code>Fn</code>. The function created
- * by this method is essentially this ternary expression:
- * <pre> condition(v) ? f(v) : null;</pre>
- * To fall back to another value than <code>null</code>, call either {@link When#orElse(Fn) .orElse(Fn)}
- * or {@link When#orElse(Object) .orElse(other)} on the returned object.
- *
- * @param condition Only when this evaluates to <code>true</code> will the function argument
- * be applied to the given {@link Fn}.
- * @param fn The {@link Fn} to apply if <code>condition</code> evaluates to <code>true</code>
- */
- public static <I, O> When<I, O> when(Predicate<? super I> condition, Fn<? super I, ? extends O> fn) {
- return new When<>(condition, fn);
- }
- /**
- * Compose a chain of several functions into one {@link Fn}, where the result of
- * each function is passed to its successor, and the last will yield the
- * actual result of the chain. Use {@link FnChain#then(Fn) .then(Fn)} to append
- * functions to the chain.
- *
- * <p><strong>Note:</strong> The chain does no internal inspection of the intermediate
- * results passed to the next function, which means that any function which may
- * return <code>null</code>, <em>must</em> have a <code>null</code>-safe successor
- * function.
- *
- * @param fn The first function in the chain.
- * @return the given function as the first function in a chain.
- */
- public static final <I, O> FnChain<I, O> first(Fn<I, O> fn) {
- return FnChain.chain(fn);
- }
- /**
- * Compose a chain of several functions into one {@link Fn2}, where the result of
- * each function is passed to its successor, and the last will yield the
- * actual result of the chain. Use {@link Fn2Chain#then(Fn) .then(Fn)} to append
- * functions to the chain.
- *
- * <p><strong>Note:</strong> The chain does no inspection of the intermediate
- * results passed to the next function, which means that any function which may
- * return <code>null</code>, <em>must</em> have a <code>null</code>-safe successor
- * function.
- *
- * @param fn2 The first function in the chain.
- * @return the given function as the first function in a chain.
- */
- public static final <I1, I2, O> Fn2Chain<I1, I2, O, O> first(Fn2<I1, I2, O> fn2) {
- return new Fn2Chain<>(fn2, NOP.<O>fn());
- }
- /**
- * Compose several {@link Runnable}s as a single Runnable which will
- * execute the given Runnables in sequence.
- *
- * @param runnable The first Runnable.
- * @return the given Runnable as the first Runnable in a sequence.
- */
- public static final RunnableChain first(Runnable runnable) {
- return new RunnableChain(runnable, NOP.runnable);
- }
- /**
- * Chain several {@link Do}s to be executed in sequence.
- *
- * @param action The first {@link Do} to execute.
- * @return The given <code>Do</code> as the first <code>Do</code> in a sequence.
- */
- public static <V> DoChain<V> first(Do<V> action) {
- return new DoChain<>(action, NOP.doNothing);
- }
- /**
- * Create a function which always yields the given value.
- *
- * @param value The value to yield.
- */
- public static <I1, I2, V> Constant<I1, I2, V> always(V value) { return new Constant<>(value); }
- /**
- * Create a predicate which always yields the given <code>boolean</code> value.
- *
- * @param bool The <code>boolean</code> value to yield.
- */
- @SuppressWarnings("unchecked")
- public static <T> Predicate<T> always(boolean bool) {
- return (Predicate<T>) (bool ? Predicate.Always.yes() : Predicate.Always.no());
- }
- /**
- * Create a function which always throw the given exception. If the
- * exception is not a {@link RuntimeException} it will be wrapped as such.
- *
- * @param ex The exception to throw.
- */
- public static <I1, I2, O> Throw<I1, I2, O> alwaysThrow(Exception ex) { return new Throw<>(ex); }
- /**
- * Evaluates if objects are contained in the given <code>Iterable</code>.
- */
- public static <T> Predicate<T> containedIn(final Iterable<? extends T> iterable) {
- if (iterable == null) return Always.<T>no();
- if (iterable instanceof Collection) {
- final Collection<? extends T> collection = (Collection<? extends T>) iterable;
- return collection.isEmpty() ? Always.<T>no() : new Predicate<T>() {
- @Override public boolean $(T value) { return collection.contains(value); }};
- } else {
- final Elements<? extends T> elements = on(iterable);
- return new Predicate<T>() {
- @Override public boolean $(T value) { return elements.exists(is(value)); }};
- }
- }
- private Base() {}
- }