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 public abstract class PLens<S, T, A, B> {
34
35 PLens() {
36 super();
37 }
38
39
40
41
42 public abstract A get(S s);
43
44
45
46
47 public abstract Function<S, T> set(B b);
48
49
50
51
52
53 public abstract <C> Function<S, Function<C, T>> modifyFunctionF(Function<A, Function<C, B>> f);
54
55
56
57
58
59 public abstract <L> Function<S, Either<L, T>> modifyEitherF(Function<A, Either<L, B>> f);
60
61
62
63
64
65 public abstract Function<S, Option<T>> modifyOptionF(Function<A, Option<B>> f);
66
67
68
69
70
71 public abstract Function<S, Iterable<T>> modifyIterableF(final Function<A, Iterable<B>> f);
72
73
74
75
76
77 public abstract Function<S, Supplier<T>> modifySupplierF(Function<A, Supplier<B>> f);
78
79
80
81
82
83 public abstract Function<S, Pair<T, T>> modifyPairF(final Function<A, Pair<B, B>> f);
84
85
86
87
88 public abstract Function<S, T> modify(final Function<A, B> f);
89
90
91
92
93 public final <S1, T1> PLens<Either<S, S1>, Either<T, T1>, A, B> sum(final PLens<S1, T1, A, B> other) {
94 return pLens(e -> e.fold(this::get, other::get), b -> e -> e.bimap(PLens.this.set(b), other.set(b)));
95 }
96
97
98
99
100
101
102
103
104 public final <C> Fold<S, C> composeFold(final Fold<A, C> other) {
105 return asFold().composeFold(other);
106 }
107
108
109
110
111 public final <C> Getter<S, C> composeGetter(final Getter<A, C> other) {
112 return asGetter().composeGetter(other);
113 }
114
115
116
117
118 public final <C, D> PSetter<S, T, C, D> composeSetter(final PSetter<A, B, C, D> other) {
119 return asSetter().composeSetter(other);
120 }
121
122
123
124
125 public final <C, D> PTraversal<S, T, C, D> composeTraversal(final PTraversal<A, B, C, D> other) {
126 return asTraversal().composeTraversal(other);
127 }
128
129
130
131
132 public final <C, D> POptional<S, T, C, D> composeOptional(final POptional<A, B, C, D> other) {
133 return asOptional().composeOptional(other);
134 }
135
136
137
138
139 public final <C, D> POptional<S, T, C, D> composePrism(final PPrism<A, B, C, D> other) {
140 return asOptional().composeOptional(other.asOptional());
141 }
142
143
144
145
146 public final <C, D> PLens<S, T, C, D> composeLens(final PLens<A, B, C, D> other) {
147 final PLens<S, T, A, B> self = this;
148 return new PLens<S, T, C, D>() {
149 @Override public C get(final S s) {
150 return other.get(self.get(s));
151 }
152
153 @Override public Function<S, T> set(final D d) {
154 return self.modify(other.set(d));
155 }
156
157 @Override public <G> Function<S, Function<G, T>> modifyFunctionF(final Function<C, Function<G, D>> f) {
158 return self.modifyFunctionF(other.modifyFunctionF(f));
159 }
160
161 @Override public <L> Function<S, Either<L, T>> modifyEitherF(final Function<C, Either<L, D>> f) {
162 return self.modifyEitherF(other.modifyEitherF(f));
163 }
164
165 @Override public Function<S, Option<T>> modifyOptionF(final Function<C, Option<D>> f) {
166 return self.modifyOptionF(other.modifyOptionF(f));
167 }
168
169 @Override public Function<S, Iterable<T>> modifyIterableF(final Function<C, Iterable<D>> f) {
170 return self.modifyIterableF(other.modifyIterableF(f));
171 }
172
173 @Override public Function<S, Supplier<T>> modifySupplierF(final Function<C, Supplier<D>> f) {
174 return self.modifySupplierF(other.modifySupplierF(f));
175 }
176
177 @Override public Function<S, Pair<T, T>> modifyPairF(final Function<C, Pair<D, D>> f) {
178 return self.modifyPairF(other.modifyPairF(f));
179 }
180
181 @Override public Function<S, T> modify(final Function<C, D> f) {
182 return self.modify(other.modify(f));
183 }
184 };
185 }
186
187
188
189
190 public final <C, D> PLens<S, T, C, D> composeIso(final PIso<A, B, C, D> other) {
191 return composeLens(other.asLens());
192 }
193
194
195
196
197
198
199
200
201 public final Fold<S, A> asFold() {
202 return new Fold<S, A>() {
203 @Override public <M> Function<S, M> foldMap(final Monoid<M> monoid, final Function<A, M> f) {
204 return s -> f.apply(get(s));
205 }
206 };
207 }
208
209
210
211
212 public final Getter<S, A> asGetter() {
213 return new Getter<S, A>() {
214 @Override public A get(final S s) {
215 return PLens.this.get(s);
216 }
217 };
218 }
219
220
221
222
223 public PSetter<S, T, A, B> asSetter() {
224 return new PSetter<S, T, A, B>() {
225 @Override public Function<S, T> modify(final Function<A, B> f) {
226 return PLens.this.modify(f);
227 }
228
229 @Override public Function<S, T> set(final B b) {
230 return PLens.this.set(b);
231 }
232 };
233 }
234
235
236
237
238 public PTraversal<S, T, A, B> asTraversal() {
239 final PLens<S, T, A, B> self = this;
240 return new PTraversal<S, T, A, B>() {
241
242 @Override public <C> Function<S, Function<C, T>> modifyFunctionF(final Function<A, Function<C, B>> f) {
243 return self.modifyFunctionF(f);
244 }
245
246 @Override public <L> Function<S, Either<L, T>> modifyEitherF(final Function<A, Either<L, B>> f) {
247 return self.modifyEitherF(f);
248 }
249
250 @Override public Function<S, Option<T>> modifyOptionF(final Function<A, Option<B>> f) {
251 return self.modifyOptionF(f);
252 }
253
254 @Override public Function<S, Iterable<T>> modifyIterableF(final Function<A, Iterable<B>> f) {
255 return self.modifyIterableF(f);
256 }
257
258 @Override public Function<S, Supplier<T>> modifySupplierF(final Function<A, Supplier<B>> f) {
259 return self.modifySupplierF(f);
260 }
261
262 @Override public Function<S, Pair<T, T>> modifyPairF(final Function<A, Pair<B, B>> f) {
263 return self.modifyPairF(f);
264 }
265
266 @Override public <M> Function<S, M> foldMap(final Monoid<M> monoid, final Function<A, M> f) {
267 return s -> f.apply(get(s));
268 }
269
270 };
271 }
272
273
274
275
276 public POptional<S, T, A, B> asOptional() {
277 final PLens<S, T, A, B> self = this;
278 return new POptional<S, T, A, B>() {
279 @Override public Either<T, A> getOrModify(final S s) {
280 return Either.right(self.get(s));
281 }
282
283 @Override public Function<S, T> set(final B b) {
284 return self.set(b);
285 }
286
287 @Override public Option<A> getOption(final S s) {
288 return Option.some(self.get(s));
289 }
290
291 @Override public <C> Function<S, Function<C, T>> modifyFunctionF(final Function<A, Function<C, B>> f) {
292 return self.modifyFunctionF(f);
293 }
294
295 @Override public <L> Function<S, Either<L, T>> modifyEitherF(final Function<A, Either<L, B>> f) {
296 return self.modifyEitherF(f);
297 }
298
299 @Override public Function<S, Option<T>> modifyOptionF(final Function<A, Option<B>> f) {
300 return self.modifyOptionF(f);
301 }
302
303 @Override public Function<S, Iterable<T>> modifyIterableF(final Function<A, Iterable<B>> f) {
304 return self.modifyIterableF(f);
305 }
306
307 @Override public Function<S, Supplier<T>> modifySupplierF(final Function<A, Supplier<B>> f) {
308 return self.modifySupplierF(f);
309 }
310
311 @Override public Function<S, Pair<T, T>> modifyPairF(final Function<A, Pair<B, B>> f) {
312 return self.modifyPairF(f);
313 }
314
315 @Override public Function<S, T> modify(final Function<A, B> f) {
316 return self.modify(f);
317 }
318 };
319 }
320
321 public static <S, T> PLens<S, T, S, T> pId() {
322 return PIso.<S, T> pId().asLens();
323 }
324
325
326
327
328
329 public static <S, T, A, B> PLens<S, T, A, B> pLens(final Function<S, A> get, final Function<B, Function<S, T>> set) {
330 return new PLens<S, T, A, B>() {
331
332 @Override public A get(final S s) {
333 return get.apply(s);
334 }
335
336 @Override public Function<S, T> set(final B b) {
337 return set.apply(b);
338 }
339
340 @Override public <C> Function<S, Function<C, T>> modifyFunctionF(final Function<A, Function<C, B>> f) {
341 return s -> f.apply(get.apply(s)).andThen(b -> set.apply(b).apply(s));
342 }
343
344 @Override public <L> Function<S, Either<L, T>> modifyEitherF(final Function<A, Either<L, B>> f) {
345 return s -> f.apply(get.apply(s)).right().map(a -> set.apply(a).apply(s));
346 }
347
348 @Override public Function<S, Option<T>> modifyOptionF(final Function<A, Option<B>> f) {
349 return s -> f.apply(get.apply(s)).map(a -> set.apply(a).apply(s));
350 }
351
352 @Override public Function<S, Iterable<T>> modifyIterableF(final Function<A, Iterable<B>> f) {
353 return s -> Iterables.map(f.apply(get.apply(s)), a -> set.apply(a).apply(s));
354 }
355
356 @Override public Function<S, Supplier<T>> modifySupplierF(final Function<A, Supplier<B>> f) {
357 return s -> Suppliers.compose(a -> set.apply(a).apply(s), f.apply(get.apply(s)));
358 }
359
360 @Override public Function<S, Pair<T, T>> modifyPairF(final Function<A, Pair<B, B>> f) {
361 return s -> Pair.map(f.apply(get.apply(s)), a -> set.apply(a).apply(s));
362 }
363
364 @Override public Function<S, T> modify(final Function<A, B> f) {
365 return s -> set.apply(f.apply(get.apply(s))).apply(s);
366 }
367
368 };
369 }
370 }