1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.atlassian.fugue;
17
18 import java.io.Serializable;
19 import java.lang.ref.ReferenceQueue;
20 import java.lang.ref.WeakReference;
21 import java.util.Arrays;
22 import java.util.HashMap;
23 import java.util.Map;
24 import java.util.concurrent.ConcurrentHashMap;
25 import java.util.concurrent.ConcurrentMap;
26 import java.util.function.BiFunction;
27 import java.util.function.Consumer;
28 import java.util.function.Function;
29 import java.util.function.Predicate;
30 import java.util.function.Supplier;
31
32 import static io.atlassian.fugue.Option.option;
33 import static io.atlassian.fugue.Unit.Unit;
34 import static java.util.Objects.requireNonNull;
35
36
37
38
39
40
41
42
43
44
45 public class Functions {
46
47
48
49 private Functions() {}
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 public static <A, B, C> Function<A, C> compose(final Function<? super B, ? extends C> g, final Function<? super A, ? extends B> f) {
67 return new FunctionComposition<>(g, f);
68 }
69
70 private static class FunctionComposition<A, B, C> implements Function<A, C>, Serializable {
71 private final Function<? super B, ? extends C> g;
72 private final Function<? super A, ? extends B> f;
73
74 FunctionComposition(final Function<? super B, ? extends C> g, final Function<? super A, ? extends B> f) {
75 this.g = requireNonNull(g);
76 this.f = requireNonNull(f);
77 }
78
79 @Override public C apply(final A a) {
80 return g.apply(f.apply(a));
81 }
82
83 @Override public boolean equals(final Object obj) {
84 if (obj instanceof FunctionComposition) {
85 final FunctionComposition<?, ?, ?> that = (FunctionComposition<?, ?, ?>) obj;
86 return f.equals(that.f) && g.equals(that.g);
87 }
88 return false;
89 }
90
91 @Override public int hashCode() {
92 return f.hashCode() ^ g.hashCode();
93 }
94
95 @Override public String toString() {
96 return g.toString() + "(" + f.toString() + ")";
97 }
98
99 private static final long serialVersionUID = 0;
100 }
101
102
103
104
105
106
107
108
109
110
111
112 public static <A, B, C> Function<C, B> ap(final Function<C, A> ca, final Function<C, Function<A, B>> cab) {
113 return m -> ca.andThen(cab.apply(m)).apply(m);
114 }
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130 public static <F, T> T fold(final BiFunction<? super T, F, T> f, final T zero, final Iterable<? extends F> elements) {
131 T currentValue = zero;
132 for (final F element : elements) {
133 currentValue = f.apply(currentValue, element);
134 }
135 return currentValue;
136 }
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153 public static <F, S, T extends S> T fold(final Function<Pair<S, F>, T> f, final T zero, final Iterable<? extends F> elements) {
154 return fold(toBiFunction(f), zero, elements);
155 }
156
157
158
159
160
161
162
163
164
165
166
167 public static <A, B> Function<Function<A, B>, B> apply(final A arg) {
168 return new Function<Function<A, B>, B>() {
169 @Override public B apply(final Function<A, B> f) {
170 return f.apply(arg);
171 }
172
173 @Override public String toString() {
174 return "Apply";
175 }
176 };
177 }
178
179
180
181
182
183
184
185
186
187
188
189
190
191 public static <A, B> Function<Function<A, B>, B> apply(final Supplier<A> lazyA) {
192 return new Function<Function<A, B>, B>() {
193 @Override public B apply(final Function<A, B> f) {
194 return f.apply(lazyA.get());
195 }
196
197 @Override public String toString() {
198 return "ApplySupplier";
199 }
200 };
201 }
202
203
204
205
206
207
208
209
210
211
212
213
214 public static <A, B> Function<A, Option<B>> isInstanceOf(final Class<B> cls) {
215 return new InstanceOf<>(cls);
216 }
217
218 static class InstanceOf<A, B> implements Function<A, Option<B>> {
219 private final Class<B> cls;
220
221 InstanceOf(final Class<B> cls) {
222 this.cls = requireNonNull(cls);
223 }
224
225 @Override public Option<B> apply(final A a) {
226 return (cls.isAssignableFrom(a.getClass())) ? Option.some(cls.cast(a)) : Option.<B> none();
227 }
228
229 @Override public String toString() {
230 return "InstanceOf";
231 }
232
233 @Override public int hashCode() {
234 return cls.hashCode();
235 }
236
237 static final long serialVersionUID = 0;
238 }
239
240
241
242
243
244
245
246
247
248
249
250
251
252 public static <A, B> Function<A, Option<B>> partial(final Predicate<? super A> p, final Function<? super A, ? extends B> f) {
253 return new Partial<>(p, f);
254 }
255
256 static class Partial<A, B> implements Function<A, Option<B>> {
257 private final Predicate<? super A> p;
258 private final Function<? super A, ? extends B> f;
259
260 Partial(final Predicate<? super A> p, final Function<? super A, ? extends B> f) {
261 this.p = requireNonNull(p);
262 this.f = requireNonNull(f);
263 }
264
265 @Override public Option<B> apply(final A a) {
266 return (p.test(a)) ? option(f.apply(a)) : Option.<B> none();
267 }
268
269 @Override public String toString() {
270 return "Partial";
271 }
272
273 @Override public int hashCode() {
274 return f.hashCode() ^ p.hashCode();
275 }
276 }
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293 public static <A, B, C> Function<A, Option<C>> composeOption(final Function<? super B, ? extends Option<? extends C>> bc,
294 final Function<? super A, ? extends Option<? extends B>> ab) {
295 return new PartialComposer<>(ab, bc);
296 }
297
298 static class PartialComposer<A, B, C> implements Function<A, Option<C>> {
299 private final Function<? super A, ? extends Option<? extends B>> ab;
300 private final Function<? super B, ? extends Option<? extends C>> bc;
301
302 PartialComposer(final Function<? super A, ? extends Option<? extends B>> ab, final Function<? super B, ? extends Option<? extends C>> bc) {
303 this.ab = requireNonNull(ab);
304 this.bc = requireNonNull(bc);
305 }
306
307 @Override public Option<C> apply(final A a) {
308 return ab.apply(a).flatMap(bc);
309 }
310
311 @Override public String toString() {
312 return "PartialComposer";
313 }
314
315 @Override public int hashCode() {
316 return bc.hashCode() ^ ab.hashCode();
317 }
318 }
319
320
321
322
323
324
325
326
327
328
329
330
331
332 public static <A, B, C> BiFunction<A, B, C> toBiFunction(final Function<Pair<A, B>, C> fpair) {
333 requireNonNull(fpair);
334 return new BiFunction<A, B, C>() {
335 @Override public C apply(final A a, final B b) {
336 return fpair.apply(Pair.pair(a, b));
337 }
338
339 @Override public String toString() {
340 return "ToBiFunction";
341 }
342 };
343 }
344
345
346
347
348
349
350
351
352
353
354
355
356
357 public static <A, B, C> Function<A, Function<B, C>> curried(final BiFunction<A, B, C> f2) {
358 requireNonNull(f2);
359 return new CurriedFunction<>(f2);
360 }
361
362 private static class CurriedFunction<A, B, C> implements Function<A, Function<B, C>> {
363 private final BiFunction<A, B, C> f2;
364
365 CurriedFunction(final BiFunction<A, B, C> f2) {
366 this.f2 = f2;
367 }
368
369 @Override public Function<B, C> apply(final A a) {
370 return b -> f2.apply(a, b);
371 }
372
373 @Override public String toString() {
374 return "CurriedFunction";
375 }
376
377 @Override public int hashCode() {
378 return f2.hashCode();
379 }
380 }
381
382
383
384
385
386
387
388
389
390
391
392
393
394 public static <A, B, C> Function<B, Function<A, C>> flip(final Function<A, Function<B, C>> f2) {
395 requireNonNull(f2);
396 return new FlippedFunction<>(f2);
397 }
398
399 private static class FlippedFunction<A, B, C> implements Function<B, Function<A, C>> {
400 private final Function<A, Function<B, C>> f2;
401
402 FlippedFunction(final Function<A, Function<B, C>> f2) {
403 this.f2 = f2;
404 }
405
406 @Override public Function<A, C> apply(final B b) {
407 return a -> f2.apply(a).apply(b);
408 }
409
410 @Override public String toString() {
411 return "FlippedFunction";
412 }
413
414 @Override public int hashCode() {
415 return f2.hashCode();
416 }
417 }
418
419
420
421
422
423
424
425
426
427
428
429 public static <A, B> Function<A, Option<B>> mapNullToOption(final Function<? super A, ? extends B> f) {
430 return Functions.compose(Functions.<B> nullToOption(), f);
431 }
432
433
434
435
436
437
438
439
440 public static <A> Function<A, Option<A>> nullToOption() {
441 return Options.toOption();
442 }
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463 public static <A, B> Function<A, B> weakMemoize(final Function<A, B> f) {
464 return WeakMemoizer.weakMemoizer(f);
465 }
466
467
468
469
470
471
472
473
474
475
476
477 static <D, R> Function<D, R> fromSupplier(final Supplier<R> supplier) {
478 return new FromSupplier<>(supplier);
479 }
480
481 static class FromSupplier<D, R> implements Function<D, R> {
482 private final Supplier<R> supplier;
483
484 FromSupplier(final Supplier<R> supplier) {
485 this.supplier = requireNonNull(supplier, "supplier");
486 }
487
488 @Override public R apply(final D ignore) {
489 return supplier.get();
490 }
491
492 @Override public String toString() {
493 return "FromSupplier";
494 }
495
496 @Override public int hashCode() {
497 return supplier.hashCode();
498 }
499 }
500
501
502
503
504
505
506
507
508
509
510 public static <D> Function<D, Unit> fromConsumer(Consumer<D> consumer) {
511 return new FromConsumer<>(consumer);
512 }
513
514 private static class FromConsumer<D> implements Function<D, Unit> {
515 private final Consumer<D> consumer;
516
517 FromConsumer(final Consumer<D> consumer) {
518 this.consumer = requireNonNull(consumer);
519 }
520
521 @Override public Unit apply(D d) {
522 consumer.accept(d);
523 return Unit();
524 }
525
526 @Override public String toString() {
527 return "FromConsumer";
528 }
529
530 @Override public int hashCode() {
531 return consumer.hashCode();
532 }
533 }
534
535
536
537
538
539
540
541
542 @SuppressWarnings("unchecked") public static <A> Function<A, A> identity() {
543
544 return (Function<A, A>) IdentityFunction.INSTANCE;
545 }
546
547
548 private enum IdentityFunction implements Function<Object, Object> {
549 INSTANCE;
550
551 @Override public Object apply(final Object o) {
552 return o;
553 }
554
555 @Override public String toString() {
556 return "identity";
557 }
558 }
559
560
561
562
563
564
565
566
567
568 public static <A, B> Function<A, B> constant(final B constant) {
569 return from -> constant;
570 }
571
572
573
574
575
576
577
578
579
580
581
582
583
584 public static <A, B> Function<A, Option<B>> forMap(final Map<A, B> map) {
585 return a -> option(map.get(a));
586 }
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602 public static <A, B> Function<A, B> forMapWithDefault(final Map<A, B> map, final B defaultValue) {
603 return forMap(map).andThen(o -> o.getOrElse(defaultValue));
604 }
605
606
607
608
609
610
611
612
613
614
615
616
617
618 public static <A, B> Function<A, Option<B>> matches(final Function<? super A, ? extends Option<? extends B>> f1,
619 final Function<? super A, ? extends Option<? extends B>> f2) {
620 return matcher(f1, f2);
621 }
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636 public static <A, B> Function<A, Option<B>> matches(final Function<? super A, ? extends Option<? extends B>> f1,
637 final Function<? super A, ? extends Option<? extends B>> f2, final Function<? super A, ? extends Option<? extends B>> f3) {
638 return matcher(f1, f2, f3);
639 }
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655 public static <A, B> Function<A, Option<B>> matches(final Function<? super A, ? extends Option<? extends B>> f1,
656 final Function<? super A, ? extends Option<? extends B>> f2, final Function<? super A, ? extends Option<? extends B>> f3,
657 final Function<? super A, ? extends Option<? extends B>> f4) {
658 return new Matcher<>(Arrays.<Function<? super A, ? extends Option<? extends B>>> asList(f1, f2, f3, f4));
659 }
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677 @SafeVarargs public static <A, B> Function<A, Option<B>> matches(final Function<? super A, ? extends Option<? extends B>> f1,
678 final Function<? super A, ? extends Option<? extends B>> f2, final Function<? super A, ? extends Option<? extends B>> f3,
679 final Function<? super A, ? extends Option<? extends B>> f4, final Function<? super A, ? extends Option<? extends B>> f5,
680 final Function<? super A, ? extends Option<? extends B>>... fs) {
681
682 @SuppressWarnings("unchecked")
683 final Function<? super A, ? extends Option<? extends B>>[] matchingFunctions = new Function[5 + fs.length];
684 matchingFunctions[0] = f1;
685 matchingFunctions[1] = f2;
686 matchingFunctions[2] = f3;
687 matchingFunctions[3] = f4;
688 matchingFunctions[4] = f5;
689 System.arraycopy(fs, 0, matchingFunctions, 5, fs.length);
690
691 return new Matcher<>(Arrays.asList(matchingFunctions));
692 }
693
694
695 @SafeVarargs private static <A, B> Matcher<A, B> matcher(final Function<? super A, ? extends Option<? extends B>>... fs) {
696 @SuppressWarnings("unchecked")
697 final Function<? super A, ? extends Option<? extends B>>[] dest = new Function[fs.length];
698
699 System.arraycopy(fs, 0, dest, 0, fs.length);
700 for (final Function<? super A, ? extends Option<? extends B>> f : fs) {
701 if (f == null) {
702 throw new NullPointerException("function value was null");
703 }
704 }
705
706 return new Matcher<>(Arrays.asList(dest));
707 }
708
709 static class Matcher<A, B> implements Function<A, Option<B>> {
710 private final Iterable<Function<? super A, ? extends Option<? extends B>>> fs;
711
712 Matcher(final Iterable<Function<? super A, ? extends Option<? extends B>>> fs) {
713 this.fs = requireNonNull(fs);
714
715 if (!fs.iterator().hasNext()) {
716 throw new IllegalArgumentException("Condition must be true but returned false instead");
717 }
718 }
719
720 @Override public Option<B> apply(final A a) {
721 for (final Function<? super A, ? extends Option<? extends B>> f : fs) {
722 @SuppressWarnings("unchecked")
723 final Option<B> b = (Option<B>) f.apply(a);
724 if (b.isDefined())
725 return b;
726 }
727 return Option.none();
728 }
729
730 @Override public String toString() {
731 return "Matcher";
732 }
733
734 @Override public int hashCode() {
735 return fs.hashCode();
736 }
737 }
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756 static final class WeakMemoizer<A, B> implements Function<A, B> {
757 static <A, B> WeakMemoizer<A, B> weakMemoizer(final Function<A, B> delegate) {
758 return new WeakMemoizer<>(delegate);
759 }
760
761 private final ConcurrentMap<A, MappedReference<A, B>> map;
762 private final ReferenceQueue<B> queue = new ReferenceQueue<>();
763 private final Function<A, B> delegate;
764
765
766
767
768
769
770 WeakMemoizer(final Function<A, B> delegate) {
771 this.map = new ConcurrentHashMap<>();
772 this.delegate = requireNonNull(delegate, "delegate");
773 }
774
775
776
777
778
779
780
781 @Override public B apply(final A descriptor) {
782 expungeStaleEntries();
783 requireNonNull(descriptor, "descriptor");
784 while (true) {
785 final MappedReference<A, B> reference = map.get(descriptor);
786 if (reference != null) {
787 final B value = reference.get();
788 if (value != null) {
789 return value;
790 }
791 map.remove(descriptor, reference);
792 }
793 map.putIfAbsent(descriptor, new MappedReference<>(descriptor, delegate.apply(descriptor), queue));
794 }
795 }
796
797
798 @SuppressWarnings("unchecked") private void expungeStaleEntries() {
799 MappedReference<A, B> ref;
800
801 while ((ref = (MappedReference<A, B>) queue.poll()) != null) {
802 final A key = ref.getDescriptor();
803 if (key == null) {
804
805
806 continue;
807 }
808 map.remove(key, ref);
809 }
810
811 }
812
813
814
815
816
817 static final class MappedReference<K, V> extends WeakReference<V> {
818 private final K key;
819
820 public MappedReference(final K key, final V value, final ReferenceQueue<? super V> q) {
821 super(requireNonNull(value, "value"), q);
822 this.key = requireNonNull(key, "key");
823 }
824
825 final K getDescriptor() {
826 return key;
827 }
828 }
829 }
830
831 static <A> Predicate<A> countingPredicate(final int n) {
832 if (n < 0) {
833 throw new IllegalArgumentException("n must be positive");
834 }
835 return new Predicate<A>() {
836 int count = n;
837
838 @Override public boolean test(final A a) {
839 return --count >= 0;
840 }
841 };
842 }
843 }