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 implements IHolder { private Supplier> oldSupplier; private Function> binder; private IHolder boundHolder; private boolean holderBound; private IFunctionalList> actions = new FunctionalList<>(); public BoundLazy(Supplier> supp, Function> binder) { oldSupplier = supp; this.binder = binder; } @Override public IHolder bind( Function> bindr) { IFunctionalList> pendingActions = new FunctionalList<>(); actions.forEach(pendingActions::add); Supplier> typeSupplier = () -> { IHolder 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 IHolder map( Function mapper) { IFunctionalList> pendingActions = new FunctionalList<>(); actions.forEach(pendingActions::add); Supplier typeSupplier = () -> { IHolder 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 transform( UnaryOperator transformer) { actions.add(transformer); return this; } @Override public UnwrappedType unwrap( Function unwrapper) { if (!holderBound) { boundHolder = oldSupplier.get().unwrap(binder::apply); } return boundHolder.unwrap(unwrapper); } @Override public Function> lift( Function func) { return (val) -> { return new Lazy<>(func.apply(val)); }; } }