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

fj.data.optic.PSetter Maven / Gradle / Ivy

package fj.data.optic;

import fj.F;
import fj.Function;
import fj.data.Either;

/**
 * A {@link PSetter} is a generalisation of Functor map:
    *
  • {@code map: (A => B) => F[A] => F[B]}
  • *
  • {@code modify: (A => B) => S => T}
  • *
*

* {@link PSetter} stands for Polymorphic Setter as it set and modify methods change a type {@code A} to {@code B} and {@code S} to {@code T}.

*

* {@link PTraversal}, {@link POptional}, {@link PPrism}, {@link PLens} and {@link PIso} are valid {@link PSetter}

* * @param the source of a {@link PSetter} * @param the modified source of a {@link PSetter} * @param the target of a {@link PSetter} * @param the modified target of a {@link PSetter} */ public abstract class PSetter { PSetter() { super(); } /** modify polymorphically the target of a {@link PSetter} with a function */ public abstract F modify(F f); /** set polymorphically the target of a {@link PSetter} with a value */ public abstract F set(final B b); /** join two {@link PSetter} with the same target */ public final PSetter, Either, A, B> sum(final PSetter other) { return pSetter(f -> e -> e.bimap(modify(f), other.modify(f))); } /*************************************************************/ /** Compose methods between a {@link PSetter} and another Optics */ /*************************************************************/ /** compose a {@link PSetter} with a {@link PSetter} */ public final PSetter composeSetter(final PSetter other) { final PSetter self = this; return new PSetter() { @Override public F modify(final F f) { return self.modify(other.modify(f)); } @Override public F set(final D d) { return self.modify(other.set(d)); } }; } /** compose a {@link PSetter} with a {@link PTraversal} */ public final PSetter composeTraversal(final PTraversal other) { return composeSetter(other.asSetter()); } /** compose a {@link PSetter} with a {@link POptional} */ public final PSetter composeOptional(final POptional other) { return composeSetter(other.asSetter()); } /** compose a {@link PSetter} with a {@link PPrism} */ public final PSetter composePrism(final PPrism other) { return composeSetter(other.asSetter()); } /** compose a {@link PSetter} with a {@link PLens} */ public final PSetter composeLens(final PLens other) { return composeSetter(other.asSetter()); } /** compose a {@link PSetter} with a {@link PIso} */ public final PSetter composeIso(final PIso other) { return composeSetter(other.asSetter()); } public static PSetter pId() { return PIso. pId().asSetter(); } public static PSetter, Either, S, T> pCodiagonal() { return pSetter(f -> e -> e.bimap(f, f)); } public static PSetter pSetter(final F, F> modify) { return new PSetter() { @Override public F modify(final F f) { return modify.f(f); } @Override public F set(final B b) { return modify.f(Function.constant(b)); } }; } }