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