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

fj.data.optic.Getter 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.data.optic;

import fj.F;
import fj.Function;
import fj.Monoid;
import fj.P;
import fj.P2;
import fj.data.Either;

/**
 * A {@link Getter} can be seen as a glorified get method between a type S and a type A.
 *
 * A {@link Getter} is also a valid {@link Fold}
 *
 * @param  the source of a {@link Getter}
 * @param  the target of a {@link Getter}
 */
public abstract class Getter {

  Getter() {
    super();
  }

  /** get the target of a {@link Getter} */
  public abstract A get(S s);

  /** join two {@link Getter} with the same target */
  public final  Getter, A> sum(final Getter other) {
    return getter(e -> e.either(this::get, other::get));
  }

  /** pair two disjoint {@link Getter} */
  public final  Getter, P2> product(final Getter other) {
    return getter(p2 -> P.p(this.get(p2._1()), other.get(p2._2())));
  }

  public final  Getter, P2> first() {
    return getter(p -> P.p(this.get(p._1()), p._2()));
  }

  public final  Getter, P2> second() {
    return getter(p -> P.p(p._1(), this.get(p._2())));
  }

  /*************************************************************/
  /** Compose methods between a {@link Getter} and another Optics */
  /*************************************************************/

  /** compose a {@link Getter} with a {@link Fold} */
  public final  Fold composeFold(final Fold other) {
    return asFold().composeFold(other);
  }

  /** compose a {@link Getter} with a {@link Getter} */
  public final  Getter composeGetter(final Getter other) {
    return getter(s -> other.get(get(s)));
  }

  /** compose a {@link Getter} with a {@link POptional} */
  public final  Fold composeOptional(final POptional other) {
    return asFold().composeOptional(other);
  }

  /** compose a {@link Getter} with a {@link PPrism} */
  public final  Fold composePrism(final PPrism other) {
    return asFold().composePrism(other);
  }

  /** compose a {@link Getter} with a {@link PLens} */
  public final  Getter composeLens(final PLens other) {
    return composeGetter(other.asGetter());
  }

  /** compose a {@link Getter} with a {@link PIso} */
  public final  Getter composeIso(final PIso other) {
    return composeGetter(other.asGetter());
  }

  /******************************************************************/
  /** Transformation methods to view a {@link Getter} as another Optics */
  /******************************************************************/

  /** view a {@link Getter} with a {@link Fold} */
  public final Fold asFold() {
    return new Fold() {
      @Override
      public  F foldMap(final Monoid m, final F f) {
        return s -> f.f(get(s));
      }
    };
  }

  public static  Getter id() {
    return PIso. pId().asGetter();
  }

  public static  Getter, A> codiagonal() {
    return getter(e -> e.either(Function.identity(), Function.identity()));
  }

  public static  Getter getter(final F get) {
    return new Getter() {

      @Override
      public A get(final S s) {
        return get.f(s);
      }
    };
  }
}