Interface Lens<S,T,A,B>
- Type Parameters:
S- the type of the "larger" value for readingT- the type of the "larger" value for puttingA- the type of the "smaller" value that is readB- 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 ClassesModifier and TypeInterfaceDescriptionstatic interfaceA convenience type with a simplified type signature for common lenses with both unified "larger" values and unified "smaller" values. -
Method Summary
Modifier and TypeMethodDescriptionLeft-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.Dually focus on two lenses at the same time.Right-to-Left composition of optics.Contravariantly mapA <- B.Dually map contravariantly over the left parameter and covariantly over the right parameter.Contravariantly map over the left parameter.Covariantly map over the right parameter.Sequence both thisApplicativeandappB, discarding thisApplicative'sresult and returningappB.Sequence both thisApplicativeandappB, discardingappB'sresult and returning thisApplicative.Chain dependent computations that may continue or short-circuit based on previous results.Covariantly transmute this functor's parameter using the given mapping function.static <S,T, A, B> Lens <S, T, A, B> 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> Promote an optic with compatible bounds to aLens.Covariantly mapAtoC, yielding a new optic.Contravariantly mapBtoZ, yielding a new optic.Contravariantly mapStoR, yielding a new optic.Covariantly mapTtoU, yielding a new optic.pure(U u) Lift the valuebinto this applicative functor.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.trampolineM(Fn1<? super T, ? extends MonadRec<RecursiveResult<T, U>, Lens<S, ?, A, B>>> fn) Given some operation yielding aRecursiveResultinside thisMonadRec, internally trampoline the operation until it yields aterminationinstruction.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 Optic
apply, monomorphize
-
Method Details
-
fmap
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:
fmapin interfaceApplicative<S,T> - Specified by:
fmapin interfaceFunctor<S,T> - Specified by:
fmapin interfaceMonad<S,T> - Specified by:
fmapin interfaceMonadRec<S,T> - Type Parameters:
U- the new parameter type- Parameters:
fn- the mapping function- Returns:
- a functor over B (the new parameter type)
-
pure
Lift the valuebinto this applicative functor. -
zip
Given another instance of this applicative over a mapping function, "zip" the two instances together using whatever application semantics the current applicative supports. -
discardL
Sequence both thisApplicativeandappB, discarding thisApplicative'sresult and returningappB. This is generally useful for sequentially performing side-effects. -
discardR
Sequence both thisApplicativeandappB, discardingappB'sresult and returning thisApplicative. This is generally useful for sequentially performing side-effects. -
flatMap
Chain dependent computations that may continue or short-circuit based on previous results. -
trampolineM
default <U> Lens<S,U, trampolineMA, B> (Fn1<? super T, ? extends MonadRec<RecursiveResult<T, U>, Lens<S, ?, A, B>>> fn) Given some operation yielding aRecursiveResultinside thisMonadRec, internally trampoline the operation until it yields aterminationinstruction.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:
trampolineMin interfaceMonadRec<S,T> - Type Parameters:
U- the ultimate resulting carrier type- Parameters:
fn- the function to internally trampoline- Returns:
- the trampolined
MonadRec - See Also:
-
diMapL
Contravariantly map over the left parameter.- Specified by:
diMapLin interfaceProfunctor<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
Covariantly map over the right parameter. For all profunctors that are also functors, it should hold thatdiMapR(f) == fmap(f).- Specified by:
diMapRin interfaceProfunctor<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
Dually map contravariantly over the left parameter and covariantly over the right parameter. This is isomorphic todiMapL(lFn).diMapR(rFn).- Specified by:
diMapin interfaceProfunctor<S,T, A> - Type Parameters:
R- the new left parameter typeU- the new right parameter type- Parameters:
lFn- the left parameter mapping functionrFn- the right parameter mapping function- Returns:
- a profunctor over Z (the new left parameter type) and C (the new right parameter type)
-
contraMap
Contravariantly mapA <- B.- Specified by:
contraMapin interfaceContravariant<S,T> - Specified by:
contraMapin interfaceProfunctor<S,T, A> - Type Parameters:
R- the new parameter type- Parameters:
fn- the mapping function- Returns:
- the mapped Contravariant functor instance
-
mapS
Contravariantly mapStoR, yielding a new optic. -
mapT
Covariantly mapTtoU, yielding a new optic. -
mapA
Covariantly mapAtoC, yielding a new optic. -
mapB
Contravariantly mapBtoZ, yielding a new optic. -
toIso
-
andThen
-
compose
-
lens
static <S,T, Lens<S,A, B> T, lensA, B> (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 readingT- the type of the "larger" value for puttingA- the type of the "smaller" value that is readB- the type of the "smaller" update value- Parameters:
getter- the getter functionsetter- the setter function- Returns:
- the lens
-
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" valuesA- the type of both "smaller" values- Parameters:
getter- the getter functionsetter- the setter function- Returns:
- the lens
-
both
Dually focus on two lenses at the same time. RequiresSandTto be invariant between lenses.- Type Parameters:
S- both larger valuesA- f's smaller viewing valueB- g's smaller viewing valueC- f's smaller setting valueD- g's smaller setting value- Parameters:
f- the first lensg- the second lens- Returns:
- the dual-focus lens
-
both
Dually focus on two simple lenses at the same time.- Type Parameters:
S- both larger valuesA- both smaller viewing valuesB- both smaller setting values- Parameters:
f- the first lensg- the second lens- Returns:
- the dual-focus simple lens
-
pureLens
- Type Parameters:
S- the type of the "larger" value for readingA- the type of the "smaller" value that is readB- the type of the "smaller" update value- Parameters:
sa- the getting function- Returns:
- the
Pureinstance
-