1
1
package com .jnape .palatable .lambda .lens ;
2
2
3
+ import com .jnape .palatable .lambda .adt .hlist .Tuple2 ;
4
+ import com .jnape .palatable .lambda .functions .Fn1 ;
3
5
import com .jnape .palatable .lambda .functions .Fn2 ;
6
+ import com .jnape .palatable .lambda .functions .builtin .fn2 .Both ;
4
7
import com .jnape .palatable .lambda .functor .Applicative ;
5
8
import com .jnape .palatable .lambda .functor .Functor ;
6
9
import com .jnape .palatable .lambda .functor .Profunctor ;
@@ -311,6 +314,23 @@ static <S, A> Lens.Simple<S, A> simpleLens(Function<? super S, ? extends A> gett
311
314
return adapt (lens (getter , setter ));
312
315
}
313
316
317
+ /**
318
+ * Dually focus on two lenses at the same time. Requires <code>S</code> and <code>T</code> to be invariant between
319
+ * lenses.
320
+ *
321
+ * @param f the first lens
322
+ * @param g the second lens
323
+ * @param <S> both larger values
324
+ * @param <A> f's smaller viewing value
325
+ * @param <B> g's smaller viewing value
326
+ * @param <C> f's smaller setting value
327
+ * @param <D> g's smaller setting value
328
+ * @return the dual-focus lens
329
+ */
330
+ 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 ) {
331
+ return lens (Both .both (view (f ), view (g )), (s , cd ) -> cd .biMap (set (f ), set (g )).into (Fn1 ::compose ).apply (s ));
332
+ }
333
+
314
334
/**
315
335
* A convenience type with a simplified type signature for common lenses with both unified "larger" values and
316
336
* unified "smaller" values.
@@ -335,11 +355,32 @@ default <B> Lens.Simple<S, B> andThen(Lens.Simple<A, B> f) {
335
355
return f .compose (this );
336
356
}
337
357
358
+ /**
359
+ * Adapt a {@link Lens} with the right variance to a {@link Lens.Simple}.
360
+ *
361
+ * @param lens the lens
362
+ * @param <S> S/T
363
+ * @param <A> A/B
364
+ * @return the simple lens
365
+ */
338
366
@ SuppressWarnings ("unchecked" )
339
367
static <S , A > Simple <S , A > adapt (Lens <S , S , A , A > lens ) {
340
368
return lens ::apply ;
341
369
}
342
370
371
+ /**
372
+ * Specialization of {@link Lens#both(Lens, Lens)} for simple lenses.
373
+ *
374
+ * @param f the first lens
375
+ * @param g the second lens
376
+ * @param <S> both lens larger values
377
+ * @param <A> both lens smaller values
378
+ * @return the dual-focus simple lens
379
+ */
380
+ static <S , A > Lens .Simple <S , Tuple2 <A , A >> both (Lens <S , S , A , A > f , Lens <S , S , A , A > g ) {
381
+ return adapt (Lens .both (f , g ));
382
+ }
383
+
343
384
/**
344
385
* A convenience type with a simplified type signature for fixed simple lenses.
345
386
*
0 commit comments