Base.java

  1. package no.motif;

  2. import static no.motif.Iterate.on;

  3. import java.util.Collection;
  4. import java.util.Objects;

  5. import no.motif.f.Do;
  6. import no.motif.f.Fn;
  7. import no.motif.f.Fn0;
  8. import no.motif.f.Fn2;
  9. import no.motif.f.Predicate;
  10. import no.motif.f.Predicate.Always;
  11. import no.motif.f.combine.Conjunction;
  12. import no.motif.f.combine.ConjunctionPremise;
  13. import no.motif.f.combine.Disjunction;
  14. import no.motif.f.combine.DisjunctionPremise;
  15. import no.motif.f.combine.DoChain;
  16. import no.motif.f.combine.Fn2Chain;
  17. import no.motif.f.combine.FnChain;
  18. import no.motif.f.combine.RunnableChain;
  19. import no.motif.f.combine.When;
  20. import no.motif.f.combine.Where;
  21. import no.motif.f.impl.Constant;
  22. import no.motif.f.impl.Throw;
  23. import no.motif.iter.ExtractingIterable;
  24. import no.motif.types.Elements;

  25. /**
  26.  * Basic functions.
  27.  *
  28.  * @see Predicate
  29.  * @see Fn
  30.  */
  31. public final class Base {

  32.     /**
  33.      * Shorthand for {@link #not(Predicate) not(}{@link #equalTo(Object) equalTo(o))}.
  34.      *
  35.      * @see #not(Predicate)
  36.      * @see #equalTo(Object)
  37.      */
  38.     public static <T> Predicate<T> not(T o) { return not(equalTo(o)); }


  39.     /**
  40.      * Negates a predicate.
  41.      * @param p The predicate to negate.
  42.      * @return The new predicate.
  43.      */
  44.     public static <T> Predicate<T> not(final Predicate<T> p) {
  45.         return new Predicate<T>() { @Override public boolean $(T value) { return !p.$(value); }}; }


  46.     /**
  47.      * Compose a predicate from taking the result of a function and apply it to
  48.      * another predicate.
  49.      *
  50.      * <pre>
  51.      * fn(T) &isin; P
  52.      * p(P) &isin; {true, false}
  53.      * <b>&fnof;(T) = p(fn(T)) &isin; {true, false}</b>
  54.      * </pre>
  55.      *
  56.      * <p>
  57.      * This simple composition enables one to focus on writing {@link Fn functions}
  58.      * for your particular domain, and reusing basic predicates provided by <em>Motif</em>.
  59.      * </p>
  60.      *
  61.      * @param <P>       The type of the predicate evaluating the function result.
  62.      * @param <T>       The type of the resulting predicate.
  63.      * @param fn        The function which result will be evaluated by the predicate. Takes
  64.      *                  an argument of <code>T</code>
  65.      * @param predicate Evaluates the result from the function, i.e. a value of <code>P</code>
  66.      * @return          A predicate of <code>T</code>
  67.      */
  68.     public static <T, P> Predicate<T> where(final Fn<T, P> fn, final Predicate<? super P> predicate) {
  69.         return new Where<T, P>(fn, predicate); }



  70.     /**
  71.      * Create a AND-expression of several predicates, starting with the one
  72.      * given to this method.
  73.      *
  74.      * @see Conjunction
  75.      * @see #allOf(Predicate...)
  76.      * @param predicate The first predicate.
  77.      * @return a new predicate which may be used to build up an AND-expression by
  78.      *         chaining the {@link Conjunction#and(Predicate) and(anotherPredicate)} method.
  79.      */
  80.     public static <T> Conjunction<T> both(Predicate<T> predicate) {
  81.         return new Conjunction<T>(predicate);
  82.     }


  83.     /**
  84.      * Create a AND-expression of several {@link Fn0 Fn0&lt;Boolean&gt;s}, starting with the one
  85.      * given to this method.
  86.      *
  87.      * @see ConjunctionPremise
  88.      * @param premise The first <code>Fn0&lt;Boolean&gt;</code>.
  89.      * @return a new <code>Fn0&lt;Boolean&gt;</code> which may be used to build up an AND-expression by
  90.      *         chaining the {@link ConjunctionPremise#and(Fn0) and(anotherPremise)} method.
  91.      */
  92.     public static ConjunctionPremise both(Fn0<Boolean> premise) {
  93.         return new ConjunctionPremise(premise);
  94.     }



  95.     /**
  96.      * Compose an AND-expression of several predicates.
  97.      *
  98.      * @see Conjunction
  99.      * @param predicates the predicates.
  100.      * @return a new predicate which is the conjunction (AND) of the given predicates.
  101.      */
  102.     @SafeVarargs
  103.     @SuppressWarnings("varargs")
  104.     public static <T> Conjunction<T> allOf(Predicate<? super T> ... predicates) {
  105.         return new Conjunction<>(predicates);
  106.     }

  107.     /**
  108.      * Compose an AND-expression of several {@link Fn0 Fn0&lt;Boolean&gt;s}.
  109.      *
  110.      * @see ConjunctionPremise
  111.      * @param premises the <code>Fn0&lt;Boolean&gt;s</code>.
  112.      * @return a new <code>Fn0&lt;Boolean&gt;</code> which is the conjunction
  113.      *         (AND) of the given premises.
  114.      */
  115.     @SafeVarargs
  116.     @SuppressWarnings("varargs")
  117.     public static ConjunctionPremise allOf(Fn0<Boolean> ... premises) {
  118.         return new ConjunctionPremise(premises);
  119.     }



  120.     /**
  121.      * Shorthand for {@link #either(Predicate) either(}{@link #equalTo(Object) equalTo(o))}.
  122.      *
  123.      * @see #either(Predicate)
  124.      * @see Disjunction
  125.      */
  126.     public static <T> Disjunction<T> either(T o) { return either(equalTo(o)); }

  127.     /**
  128.      * Create a OR-expression of several predicates, starting with the one
  129.      * given to this method.
  130.      *
  131.      * @see Disjunction
  132.      * @see #anyOf(Predicate...)
  133.      * @param predicate The first predicate.
  134.      * @return a new predicate which may be used to build up an OR-expression by
  135.      *         chaining the {@link Disjunction#or(Predicate) or(anotherPredicate)} method.
  136.      */
  137.     public static <T> Disjunction<T> either(Predicate<T> predicate) {
  138.         return new Disjunction<T>(predicate);
  139.     }


  140.     /**
  141.      * Create a OR-expression of several {@link Fn0 Fn0&lt;Boolean&gt;s},
  142.      * starting with the one given to this method.
  143.      *
  144.      * @see DisjunctionPremise
  145.      * @param premise The first <code>Fn0&lt;Boolean&gt;</code>.
  146.      * @return a new <code>Fn0&lt;Boolean&gt;</code> which may be used to build up an OR-expression by
  147.      *         chaining the {@link DisjunctionPremise#or(Fn0) or(anotherPremise)} method.
  148.      */
  149.     public static DisjunctionPremise either(Fn0<Boolean> premise) {
  150.         return new DisjunctionPremise(premise);
  151.     }


  152.     /**
  153.      * Shorthand for
  154.      * {@link #anyOf(Predicate...) anyOf(}{@link #equalTo(Object) equalTo(o1), equalTo(o2), ..., equalTo(on))}
  155.      *
  156.      * @param objects the candidate objects for equivalence check.
  157.      * @see Disjunction
  158.      */
  159.     @SafeVarargs
  160.     @SuppressWarnings("varargs")
  161.     public static <T> Disjunction<T> anyOf(T ... objects) {
  162.         @SuppressWarnings("unchecked")
  163.         Predicate<T>[] equalToPredicates = on(objects)
  164.             .map(new Fn<T, Predicate<T>>() { @Override public Predicate<T> $(T o) { return equalTo(o); }})
  165.             .collect().toArray(new Predicate[objects.length]);
  166.         return anyOf(equalToPredicates);
  167.     }


  168.     /**
  169.      * Compose an OR-expression of several predicates.
  170.      *
  171.      * @see Disjunction
  172.      * @param predicates the predicates.
  173.      * @return a new predicate which is the disjunction (OR) of the given predicates.
  174.      */
  175.     @SafeVarargs
  176.     @SuppressWarnings("varargs")
  177.     public static <T> Disjunction<T> anyOf(Predicate<? super T> ... predicates) {
  178.         return new Disjunction<>(predicates);
  179.     }


  180.     /**
  181.      * Compose an OR-expression of several {@link Fn0 Fn0&lt;Boolean&gt;s}.
  182.      *
  183.      * @see DisjunctionPremise
  184.      * @param premises the <code>Fn0&lt;Boolean&gt;s</code>.
  185.      * @return a new <code>Fn0&lt;Boolean&gt;s</code> which is the disjunction (OR) of the given premises.
  186.      */
  187.     @SafeVarargs
  188.     @SuppressWarnings("varargs")
  189.     public static DisjunctionPremise anyOf(Fn0<Boolean> ... premises) {
  190.         return new DisjunctionPremise(premises);
  191.     }


  192.     /**
  193.      * Evaluate if all elements satisfies a predicate, i.e. the <em>Universal quantifier function</em>.
  194.      * Note that the predicate
  195.      *
  196.      * @param predicate The predicate which will evaluate all elements.
  197.      * @return a predicate which evaluates to <code>true</code> if all elements evaluates
  198.      *         to true by the given predicate, false if any evaluates to <code>false</code>.
  199.      */
  200.     public static <E, I extends Iterable<E>> Predicate<I> all(final Predicate<? super E> predicate) {
  201.         return new Predicate<I>() { @Override public boolean $(I iterable) {
  202.             return on(iterable).filter(not(predicate)).isEmpty(); }};}


  203.     /**
  204.      * Shorthand for {@link #exists(Predicate) exists(}{@link #equalTo(Object) equalTo(element))}
  205.      *
  206.      * @param element The element to look for in an {@link Iterable}.
  207.      * @return a predicate which evaluates to <code>true</code> if an element equal to the given
  208.      *         element is found, <code>false</code> otherwise.
  209.      */
  210.     public static <E, I extends Iterable<E>> Predicate<I> exists(E element) { return exists(equalTo(element)); }


  211.     /**
  212.      * Evaluate if an element exists, i.e. the <em>Existential quantifier function</em>.
  213.      *
  214.      * @param element The existance-deciding predicate.
  215.      * @return a predicate which evaluates to <code>true</code> if any element evaluates
  216.      *         to true by the given predicate, <code>false</code> otherwise.
  217.      */
  218.     public static <E, I extends Iterable<E>> Predicate<I> exists(final Predicate<? super E> element) {
  219.         return new Predicate<I>() { @Override public boolean $(I iterable) {
  220.             return on(iterable).exists(element); }};}


  221.     /**
  222.      * A synonym for {@link #equalTo(Object)}.
  223.      */
  224.     public static <T> Predicate<T> is(T value) { return equalTo(value); }


  225.     /**
  226.      * Equality predicate, checks if values are equal to the given value.
  227.      *
  228.      * @param value the value the predicate should check for equality against.
  229.      */
  230.     public static <T> Predicate<T> equalTo(final T value) { return equalTo(always(value)); }


  231.     /**
  232.      * Equality predicate, checks if values are equal to the value computed from the given {@link Fn0}.
  233.      *
  234.      * @param value the {@link Fn0} which will compute the value to check for equality against on each
  235.      *              application of the predicate.
  236.      */
  237.     public static <T> Predicate<T> equalTo(final Fn0<? super T> value) {
  238.         return new Predicate<T>() { @Override public boolean $(T input) {
  239.             return Objects.equals(input, value.$()); }}; }


  240.     /**
  241.      * Predicate evaluating if values are less than a given value.
  242.      *
  243.      * @param value the right operand, i.e. the predicate will evaluate
  244.      *              if values are less than this value.
  245.      * @return the "<em>&lt; value</em>" predicate
  246.      */
  247.     public static <T extends Comparable<? super T>> Predicate<T> lessThan(final T value) {
  248.         return new Predicate<T>() { @Override public boolean $(T candidate) { return candidate.compareTo(value) < 0; }}; }


  249.     /**
  250.      * Predicate evaluating if values are equal to or less than a given value.
  251.      *
  252.      * @param value the right operand, i.e. the predicate will evaluate
  253.      *              if values are equal to or less than this value.
  254.      * @return the "<em>=&lt; value</em>" predicate
  255.      */
  256.     public static <T extends Comparable<? super T>> Predicate<T> equalOrLessThan(T value) {
  257.         return either(equalTo(value)).or(lessThan(value)); }



  258.     /**
  259.      * Predicate evaluating if values are greater than a given value.
  260.      *
  261.      * @param value the right operand, i.e. the predicate will evaluate
  262.      *              if values are greater than this value.
  263.      * @return the "<em>&gt; value</em>" predicate
  264.      */
  265.     public static <T extends Comparable<? super T>> Predicate<T> greaterThan(final T value) {
  266.         return new Predicate<T>() { @Override public boolean $(T candidate) { return candidate.compareTo(value) > 0; }}; }


  267.     /**
  268.      * Predicate evaluating if values are equal to or greater than a given value.
  269.      *
  270.      * @param value the right operand, i.e. the predicate will evaluate
  271.      *              if values are equal to or greater than this value.
  272.      * @return the "<em>&gt;= value</em>" predicate
  273.      */
  274.     public static <T extends Comparable<? super T>> Predicate<T> equalOrGreaterThan(T value) {
  275.         return either(equalTo(value)).or(greaterThan(value)); }



  276.     /**
  277.      * Yields <code>true</code> for <code>null</code> values.
  278.      */
  279.     public static final Predicate<Object> isNull = new Predicate<Object>() {
  280.         @Override public boolean $(Object value) { return value == null; }};


  281.     /**
  282.      * Yields <code>true</code> for all non-<code>null</code> values.
  283.      */
  284.     public static final Predicate<Object> notNull = not(isNull);



  285.     /**
  286.      * A function to extract/derive several values from one object. The result of the
  287.      * extraction is an {@link Elements}s container of the least common supertype of
  288.      * the extractor {@link Fn}s' return types.
  289.      *
  290.      * @param extractors the {@link Fn}s which will extract values from each object passed
  291.      *        to the function.
  292.      *
  293.      * @return the composed function which yields.
  294.      */
  295.     @SafeVarargs
  296.     public static <T, E> Fn<T, Elements<E>> extract(final Fn<? super T, ? extends E> ... extractors) {
  297.         return new Fn<T, Elements<E>>() { @Override public Elements<E> $(T value) {
  298.                 return on(new ExtractingIterable<T, E>(value, on(extractors))); }}; }


  299.     /**
  300.      * Yields the {@link String#valueOf(Object) string representation} of
  301.      * any object.
  302.      */
  303.     public static final Fn<Object, String> toString = new Fn<Object, String>() {
  304.         @Override public String $(Object value) { return String.valueOf(value); }};


  305.     /**
  306.      * Yields the {@link Object#hashCode() hashCode} for objects, or 0 if <code>null</code>.
  307.      */
  308.     public static final Fn<Object, Integer> hashCode = new Fn<Object, Integer>() {
  309.         @Override public Integer $(Object o) { return o != null ? o.hashCode() : 0; }};


  310.     /**
  311.      * Creates a "guarded" {@link Fn} using a {@link Predicate} to evaluate if the
  312.      * argument should be passed to the wrapped <code>Fn</code>. The function created
  313.      * by this method is essentially this ternary expression:
  314.      * <pre> condition(v) ? f(v) : null;</pre>
  315.      * To fall back to another value than <code>null</code>, call either {@link When#orElse(Fn) .orElse(Fn)}
  316.      * or {@link When#orElse(Object) .orElse(other)} on the returned object.
  317.      *
  318.      * @param condition Only when this evaluates to <code>true</code> will the function argument
  319.      *                  be applied to the given {@link Fn}.
  320.      * @param fn        The {@link Fn} to apply if <code>condition</code> evaluates to <code>true</code>
  321.      */
  322.     public static <I, O> When<I, O> when(Predicate<? super I> condition, Fn<? super I, ? extends O> fn) {
  323.         return new When<>(condition, fn);
  324.     }


  325.     /**
  326.      * Compose a chain of several functions into one {@link Fn}, where the result of
  327.      * each function is passed to its successor, and the last will yield the
  328.      * actual result of the chain. Use {@link FnChain#then(Fn) .then(Fn)} to append
  329.      * functions to the chain.
  330.      *
  331.      * <p><strong>Note:</strong> The chain does no internal inspection of the intermediate
  332.      * results passed to the next function, which means that any function which may
  333.      * return <code>null</code>, <em>must</em> have a <code>null</code>-safe successor
  334.      * function.
  335.      *
  336.      * @param fn The first function in the chain.
  337.      * @return the given function as the first function in a chain.
  338.      */
  339.     public static final <I, O> FnChain<I, O> first(Fn<I, O> fn) {
  340.         return FnChain.chain(fn);
  341.     }


  342.     /**
  343.      * Compose a chain of several functions into one {@link Fn2}, where the result of
  344.      * each function is passed to its successor, and the last will yield the
  345.      * actual result of the chain. Use {@link Fn2Chain#then(Fn) .then(Fn)} to append
  346.      * functions to the chain.
  347.      *
  348.      * <p><strong>Note:</strong> The chain does no inspection of the intermediate
  349.      * results passed to the next function, which means that any function which may
  350.      * return <code>null</code>, <em>must</em> have a <code>null</code>-safe successor
  351.      * function.
  352.      *
  353.      * @param fn2 The first function in the chain.
  354.      * @return the given function as the first function in a chain.
  355.      */
  356.     public static final <I1, I2, O> Fn2Chain<I1, I2, O, O> first(Fn2<I1, I2, O> fn2) {
  357.         return new Fn2Chain<>(fn2, NOP.<O>fn());
  358.     }


  359.     /**
  360.      * Compose several {@link Runnable}s as a single Runnable which will
  361.      * execute the given Runnables in sequence.
  362.      *
  363.      * @param runnable The first Runnable.
  364.      * @return the given Runnable as the first Runnable in a sequence.
  365.      */
  366.     public static final RunnableChain first(Runnable runnable) {
  367.         return new RunnableChain(runnable, NOP.runnable);
  368.     }


  369.     /**
  370.      * Chain several {@link Do}s to be executed in sequence.
  371.      *
  372.      * @param action The first {@link Do} to execute.
  373.      * @return The given <code>Do</code> as the first <code>Do</code> in a sequence.
  374.      */
  375.     public static <V> DoChain<V> first(Do<V> action) {
  376.         return new DoChain<>(action, NOP.doNothing);
  377.     }


  378.     /**
  379.      * Create a function which always yields the given value.
  380.      *
  381.      * @param value The value to yield.
  382.      */
  383.     public static <I1, I2, V> Constant<I1, I2, V> always(V value) { return new Constant<>(value); }


  384.     /**
  385.      * Create a predicate which always yields the given <code>boolean</code> value.
  386.      *
  387.      * @param bool The <code>boolean</code> value to yield.
  388.      */
  389.     @SuppressWarnings("unchecked")
  390.     public static <T> Predicate<T> always(boolean bool) {
  391.         return (Predicate<T>) (bool ? Predicate.Always.yes() : Predicate.Always.no());
  392.     }



  393.     /**
  394.      * Create a function which always throw the given exception. If the
  395.      * exception is not a {@link RuntimeException} it will be wrapped as such.
  396.      *
  397.      * @param ex The exception to throw.
  398.      */
  399.     public static <I1, I2, O> Throw<I1, I2, O> alwaysThrow(Exception ex) { return new Throw<>(ex); }



  400.     /**
  401.      * Evaluates if objects are contained in the given <code>Iterable</code>.
  402.      */
  403.     public static <T> Predicate<T> containedIn(final Iterable<? extends T> iterable) {
  404.         if (iterable == null) return Always.<T>no();
  405.         if (iterable instanceof Collection) {
  406.             final Collection<? extends T> collection = (Collection<? extends T>) iterable;
  407.             return collection.isEmpty() ? Always.<T>no() : new Predicate<T>() {
  408.                 @Override public boolean $(T value) { return collection.contains(value); }};
  409.         } else {
  410.             final Elements<? extends T> elements = on(iterable);
  411.             return new Predicate<T>() {
  412.                 @Override public boolean $(T value) { return elements.exists(is(value)); }};
  413.         }

  414.     }

  415.     private Base() {}

  416. }