All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fj.function.Visitor Maven / Gradle / Ivy

Go to download

Functional Java is an open source library that supports closures for the Java programming language

There is a newer version: 5.0
Show newest version
package fj.function;

import fj.Equal;
import fj.F;
import fj.F0;
import fj.F2;
import fj.Function;
import fj.Monoid;
import fj.P1;
import fj.P2;
import fj.data.List;
import fj.data.Option;
import static fj.Function.compose;
import static fj.Function.curry;
import static fj.data.List.lookup;

/**
 * The essence of the visitor design pattern expressed polymorphically.
 *
 * @version %build.number%
 */
public final class Visitor {
  private Visitor() {
    throw new UnsupportedOperationException();
  }

  /**
   * Returns the first value available in the given list of optional values. If none is found return the given default value.
   *
   * @param values The optional values to search.
   * @param def The default value if no value is found in the list.
   * @return The first value available in the given list of optional values. If none is found return the given default value.
   */
  public static  X findFirst(final List> values, final F0 def) {
    return Monoid.firstOptionMonoid().sumLeft(values).orSome(def);
  }

  /**
   * Returns the first non-null value in the given list of optional values. If none is found return the given default value.
   *
   * @param values The potentially null values to search.
   * @param def The default value if no value is found in the list.
   * @return The first non-null value in the given list of optional values. If none is found return the given default value.
   */
  public static  X nullablefindFirst(final List values, final F0 def) {
    return findFirst(values.map(Option.fromNull()), def);
  }

  /**
   * Returns the first value found in the list of visitors after application of the given value, otherwise returns the
   * given default.
   *
   * @param visitors The list of visitors to apply.
   * @param def The default if none of the visitors yield a value.
   * @param value The value to apply to the visitors.
   * @return The first value found in the list of visitors after application of the given value, otherwise returns the
   * given default.
   */
  public static  B visitor(final List>> visitors, final F0 def, final A value) {
    return findFirst(visitors.map(Function.>apply(value)), def);
  }

  /**
   * Returns the first non-null value found in the list of visitors after application of the given value,
   * otherwise returns the given default.
   *
   * @param visitors The list of visitors to apply looking for a non-null.
   * @param def The default if none of the visitors yield a non-null value.
   * @param value The value to apply to the visitors.
   * @return The first value found in the list of visitors after application of the given value, otherwise returns the
   * given default.
   */
  public static  B nullableVisitor(final List> visitors, final F0 def, final A value) {
    return visitor(visitors.map(new F, F>>() {
      public F> f(final F k) {
        return compose(Option.fromNull(), k);
      }
    }), def, value);
  }

  /**
   * Uses an association list to perform a lookup with equality and returns a function that can be applied to a default,
   * followed by the associated key to return a value.
   *
   * @param x The association list.
   * @param eq The equality for the association list keys.
   * @return A function that can be applied to a default value (there is no association) and an associated key.
   */
  public static  F> association(final List> x, final Equal eq) {
    return curry(new F2() {
      public B f(final B def, final A a) {
        return lookup(eq, x, a).orSome(def);
      }
    });
  }

  /**
   * Uses an association list to perform a lookup with equality and returns a function that can be applied to a default,
   * followed by the associated key to return a value.
   *
   * @param x The association list.
   * @param eq The equality for the association list keys.
   * @return A function that can be applied to a default value (there is no association) and an associated key.
   */
  public static  F, F> associationLazy(final List> x, final Equal eq) {
    return curry(new F2, A, B>() {
      public B f(final P1 def, final A a) {
        return lookup(eq, x, a).orSome(def);
      }
    });
  }
}