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