Interface Lens<S,T,A,B>

Type Parameters:
S - the type of the "larger" value for reading
T - the type of the "larger" value for putting
A - the type of the "smaller" value that is read
B - the type of the "smaller" update value
All Superinterfaces:
Applicative<T,Lens<S,?,A,B>>, Contravariant<S,Profunctor<?,T,Lens<?,?,A,B>>>, Functor<T,Lens<S,?,A,B>>, Monad<T,Lens<S,?,A,B>>, MonadRec<T,Lens<S,?,A,B>>, Optic<Cartesian<?,?,?>,Functor<?,?>,S,T,A,B>, Profunctor<S,T,Lens<?,?,A,B>>
All Known Subinterfaces:
Lens.Simple<S,A>, Schema<Values>
Functional Interface:
This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.

@FunctionalInterface public interface Lens<S,T,A,B> extends Optic<Cartesian<?,?,?>,Functor<?,?>,S,T,A,B>, MonadRec<T,Lens<S,?,A,B>>, Profunctor<S,T,Lens<?,?,A,B>>
An approximation of van Laarhoven lenses.

A "lens" can be considered in its simplest form as the conjugation of a "getter" and a "setter"; that is, a unification type representing the way to retrieve a "smaller" value A from a "larger" value S, as well as a way to update a "smaller" value B of a "larger" value S, producing another "larger" value T.

Consider the following example:

 
 public final class Person {
     private final int age;

     public Person(int age) {
         this.age = age;
     }

     public int getAge() {
         return age;
     }

     public Person setAge(int age) {
         return new Person(age);
     }
 }
 
 
A lens that focused on the age field of an instance of Person might look like this:
 
 Lens<Person, Person, Integer, Integer> ageLens = Lens.lens(Person::getAge, Person::setAge);

 Person adult = new Person(18);
 Integer age = view(ageLens, adult); // 18

 Person olderAdult = set(ageLens, 19, adult);
 Integer olderAge = view(ageLens, olderAdult); // 19
 
 
The pattern of a getter and setter that mutually agree on both A and B as well as on both S and T is so common that this can be given a simplified type signature:
 
 Lens.Simple<Person, Integer> ageLens = Lens.simpleLens(Person::getAge, Person::setAge);

 Person adult = new Person(18);
 Integer age = view(ageLens, adult); // 18

 Person olderAdult = set(ageLens, 19, adult);
 Integer olderAge = view(ageLens, olderAdult); // 19
 
 
However, consider if age could be updated on a Person by being provided a date of birth, in the form of a LocalDate:
 
 public final class Person {
     private final int age;

     public Person(int age) {
         this.age = age;
     }

     public int getAge() {
         return age;
     }

     public Person setAge(int age) {
         return new Person(age);
     }

     public Person setAge(LocalDate dob) {
         return setAge((int) YEARS.between(dob, LocalDate.now()));
     }
 }
 
 
This is why Lens has both an A and a B: A is the value for "getting", and B is the potentially different value for "setting". This distinction makes lenses powerful enough to express the more complicated setAge case naturally:
 
 Lens<Person, Person, Integer, LocalDate> ageDobLens = Lens.lens(Person::getAge, Person::setAge);

 Person adult = new Person(18);
 Integer age = view(ageDobLens, adult); // 18

 Person olderAdult = set(ageDobLens, LocalDate.of(1997, 1, 1), adult);
 Integer olderAge = view(ageDobLens, olderAdult); // 19 at the time of this writing...anyone else feel old?
 
 
Additionally, we might imagine a lens that produces a different "larger" value on updating than what was given. Consider a lens that reads the first string from a list, but produces a Set of strings on update:
 
 Lens<List<String>, Set<String>, String, String> lens = Lens.lens(
         l -> l.get(0),
         (l, s) -> {
             List<String> copy = new ArrayList<>(l);
             copy.set(0, s);
             return new HashSet<>(copy);
         });

 String firstElement = view(lens, asList("foo", "bar")); // "foo
 System.out.println(firstElement);

 set(lens, "oof", asList("foo", "bar")); // ["bar", "oof"]
 set(lens, "bar", asList("foo", "bar")); // ["bar"]
 
 
