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:
    Optic, Iso
    • Nested Class Summary

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

      All Methods Static Methods Instance Methods Default Methods 
      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
    • Method Detail

      • 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
      • 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