forked from functionaljava/functionaljava
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathVisitor.java
More file actions
112 lines (103 loc) · 4.32 KB
/
Visitor.java
File metadata and controls
112 lines (103 loc) · 4.32 KB
1
2
3
4
5
6
7
8
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package fj.function;
import fj.Equal;
import fj.F;
import fj.F2;
import fj.Function;
import fj.Monoid;
import fj.P1;
import fj.P2;
import fj.data.List;
import fj.data.Option;
import static fj.Function.compose;
import static fj.Function.curry;
import static fj.data.List.lookup;
/**
* The essence of the visitor design pattern expressed polymorphically.
*
* @version %build.number%
*/
public final class Visitor {
private Visitor() {
throw new UnsupportedOperationException();
}
/**
* Returns the first value available in the given list of optional values. If none is found return the given default value.
*
* @param values The optional values to search.
* @param def The default value if no value is found in the list.
* @return The first value available in the given list of optional values. If none is found return the given default value.
*/
public static <X> X findFirst(final List<Option<X>> values, final P1<X> def) {
return Monoid.<X>firstOptionMonoid().sumLeft(values).orSome(def);
}
/**
* Returns the first non-<code>null</code> value in the given list of optional values. If none is found return the given default value.
*
* @param values The potentially <code>null</code> values to search.
* @param def The default value if no value is found in the list.
* @return The first non-<code>null</code> value in the given list of optional values. If none is found return the given default value.
*/
public static <X> X nullablefindFirst(final List<X> values, final P1<X> def) {
return findFirst(values.map(Option.<X>fromNull()), def);
}
/**
* Returns the first value found in the list of visitors after application of the given value, otherwise returns the
* given default.
*
* @param visitors The list of visitors to apply.
* @param def The default if none of the visitors yield a value.
* @param value The value to apply to the visitors.
* @return The first value found in the list of visitors after application of the given value, otherwise returns the
* given default.
*/
public static <A, B> B visitor(final List<F<A, Option<B>>> visitors, final P1<B> def, final A value) {
return findFirst(visitors.map(Function.<A, Option<B>>apply(value)), def);
}
/**
* Returns the first non-<code>null</code> value found in the list of visitors after application of the given value,
* otherwise returns the given default.
*
* @param visitors The list of visitors to apply looking for a non-<code>null</code>.
* @param def The default if none of the visitors yield a non-<code>null</code> value.
* @param value The value to apply to the visitors.
* @return The first value found in the list of visitors after application of the given value, otherwise returns the
* given default.
*/
public static <A, B> B nullableVisitor(final List<F<A, B>> visitors, final P1<B> def, final A value) {
return visitor(visitors.map(new F<F<A, B>, F<A, Option<B>>>() {
public F<A, Option<B>> f(final F<A, B> k) {
return compose(Option.<B>fromNull(), k);
}
}), def, value);
}
/**
* Uses an association list to perform a lookup with equality and returns a function that can be applied to a default,
* followed by the associated key to return a value.
*
* @param x The association list.
* @param eq The equality for the association list keys.
* @return A function that can be applied to a default value (there is no association) and an associated key.
*/
public static <A, B> F<B, F<A, B>> association(final List<P2<A, B>> x, final Equal<A> eq) {
return curry(new F2<B, A, B>() {
public B f(final B def, final A a) {
return lookup(eq, x, a).orSome(def);
}
});
}
/**
* Uses an association list to perform a lookup with equality and returns a function that can be applied to a default,
* followed by the associated key to return a value.
*
* @param x The association list.
* @param eq The equality for the association list keys.
* @return A function that can be applied to a default value (there is no association) and an associated key.
*/
public static <A, B> F<P1<B>, F<A, B>> associationLazy(final List<P2<A, B>> x, final Equal<A> eq) {
return curry(new F2<P1<B>, A, B>() {
public B f(final P1<B> def, final A a) {
return lookup(eq, x, a).orSome(def);
}
});
}
}