From f9283a20abd9eaed0b0436bc54c60576233121f4 Mon Sep 17 00:00:00 2001 From: bculkin2442 Date: Mon, 11 Apr 2016 09:32:59 -0400 Subject: Added new method to pairs and holders --- .../src/main/java/bjc/utils/data/GenHolder.java | 5 ++ .../src/main/java/bjc/utils/data/IHolder.java | 11 +++ BJC-Utils2/src/main/java/bjc/utils/data/IPair.java | 18 ++++- BJC-Utils2/src/main/java/bjc/utils/data/Pair.java | 6 ++ .../main/java/bjc/utils/data/lazy/LazyHolder.java | 93 +++++++++++++++++++--- .../main/java/bjc/utils/data/lazy/LazyPair.java | 19 ++++- 6 files changed, 138 insertions(+), 14 deletions(-) (limited to 'BJC-Utils2/src/main/java/bjc/utils/data') diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/GenHolder.java b/BJC-Utils2/src/main/java/bjc/utils/data/GenHolder.java index e042554..bd87f07 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/GenHolder.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/GenHolder.java @@ -105,4 +105,9 @@ public class GenHolder implements IHolder { return heldValue.toString(); } + + @Override + public IHolder bind(Function> binder) { + return binder.apply(heldValue); + } } diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/IHolder.java b/BJC-Utils2/src/main/java/bjc/utils/data/IHolder.java index 6290d5f..a4f4013 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/IHolder.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/IHolder.java @@ -56,4 +56,15 @@ public interface IHolder { * @return The mapped value outside of a GenHolder */ public E unwrap(Function unwrapper); + + /** + * Bind the value in this holder to a new value + * + * @param + * The new type of the held value + * @param binder + * The function to do the binding with + * @return The bound value + */ + public IHolder bind(Function> binder); } \ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/IPair.java b/BJC-Utils2/src/main/java/bjc/utils/data/IPair.java index e2ee6a4..a20ff36 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/IPair.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/IPair.java @@ -14,7 +14,7 @@ import java.util.function.Function; * @param * The type stored in the right side of the pair */ -public interface IPair { +public interface IPair { /** * Create a new pair by applying the given functions to the left/right. @@ -34,6 +34,22 @@ public interface IPair { public IPair apply(Function leftTransformer, Function rightTransformer); + /** + * Apply a function to the two internal values that returns a new pair. + * + * Is a monadic bind. + * + * @param + * The new left pair type + * @param + * The new right pair type + * @param binder + * The function to use as a bind + * @return The new pair + */ + public IPair + bind(BiFunction> binder); + /** * Execute an action with the values of this pair. Has no effect on the * internal contents diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/Pair.java b/BJC-Utils2/src/main/java/bjc/utils/data/Pair.java index f721a9a..d0397f7 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/Pair.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/Pair.java @@ -97,4 +97,10 @@ public class Pair implements IPair { public String toString() { return "pair[l=" + leftValue.toString() + ", r=" + rightValue.toString() + "]"; } + + @Override + public IPair + bind(BiFunction> binder) { + return binder.apply(leftValue, rightValue); + } } diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/lazy/LazyHolder.java b/BJC-Utils2/src/main/java/bjc/utils/data/lazy/LazyHolder.java index 2ad8dbf..9f9dc4a 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/lazy/LazyHolder.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/lazy/LazyHolder.java @@ -21,34 +21,100 @@ import bjc.utils.funcdata.IFunctionalList; * The type of the data being held */ public class LazyHolder implements IHolder, ILazy { - private final class LazyHolderSupplier + private static final class LazyHolderHolder + implements IHolder { + private Supplier> holderSource; + + private IHolder holder; + + private IFunctionalList> actions = new FunctionalList<>(); + + public LazyHolderHolder(Supplier> source) { + + holderSource = source; + } + + @Override + public void doWith(Consumer action) { + actions.add((val) -> { + action.accept(val); + + return val; + }); + } + + @Override + public IHolder map(Function transformer) { + // TODO implement me + throw new UnsupportedOperationException( + "Mapping is not yet supported on bound holders"); + } + + @Override + public IHolder transform(Function transformer) { + actions.add(transformer); + + return this; + } + + @Override + public E unwrap(Function unwrapper) { + if (holder == null) { + holder = holderSource.get(); + } + + if (!actions.isEmpty()) { + actions.forEach((transform) -> { + holder.transform(transform); + }); + } + + return holder.unwrap(unwrapper); + } + + @Override + public IHolder bind(Function> binder) { + return new LazyHolderHolder<>(() -> { + return binder.apply(unwrap((val) -> val)); + }); + } + + } + + private static final class LazyHolderSupplier implements Supplier { - private IFunctionalList> pendingActions; - private Function pendingTransform; + private IFunctionalList> pendingActions; + private Function pendingTransform; + + private T2 heldValue; + private Supplier heldSource; - public LazyHolderSupplier(IFunctionalList> actons, - Function transform) { + public LazyHolderSupplier(IFunctionalList> actons, + Function transform, T2 heldValue, + Supplier heldSource) { // Resolve latent bug I just realized. After a map, adding new // actions to the original holder could've resulted in changes // to all unactualized mapped values from that holder pendingActions = new FunctionalList<>(); - for (Function action : actons.toIterable()) { + for (Function action : actons.toIterable()) { pendingActions.add(action); } this.pendingTransform = transform; + this.heldValue = heldValue; + this.heldSource = heldSource; } @Override public NewT get() { if (heldValue == null) { return pendingActions.reduceAux(heldSource.get(), - Function::apply, pendingTransform::apply); + Function::apply, pendingTransform::apply); } return pendingActions.reduceAux(heldValue, - Function::apply, pendingTransform::apply); + Function::apply, pendingTransform::apply); } } @@ -114,8 +180,8 @@ public class LazyHolder implements IHolder, ILazy { } // Don't actually map until we need to - return new LazyHolder<>( - new LazyHolderSupplier<>(actions, transform)); + return new LazyHolder<>(new LazyHolderSupplier<>(actions, + transform, heldValue, heldSource)); } @Override @@ -179,4 +245,11 @@ public class LazyHolder implements IHolder, ILazy { heldValue = action.apply(heldValue); }); } + + @Override + public IHolder bind(Function> binder) { + return new LazyHolderHolder<>(() -> { + return binder.apply(unwrap((val) -> val)); + }); + } } \ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/lazy/LazyPair.java b/BJC-Utils2/src/main/java/bjc/utils/data/lazy/LazyPair.java index e08c8fb..7ba7ee7 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/lazy/LazyPair.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/lazy/LazyPair.java @@ -98,9 +98,9 @@ public class LazyPair implements IPair, ILazy { throw new NullPointerException("Transforms must be non-null"); } - IHolder> newPair = - delegatePair.map((currentPair) -> currentPair - .apply(leftTransform, rightTransform)); + IHolder> newPair = delegatePair + .map((currentPair) -> currentPair.apply(leftTransform, + rightTransform)); return new LazyPair<>(newPair, materialized, true); } @@ -169,4 +169,17 @@ public class LazyPair implements IPair, ILazy { materialized = true; pendingActions = false; } + + @Override + public IPair bind( + BiFunction> binder) { + // TODO Auto-generated method stub + IHolder> newDelegate = delegatePair + .map((pairVal) -> { + return pairVal.bind(binder); + }); + + return new LazyPair<>(newDelegate, isMaterialized(), + hasPendingActions()); + } } \ No newline at end of file -- cgit v1.2.3