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 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 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 thisApplicative
andappB
, discarding thisApplicative's
result and returningappB
.Sequence both thisApplicative
andappB
, discardingappB's
result 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 mapA
toC
, yielding a new optic.Contravariantly mapB
toZ
, yielding a new optic.Contravariantly mapS
toR
, yielding a new optic.Covariantly mapT
toU
, yielding a new optic.pure
(U u) Lift the valueb
into 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 aRecursiveResult
inside thisMonadRec
, internally trampoline the operation until it yields atermination
instruction.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.optics.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:
fmap
in interfaceApplicative<S,
T> - Specified by:
fmap
in interfaceFunctor<S,
T> - Specified by:
fmap
in interfaceMonad<S,
T> - Specified by:
fmap
in 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 valueb
into 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 thisApplicative
andappB
, discarding thisApplicative's
result and returningappB
. This is generally useful for sequentially performing side-effects. -
discardR
Sequence both thisApplicative
andappB
, discardingappB's
result 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 aRecursiveResult
inside thisMonadRec
, internally trampoline the operation until it yields atermination
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 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:
diMapL
in 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:
diMapR
in 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:
diMap
in 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:
contraMap
in interfaceContravariant<S,
T> - Specified by:
contraMap
in interfaceProfunctor<S,
T, A> - Type Parameters:
R
- the new parameter type- Parameters:
fn
- the mapping function- Returns:
- the mapped Contravariant functor instance
-
mapS
Contravariantly mapS
toR
, yielding a new optic. -
mapT
Covariantly mapT
toU
, yielding a new optic. -
mapA
Covariantly mapA
toC
, yielding a new optic. -
mapB
Contravariantly mapB
toZ
, yielding a new optic. -
toIso
- Parameters:
s
- the defaultS
- Returns:
- an
Iso
-
andThen
default <C,D> Lens<S,T, andThenC, D> (Optic<? super Cartesian<?, ?, ?>, ? super Functor<?, ?>, A, B, C, D> f) Left-to-right composition of optics. Requires compatibility betweenS
andT
. -
compose
default <R,U> Lens<R,U, composeA, B> (Optic<? super Cartesian<?, ?, ?>, ? super Functor<?, ?>, R, U, S, T> g) Right-to-Left composition of optics. Requires compatibility betweenA
andB
. -
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
static <S,T, Lens<S,A, B> T, lensA, B> (Optic<? super Cartesian<?, ?, ?>, ? super Functor<?, ?>, S, T, A, B> optic) Promote an optic with compatible bounds to aLens
. -
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. RequiresS
andT
to 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
Pure
instance
-