For more information, learn about lenses.
See Also:
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Interface
    Description
    static interface 
    A convenience type with a simplified type signature for common lenses with both unified "larger" values and unified "smaller" values.
  • Method Summary

    Modifier and Type
    Method
    Description
    default <C, D> Lens<S,T,C,D>
    andThen(Optic<? super Cartesian<?,?,?>,? super Functor<?,?>,A,B,C,D> f)
    Left-to-right composition of optics.
    static <S, A, B> Lens.Simple<S,Tuple2<A,B>>
    both(Lens.Simple<S,A> f, Lens.Simple<S,B> g)
    Dually focus on two simple lenses at the same time.
    static <S, A, B, C, D>
    Lens<S,S,Tuple2<A,B>,Tuple2<C,D>>
    both(Lens<S,S,A,C> f, Lens<S,S,B,D> g)
    Dually focus on two lenses at the same time.
    default <R, U> Lens<R,U,A,B>
    compose(Optic<? super Cartesian<?,?,?>,? super Functor<?,?>,R,U,S,T> g)
    Right-to-Left composition of optics.
    default <R> Lens<R,T,A,B>
    contraMap(Fn1<? super R,? extends S> fn)
    Contravariantly map A <- B.
    default <R, U> Lens<R,U,A,B>
    diMap(Fn1<? super R,? extends S> lFn, Fn1<? super T,? extends U> rFn)
    Dually map contravariantly over the left parameter and covariantly over the right parameter.
    default <R> Lens<R,T,A,B>
    diMapL(Fn1<? super R,? extends S> fn)
    Contravariantly map over the left parameter.
    default <U> Lens<S,U,A,B>
    diMapR(Fn1<? super T,? extends U> fn)
    Covariantly map over the right parameter.
    default <U> Lens<S,U,A,B>
    discardL(Applicative<U,Lens<S,?,A,B>> appB)
    Sequence both this Applicative and appB, discarding this Applicative's result and returning appB.
    default <U> Lens<S,T,A,B>
    discardR(Applicative<U,Lens<S,?,A,B>> appB)
    Sequence both this Applicative and appB, discarding appB's result and returning this Applicative.
    default <U> Lens<S,U,A,B>
    flatMap(Fn1<? super T,? extends Monad<U,Lens<S,?,A,B>>> f)
    Chain dependent computations that may continue or short-circuit based on previous results.
    default <U> Lens<S,U,A,B>
    fmap(Fn1<? super T,? extends U> fn)
    Covariantly transmute this functor's parameter using the given mapping function.
    static <S, T, A, B>
    Lens<S,T,A,B>
    lens(Fn1<? super S,? extends A> getter, Fn2<? super S,? super B,? extends T> setter)
    Static factory method for creating a lens from a getter function and a setter function.
    static <S, T, A, B>
    Lens<S,T,A,B>
    lens(Optic<? super Cartesian<?,?,?>,? super Functor<?,?>,S,T,A,B> optic)
    Promote an optic with compatible bounds to a Lens.
    default <C> Lens<S,T,C,B>
    mapA(Fn1<? super A,? extends C> fn)
    Covariantly map A to C, yielding a new optic.
    default <Z> Lens<S,T,A,Z>
    mapB(Fn1<? super Z,? extends B> fn)
    Contravariantly map B to Z, yielding a new optic.
    default <R> Lens<R,T,A,B>
    mapS(Fn1<? super R,? extends S> fn)
    Contravariantly map S to R, yielding a new optic.
    default <U> Lens<S,U,A,B>
    mapT(Fn1<? super T,? extends U> fn)
    Covariantly map T to U, yielding a new optic.
    default <U> Lens<S,U,A,B>
    pure(U u)
    Lift the value b into this applicative functor.
    static <S, A, B> Pure<Lens<S,?,A,B>>
    pureLens(Fn1<? super S,? extends A> sa)
    The canonical Pure instance for Lens.
    static <S, A> Lens.Simple<S,A>
    simpleLens(Fn1<? super S,? extends A> getter, Fn2<? super S,? super A,? extends S> setter)
    Static factory method for creating a simple lens from a getter function and a setter function.
    default Iso<S,T,A,B>
    toIso(S s)
    Produce an Iso from this Lens by providing a default S value.
    default <U> Lens<S,U,A,B>
    trampolineM(Fn1<? super T,? extends MonadRec<RecursiveResult<T,U>,Lens<S,?,A,B>>> fn)
    Given some operation yielding a RecursiveResult inside this MonadRec, internally trampoline the operation until it yields a termination instruction.
    default <U> Lens<S,U,A,B>
    zip(Applicative<Fn1<? super T,? extends U>,Lens<S,?,A,B>> appFn)
    Given another instance of this applicative over a mapping function, "zip" the two instances together using whatever application semantics the current applicative supports.

    Methods inherited from interface com.jnape.palatable.lambda.functor.Functor

    coerce

    Methods inherited from interface com.jnape.palatable.lambda.monad.MonadRec

    lazyZip

    Methods inherited from interface com.jnape.palatable.lambda.optics.Optic

    apply, monomorphize
  • Method Details

    • fmap

      default <U> Lens<S,U,A,B> fmap(Fn1<? super T,? extends U> fn)
      Covariantly transmute this functor's parameter using the given mapping function. Generally this method is specialized to return an instance of the class implementing Functor.
      Specified by:
      fmap in interface Applicative<S,T>
      Specified by:
      fmap in interface Functor<S,T>
      Specified by:
      fmap in interface Monad<S,T>
      Specified by:
      fmap in interface MonadRec<S,T>
      Type Parameters:
      U - the new parameter type
      Parameters:
      fn - the mapping function
      Returns:
      a functor over B (the new parameter type)
    • pure

      default <U> Lens<S,U,A,B> pure(U u)
      Lift the value b into this applicative functor.
      Specified by:
      pure in interface Applicative<S,T>
      Specified by:
      pure in interface Monad<S,T>
      Specified by:
      pure in interface MonadRec<S,T>
      Type Parameters:
      U - the type of the returned applicative's parameter
      Parameters:
      u - the value
      Returns:
      an instance of this applicative over b
    • zip

      default <U> Lens<S,U,A,B> zip(Applicative<Fn1<? super T,? extends U>,Lens<S,?,A,B>> appFn)
      Given another instance of this applicative over a mapping function, "zip" the two instances together using whatever application semantics the current applicative supports.
      Specified by:
      zip in interface Applicative<S,T>
      Specified by:
      zip in interface Monad<S,T>
      Specified by:
      zip in interface MonadRec<S,T>
      Type Parameters:
      U - the resulting applicative parameter type
      Parameters:
      appFn - the other applicative instance
      Returns:
      the mapped applicative
    • discardL

      default <U> Lens<S,U,A,B> discardL(Applicative<U,Lens<S,?,A,B>> appB)
      Sequence both this Applicative and appB, discarding this Applicative's result and returning appB. This is generally useful for sequentially performing side-effects.
      Specified by:
      discardL in interface Applicative<S,T>
      Specified by:
      discardL in interface Monad<S,T>
      Specified by:
      discardL in interface MonadRec<S,T>
      Type Parameters:
      U - the type of the returned Applicative's parameter
      Parameters:
      appB - the other Applicative
      Returns:
      appB
    • discardR

      default <U> Lens<S,T,A,B> discardR(Applicative<U,Lens<S,?,A,B>> appB)
      Sequence both this Applicative and appB, discarding appB's result and returning this Applicative. This is generally useful for sequentially performing side-effects.
      Specified by:
      discardR in interface Applicative<S,T>
      Specified by:
      discardR in interface Monad<S,T>
      Specified by:
      discardR in interface MonadRec<S,T>
      Type Parameters:
      U - the type of appB's parameter
      Parameters:
      appB - the other Applicative
      Returns:
      this Applicative
    • flatMap

      default <U> Lens<S,U,A,B> flatMap(Fn1<? super T,? extends Monad<U,Lens<S,?,A,B>>> f)
      Chain dependent computations that may continue or short-circuit based on previous results.
      Specified by:
      flatMap in interface Monad<S,T>
      Specified by:
      flatMap in interface MonadRec<S,T>
      Type Parameters:
      U - the resulting monad parameter type
      Parameters:
      f - the dependent computation over A
      Returns:
      the new monad instance
    • trampolineM

      default <U> Lens<S,U,A,B> trampolineM(Fn1<? super T,? extends MonadRec<RecursiveResult<T,U>,Lens<S,?,A,B>>> fn)
      Given some operation yielding a RecursiveResult inside this MonadRec, internally trampoline the operation until it yields a termination instruction.

      Stack-safety depends on implementations guaranteeing that the growth of the call stack is a constant factor independent of the number of invocations of the operation. For various examples of how this can be achieved in stereotypical circumstances, see the referenced types.

      Specified by:
      trampolineM in interface MonadRec<S,T>
      Type Parameters:
      U - the ultimate resulting carrier type
      Parameters:
      fn - the function to internally trampoline
      Returns:
      the trampolined MonadRec
      See Also:
    • diMapL

      default <R> Lens<R,T,A,B> diMapL(Fn1<? super R,? extends S> fn)
      Contravariantly map over the left parameter.
      Specified by:
      diMapL in interface Profunctor<S,T,A>
      Type Parameters:
      R - the new left parameter type
      Parameters:
      fn - the mapping function
      Returns:
      a profunctor over Z (the new left parameter type) and C (the same right parameter type)
    • diMapR

      default <U> Lens<S,U,A,B> diMapR(Fn1<? super T,? extends U> fn)
      Covariantly map over the right parameter. For all profunctors that are also functors, it should hold that diMapR(f) == fmap(f).
      Specified by:
      diMapR in interface Profunctor<S,T,A>
      Type Parameters:
      U - the new right parameter type
      Parameters:
      fn - the mapping function
      Returns:
      a profunctor over A (the same left parameter type) and C (the new right parameter type)
    • diMap

      default <R, U> Lens<R,U,A,B> diMap(Fn1<? super R,? extends S> lFn, Fn1<? super T,? extends U> rFn)
      Dually map contravariantly over the left parameter and covariantly over the right parameter. This is isomorphic to diMapL(lFn).diMapR(rFn).
      Specified by:
      diMap in interface Profunctor<S,T,A>
      Type Parameters:
      R - the new left parameter type
      U - the new right parameter type
      Parameters:
      lFn - the left parameter mapping function
      rFn - the right parameter mapping function
      Returns:
      a profunctor over Z (the new left parameter type) and C (the new right parameter type)
    • contraMap

      default <R> Lens<R,T,A,B> contraMap(Fn1<? super R,? extends S> fn)
      Contravariantly map A <- B.
      Specified by:
      contraMap in interface Contravariant<S,T>
      Specified by:
      contraMap in interface Profunctor<S,T,A>
      Type Parameters:
      R - the new parameter type
      Parameters:
      fn - the mapping function
      Returns:
      the mapped Contravariant functor instance
    • mapS

      default <R> Lens<R,T,A,B> mapS(Fn1<? super R,? extends S> fn)
      Contravariantly map S to R, yielding a new optic.
      Specified by:
      mapS in interface Optic<Cartesian<?,?,?>,Functor<?,?>,S,T,A,B>
      Type Parameters:
      R - the new left side of the output profunctor
      Parameters:
      fn - the mapping function
      Returns:
      the new optic
    • mapT

      default <U> Lens<S,U,A,B> mapT(Fn1<? super T,? extends U> fn)
      Covariantly map T to U, yielding a new optic.
      Specified by:
      mapT in interface Optic<Cartesian<?,?,?>,Functor<?,?>,S,T,A,B>
      Type Parameters:
      U - the new right side's functor embedding of the output profunctor
      Parameters:
      fn - the mapping function
      Returns:
      the new optic
    • mapA

      default <C> Lens<S,T,C,B> mapA(Fn1<? super A,? extends C> fn)
      Covariantly map A to C, yielding a new optic.
      Specified by:
      mapA in interface Optic<Cartesian<?,?,?>,Functor<?,?>,S,T,A,B>
      Type Parameters:
      C - the new left side of the input profunctor
      Parameters:
      fn - the mapping function
      Returns:
      the new optic
    • mapB

      default <Z> Lens<S,T,A,Z> mapB(Fn1<? super Z,? extends B> fn)
      Contravariantly map B to Z, yielding a new optic.
      Specified by:
      mapB in interface Optic<Cartesian<?,?,?>,Functor<?,?>,S,T,A,B>
      Type Parameters:
      Z - the new right side's functor embedding of the input profunctor
      Parameters:
      fn - the mapping function
      Returns:
      the new optic
    • toIso

      default Iso<S,T,A,B> toIso(S s)
      Produce an Iso from this Lens by providing a default S value.
      Parameters:
      s - the default S
      Returns:
      an Iso
    • andThen

      default <C, D> Lens<S,T,C,D> andThen(Optic<? super Cartesian<?,?,?>,? super Functor<?,?>,A,B,C,D> f)
      Left-to-right composition of optics. Requires compatibility between S and T.
      Specified by:
      andThen in interface Optic<Cartesian<?,?,?>,Functor<?,?>,S,T,A,B>
      Type Parameters:
      C - the new left side of the input profunctor
      D - the new right side's functor embedding of the input profunctor
      Parameters:
      f - the other optic
      Returns:
      the composed optic
    • compose

      default <R, U> Lens<R,U,A,B> compose(Optic<? super Cartesian<?,?,?>,? super Functor<?,?>,R,U,S,T> g)
      Right-to-Left composition of optics. Requires compatibility between A and B.
      Specified by:
      compose in interface Optic<Cartesian<?,?,?>,Functor<?,?>,S,T,A,B>
      Type Parameters:
      R - the new left side of the output profunctor
      U - the new right side's functor embedding of the output profunctor
      Parameters:
      g - the other optic
      Returns:
      the composed optic
    • lens

      static <S, T, A, B> Lens<S,T,A,B> lens(Fn1<? super S,? extends A> getter, Fn2<? super S,? super B,? extends T> setter)
      Static factory method for creating a lens from a getter function and a setter function.
      Type Parameters:
      S - the type of the "larger" value for reading
      T - the type of the "larger" value for putting
      A - the type of the "smaller" value that is read
      B - the type of the "smaller" update value
      Parameters:
      getter - the getter function
      setter - the setter function
      Returns:
      the lens
    • lens

      static <S, T, A, B> Lens<S,T,A,B> lens(Optic<? super Cartesian<?,?,?>,? super Functor<?,?>,S,T,A,B> optic)
      Promote an optic with compatible bounds to a Lens.
      Type Parameters:
      S - the type of the "larger" value for reading
      T - the type of the "larger" value for putting
      A - the type of the "smaller" value that is read
      B - the type of the "smaller" update value
      Parameters:
      optic - the Optic
      Returns:
      the Lens
    • simpleLens

      static <S, A> Lens.Simple<S,A> simpleLens(Fn1<? super S,? extends A> getter, Fn2<? super S,? super A,? extends S> setter)
      Static factory method for creating a simple lens from a getter function and a setter function.
      Type Parameters:
      S - the type of both "larger" values
      A - the type of both "smaller" values
      Parameters:
      getter - the getter function
      setter - the setter function
      Returns:
      the lens
    • both

      static <S, A, B, C, D> Lens<S,S,Tuple2<A,B>,Tuple2<C,D>> both(Lens<S,S,A,C> f, Lens<S,S,B,D> g)
      Dually focus on two lenses at the same time. Requires S and T to be invariant between lenses.
      Type Parameters:
      S - both larger values
      A - f's smaller viewing value
      B - g's smaller viewing value
      C - f's smaller setting value
      D - g's smaller setting value
      Parameters:
      f - the first lens
      g - the second lens
      Returns:
      the dual-focus lens
    • both

      static <S, A, B> Lens.Simple<S,Tuple2<A,B>> both(Lens.Simple<S,A> f, Lens.Simple<S,B> g)
      Dually focus on two simple lenses at the same time.
      Type Parameters:
      S - both larger values
      A - both smaller viewing values
      B - both smaller setting values
      Parameters:
      f - the first lens
      g - the second lens
      Returns:
      the dual-focus simple lens
    • pureLens

      static <S, A, B> Pure<Lens<S,?,A,B>> pureLens(Fn1<? super S,? extends A> sa)
      The canonical Pure instance for Lens.
      Type Parameters:
      S - the type of the "larger" value for reading
      A - the type of the "smaller" value that is read
      B - the type of the "smaller" update value
      Parameters:
      sa - the getting function
      Returns:
      the Pure instance