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
|
package bjc.utils.data;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
import bjc.utils.funcdata.FunctionalList;
import bjc.utils.funcdata.IFunctionalList;
class BoundLazy<OldType, BoundContainedType>
implements IHolder<BoundContainedType> {
private Supplier<IHolder<OldType>> oldSupplier;
private Function<OldType, IHolder<BoundContainedType>> binder;
private IHolder<BoundContainedType> boundHolder;
private boolean holderBound;
private IFunctionalList<UnaryOperator<BoundContainedType>> actions = new FunctionalList<>();
public BoundLazy(Supplier<IHolder<OldType>> supp,
Function<OldType, IHolder<BoundContainedType>> binder) {
oldSupplier = supp;
this.binder = binder;
}
@Override
public <BoundType> IHolder<BoundType> bind(
Function<BoundContainedType, IHolder<BoundType>> bindr) {
IFunctionalList<UnaryOperator<BoundContainedType>> pendingActions = new FunctionalList<>();
actions.forEach(pendingActions::add);
Supplier<IHolder<BoundContainedType>> typeSupplier = () -> {
IHolder<BoundContainedType> oldHolder = boundHolder;
if (!holderBound) {
oldHolder = oldSupplier.get().unwrap(binder);
}
return pendingActions.reduceAux(oldHolder, (action, state) -> {
return state.transform(action);
}, (value) -> value);
};
return new BoundLazy<>(typeSupplier, bindr);
}
@Override
public <MappedType> IHolder<MappedType> map(
Function<BoundContainedType, MappedType> mapper) {
IFunctionalList<UnaryOperator<BoundContainedType>> pendingActions = new FunctionalList<>();
actions.forEach(pendingActions::add);
Supplier<MappedType> typeSupplier = () -> {
IHolder<BoundContainedType> oldHolder = boundHolder;
if (!holderBound) {
oldHolder = oldSupplier.get().unwrap(binder);
}
return pendingActions.reduceAux(oldHolder.getValue(),
(action, state) -> {
return action.apply(state);
}, (value) -> mapper.apply(value));
};
return new Lazy<>(typeSupplier);
}
@Override
public String toString() {
if (holderBound) {
return boundHolder.toString();
}
return "(unmaterialized)";
}
@Override
public IHolder<BoundContainedType> transform(
UnaryOperator<BoundContainedType> transformer) {
actions.add(transformer);
return this;
}
@Override
public <UnwrappedType> UnwrappedType unwrap(
Function<BoundContainedType, UnwrappedType> unwrapper) {
if (!holderBound) {
boundHolder = oldSupplier.get().unwrap(binder::apply);
}
return boundHolder.unwrap(unwrapper);
}
@Override
public <NewType> Function<BoundContainedType, IHolder<NewType>> lift(
Function<BoundContainedType, NewType> func) {
return (val) -> {
return new Lazy<>(func.apply(val));
};
}
}
|