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
|
package bjc.utils.data;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
class HalfBoundLazyPair<OldType, NewLeft, NewRight>
implements IPair<NewLeft, NewRight> {
private Supplier<OldType> oldSupplier;
private Function<OldType, IPair<NewLeft, NewRight>> binder;
private IPair<NewLeft, NewRight> boundPair;
private boolean pairBound;
public HalfBoundLazyPair(Supplier<OldType> oldSupp,
Function<OldType, IPair<NewLeft, NewRight>> bindr) {
oldSupplier = oldSupp;
binder = bindr;
}
@Override
public <BoundLeft, BoundRight> IPair<BoundLeft, BoundRight> bind(
BiFunction<NewLeft, NewRight, IPair<BoundLeft, BoundRight>> bindr) {
IHolder<IPair<NewLeft, NewRight>> newPair = new Identity<>(
boundPair);
IHolder<Boolean> newPairMade = new Identity<>(pairBound);
Supplier<NewLeft> leftSupp = () -> {
if (!newPairMade.getValue()) {
newPair.replace(binder.apply(oldSupplier.get()));
newPairMade.replace(true);
}
return newPair.unwrap((pair) -> pair.getLeft());
};
Supplier<NewRight> rightSupp = () -> {
if (!newPairMade.getValue()) {
newPair.replace(binder.apply(oldSupplier.get()));
newPairMade.replace(true);
}
return newPair.unwrap((pair) -> pair.getRight());
};
return new BoundLazyPair<>(leftSupp, rightSupp, bindr);
}
@Override
public <BoundLeft> IPair<BoundLeft, NewRight> bindLeft(
Function<NewLeft, IPair<BoundLeft, NewRight>> leftBinder) {
Supplier<NewLeft> leftSupp = () -> {
IPair<NewLeft, NewRight> newPair = boundPair;
if (!pairBound) {
newPair = binder.apply(oldSupplier.get());
}
return newPair.getLeft();
};
return new HalfBoundLazyPair<>(leftSupp, leftBinder);
}
@Override
public <BoundRight> IPair<NewLeft, BoundRight> bindRight(
Function<NewRight, IPair<NewLeft, BoundRight>> rightBinder) {
Supplier<NewRight> rightSupp = () -> {
IPair<NewLeft, NewRight> newPair = boundPair;
if (!pairBound) {
newPair = binder.apply(oldSupplier.get());
}
return newPair.getRight();
};
return new HalfBoundLazyPair<>(rightSupp, rightBinder);
}
@Override
public <MergedType> MergedType merge(
BiFunction<NewLeft, NewRight, MergedType> merger) {
if (!pairBound) {
boundPair = binder.apply(oldSupplier.get());
pairBound = true;
}
return boundPair.merge(merger);
}
}
|