1 package io.atlassian.fugue.optic;
2
3 import io.atlassian.fugue.*;
4
5 import java.util.function.BinaryOperator;
6 import java.util.function.Function;
7 import java.util.function.Supplier;
8 import java.util.stream.Stream;
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 public abstract class PIso<S, T, A, B> {
44
45 PIso() {
46 super();
47 }
48
49
50
51
52 public abstract A get(S s);
53
54
55
56
57 public abstract T reverseGet(B b);
58
59
60
61
62
63 public abstract PIso<B, A, T, S> reverse();
64
65
66
67
68
69 public final <C> Function<S, Function<C, T>> modifyFunctionF(final Function<A, Function<C, B>> f) {
70 return s -> f.apply(get(s)).andThen(this::reverseGet);
71 }
72
73
74
75
76
77 public final <L> Function<S, Either<L, T>> modifyEitherF(final Function<A, Either<L, B>> f) {
78 return s -> f.apply(get(s)).right().map(this::reverseGet);
79 }
80
81
82
83
84
85 public final Function<S, Option<T>> modifyOptionF(final Function<A, Option<B>> f) {
86 return s -> f.apply(get(s)).map(this::reverseGet);
87 }
88
89
90
91
92
93 public final Function<S, Iterable<T>> modifyIterableF(final Function<A, Iterable<B>> f) {
94 return s -> Iterables.map(f.apply(get(s)), this::reverseGet);
95 }
96
97
98
99
100
101 public final Function<S, Supplier<T>> modifySupplierF(final Function<A, Supplier<B>> f) {
102 return s -> Suppliers.compose(this::reverseGet, f.apply(get(s)));
103 }
104
105
106
107
108
109 public final Function<S, Pair<T, T>> modifyPairF(final Function<A, Pair<B, B>> f) {
110 return s -> Pair.map(f.apply(get(s)), this::reverseGet);
111 }
112
113
114
115
116 public final Function<S, T> modify(final Function<A, B> f) {
117 return s -> reverseGet(f.apply(get(s)));
118 }
119
120
121
122
123 public final Function<S, T> set(final B b) {
124 return __ -> reverseGet(b);
125 }
126
127
128
129
130 public <S1, T1, A1, B1> PIso<Pair<S, S1>, Pair<T, T1>, Pair<A, A1>, Pair<B, B1>> product(final PIso<S1, T1, A1, B1> other) {
131 return pIso(ss1 -> Pair.pair(get(ss1.left()), other.get(ss1.right())), bb1 -> Pair.pair(reverseGet(bb1.left()), other.reverseGet(bb1.right())));
132 }
133
134 public <C> PIso<Pair<S, C>, Pair<T, C>, Pair<A, C>, Pair<B, C>> first() {
135 return pIso(sc -> Pair.pair(get(sc.left()), sc.right()), bc -> Pair.pair(reverseGet(bc.left()), bc.right()));
136 }
137
138 public <C> PIso<Pair<C, S>, Pair<C, T>, Pair<C, A>, Pair<C, B>> second() {
139 return pIso(cs -> Pair.pair(cs.left(), get(cs.right())), cb -> Pair.pair(cb.left(), reverseGet(cb.right())));
140 }
141
142
143
144
145
146
147
148
149 public final <C> Fold<S, C> composeFold(final Fold<A, C> other) {
150 return asFold().composeFold(other);
151 }
152
153
154
155
156 public final <C> Getter<S, C> composeGetter(final Getter<A, C> other) {
157 return asGetter().composeGetter(other);
158 }
159
160
161
162
163 public final <C, D> PSetter<S, T, C, D> composeSetter(final PSetter<A, B, C, D> other) {
164 return asSetter().composeSetter(other);
165 }
166
167
168
169
170 public final <C, D> PTraversal<S, T, C, D> composeTraversal(final PTraversal<A, B, C, D> other) {
171 return asTraversal().composeTraversal(other);
172 }
173
174
175
176
177 public final <C, D> POptional<S, T, C, D> composeOptional(final POptional<A, B, C, D> other) {
178 return asOptional().composeOptional(other);
179 }
180
181
182
183
184 public final <C, D> PPrism<S, T, C, D> composePrism(final PPrism<A, B, C, D> other) {
185 return asPrism().composePrism(other);
186 }
187
188
189
190
191 public final <C, D> PLens<S, T, C, D> composeLens(final PLens<A, B, C, D> other) {
192 return asLens().composeLens(other);
193 }
194
195
196
197
198 public final <C, D> PIso<S, T, C, D> composeIso(final PIso<A, B, C, D> other) {
199 final PIso<S, T, A, B> self = this;
200 return new PIso<S, T, C, D>() {
201 @Override public C get(final S s) {
202 return other.get(self.get(s));
203 }
204
205 @Override public T reverseGet(final D d) {
206 return self.reverseGet(other.reverseGet(d));
207 }
208
209 @Override public PIso<D, C, T, S> reverse() {
210 final PIso<S, T, C, D> composeSelf = this;
211 return new PIso<D, C, T, S>() {
212 @Override public T get(final D d) {
213 return self.reverseGet(other.reverseGet(d));
214 }
215
216 @Override public C reverseGet(final S s) {
217 return other.get(self.get(s));
218 }
219
220 @Override public PIso<S, T, C, D> reverse() {
221 return composeSelf;
222 }
223 };
224 }
225 };
226 }
227
228
229
230
231
232
233
234
235 public final Fold<S, A> asFold() {
236 return new Fold<S, A>() {
237 @Override public <M> Function<S, M> foldMap(final Monoid<M> monoid, final Function<A, M> f) {
238 return s -> f.apply(PIso.this.get(s));
239 }
240 };
241 }
242
243
244
245
246 public final Getter<S, A> asGetter() {
247 return new Getter<S, A>() {
248 @Override public A get(final S s) {
249 return PIso.this.get(s);
250 }
251 };
252 }
253
254
255
256
257 public PSetter<S, T, A, B> asSetter() {
258 return new PSetter<S, T, A, B>() {
259 @Override public Function<S, T> modify(final Function<A, B> f) {
260 return PIso.this.modify(f);
261 }
262
263 @Override public Function<S, T> set(final B b) {
264 return PIso.this.set(b);
265 }
266 };
267 }
268
269
270
271
272 public PTraversal<S, T, A, B> asTraversal() {
273 final PIso<S, T, A, B> self = this;
274 return new PTraversal<S, T, A, B>() {
275
276 @Override public <C> Function<S, Function<C, T>> modifyFunctionF(final Function<A, Function<C, B>> f) {
277 return self.modifyFunctionF(f);
278 }
279
280 @Override public <L> Function<S, Either<L, T>> modifyEitherF(final Function<A, Either<L, B>> f) {
281 return self.modifyEitherF(f);
282 }
283
284 @Override public Function<S, Option<T>> modifyOptionF(final Function<A, Option<B>> f) {
285 return self.modifyOptionF(f);
286 }
287
288 @Override public Function<S, Iterable<T>> modifyIterableF(final Function<A, Iterable<B>> f) {
289 return self.modifyIterableF(f);
290 }
291
292 @Override public Function<S, Supplier<T>> modifySupplierF(final Function<A, Supplier<B>> f) {
293 return self.modifySupplierF(f);
294 }
295
296 @Override public Function<S, Pair<T, T>> modifyPairF(final Function<A, Pair<B, B>> f) {
297 return self.modifyPairF(f);
298 }
299
300 @Override public <M> Function<S, M> foldMap(final Monoid<M> monoid, final Function<A, M> f) {
301 return s -> f.apply(self.get(s));
302 }
303
304 };
305 }
306
307
308
309
310 public POptional<S, T, A, B> asOptional() {
311 final PIso<S, T, A, B> self = this;
312 return new POptional<S, T, A, B>() {
313 @Override public Either<T, A> getOrModify(final S s) {
314 return Either.right(self.get(s));
315 }
316
317 @Override public <C> Function<S, Function<C, T>> modifyFunctionF(final Function<A, Function<C, B>> f) {
318 return self.modifyFunctionF(f);
319 }
320
321 @Override public <L> Function<S, Either<L, T>> modifyEitherF(final Function<A, Either<L, B>> f) {
322 return self.modifyEitherF(f);
323 }
324
325 @Override public Function<S, Option<T>> modifyOptionF(final Function<A, Option<B>> f) {
326 return self.modifyOptionF(f);
327 }
328
329 @Override public Function<S, Iterable<T>> modifyIterableF(final Function<A, Iterable<B>> f) {
330 return self.modifyIterableF(f);
331 }
332
333 @Override public Function<S, Supplier<T>> modifySupplierF(final Function<A, Supplier<B>> f) {
334 return self.modifySupplierF(f);
335 }
336
337 @Override public Function<S, Pair<T, T>> modifyPairF(final Function<A, Pair<B, B>> f) {
338 return self.modifyPairF(f);
339 }
340
341 @Override public Function<S, T> set(final B b) {
342 return self.set(b);
343 }
344
345 @Override public Option<A> getOption(final S s) {
346 return Option.some(self.get(s));
347 }
348
349 @Override public Function<S, T> modify(final Function<A, B> f) {
350 return self.modify(f);
351 }
352 };
353 }
354
355
356
357
358 public PPrism<S, T, A, B> asPrism() {
359 final PIso<S, T, A, B> self = this;
360 return new PPrism<S, T, A, B>() {
361 @Override public Either<T, A> getOrModify(final S s) {
362 return Either.right(self.get(s));
363 }
364
365 @Override public T reverseGet(final B b) {
366 return self.reverseGet(b);
367 }
368
369 @Override public Option<A> getOption(final S s) {
370 return Option.some(self.get(s));
371 }
372 };
373 }
374
375
376
377
378 public PLens<S, T, A, B> asLens() {
379 final PIso<S, T, A, B> self = this;
380 return new PLens<S, T, A, B>() {
381 @Override public A get(final S s) {
382 return self.get(s);
383 }
384
385 @Override public Function<S, T> set(final B b) {
386 return self.set(b);
387 }
388
389 @Override public Function<S, T> modify(final Function<A, B> f) {
390 return self.modify(f);
391 }
392
393 @Override public <C> Function<S, Function<C, T>> modifyFunctionF(final Function<A, Function<C, B>> f) {
394 return self.modifyFunctionF(f);
395 }
396
397 @Override public <L> Function<S, Either<L, T>> modifyEitherF(final Function<A, Either<L, B>> f) {
398 return self.modifyEitherF(f);
399 }
400
401 @Override public Function<S, Option<T>> modifyOptionF(final Function<A, Option<B>> f) {
402 return self.modifyOptionF(f);
403 }
404
405 @Override public Function<S, Iterable<T>> modifyIterableF(final Function<A, Iterable<B>> f) {
406 return self.modifyIterableF(f);
407 }
408
409 @Override public Function<S, Supplier<T>> modifySupplierF(final Function<A, Supplier<B>> f) {
410 return self.modifySupplierF(f);
411 }
412
413 @Override public Function<S, Pair<T, T>> modifyPairF(final Function<A, Pair<B, B>> f) {
414 return self.modifyPairF(f);
415 }
416
417 };
418 }
419
420
421
422
423
424 public static <S, T, A, B> PIso<S, T, A, B> pIso(final Function<S, A> get, final Function<B, T> reverseGet) {
425 return new PIso<S, T, A, B>() {
426
427 @Override public A get(final S s) {
428 return get.apply(s);
429 }
430
431 @Override public T reverseGet(final B b) {
432 return reverseGet.apply(b);
433 }
434
435 @Override public PIso<B, A, T, S> reverse() {
436 final PIso<S, T, A, B> self = this;
437 return new PIso<B, A, T, S>() {
438 @Override public T get(final B b) {
439 return reverseGet.apply(b);
440 }
441
442 @Override public A reverseGet(final S s) {
443 return get.apply(s);
444 }
445
446 @Override public PIso<S, T, A, B> reverse() {
447 return self;
448 }
449 };
450 }
451
452 };
453 }
454
455
456
457
458
459
460
461
462
463
464
465
466
467 public static <S, T> PIso<S, T, S, T> pId() {
468 return new PIso<S, T, S, T>() {
469
470 @Override public S get(final S s) {
471 return s;
472 }
473
474 @Override public T reverseGet(final T t) {
475 return t;
476 }
477
478 @Override public PIso<T, S, T, S> reverse() {
479 final PIso<S, T, S, T> self = this;
480 return new PIso<T, S, T, S>() {
481 @Override public T get(final T t) {
482 return t;
483 }
484
485 @Override public S reverseGet(final S s) {
486 return s;
487 }
488
489 @Override public PIso<S, T, S, T> reverse() {
490 return self;
491 }
492 };
493 }
494 };
495 }
496
497 }