summaryrefslogtreecommitdiff
path: root/BJC-Utils2/src/main/java/bjc/utils/data/internals
diff options
context:
space:
mode:
authorbjculkin <bjculkin@WIT-136XG42.wvu-ad.wvu.edu>2017-02-27 10:11:43 -0500
committerbjculkin <bjculkin@WIT-136XG42.wvu-ad.wvu.edu>2017-02-27 10:11:43 -0500
commite6459a351f14d76dbac83e95a55664820387ad7b (patch)
tree3fba82ce642fb6da2359bf55510b87fcd8064a88 /BJC-Utils2/src/main/java/bjc/utils/data/internals
parent0b4fd83d36eb82c92a39af8b8e1c521d822bd4c3 (diff)
Package reorganization
Diffstat (limited to 'BJC-Utils2/src/main/java/bjc/utils/data/internals')
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/internals/BoundLazy.java164
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/internals/BoundLazyPair.java241
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/internals/BoundListHolder.java86
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/internals/HalfBoundLazyPair.java163
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/internals/WrappedLazy.java62
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/internals/WrappedOption.java83
6 files changed, 799 insertions, 0 deletions
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/internals/BoundLazy.java b/BJC-Utils2/src/main/java/bjc/utils/data/internals/BoundLazy.java
new file mode 100644
index 0000000..beb2465
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/internals/BoundLazy.java
@@ -0,0 +1,164 @@
+package bjc.utils.data.internals;
+
+import java.util.function.Function;
+import java.util.function.Supplier;
+import java.util.function.UnaryOperator;
+
+import bjc.utils.data.IHolder;
+import bjc.utils.data.Lazy;
+import bjc.utils.funcdata.FunctionalList;
+import bjc.utils.funcdata.IList;
+
+/**
+ * Implements a lazy holder that has been bound
+ */
+public class BoundLazy<OldType, BoundContainedType>
+ implements IHolder<BoundContainedType> {
+ /*
+ * The old value
+ */
+ private Supplier<IHolder<OldType>> oldSupplier;
+
+ /*
+ * The function to use to transform the old value into a new value
+ */
+ private Function<OldType, IHolder<BoundContainedType>> binder;
+
+ /*
+ * The bound value being held
+ */
+ private IHolder<BoundContainedType> boundHolder;
+
+ /*
+ * Whether the bound value has been actualized or not
+ */
+ private boolean holderBound;
+
+ /*
+ * Transformations currently pending on the bound value
+ */
+ private IList<UnaryOperator<BoundContainedType>> actions = new FunctionalList<>();
+
+ /*
+ * Create a new bound lazy value
+ */
+ 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) {
+ if (bindr == null) {
+ throw new NullPointerException("Binder must not be null");
+ }
+
+ /*
+ * Prepare a list of pending actions
+ */
+ IList<UnaryOperator<BoundContainedType>> pendingActions = new FunctionalList<>();
+ actions.forEach(pendingActions::add);
+
+ /*
+ * Create the new supplier of a value
+ */
+ Supplier<IHolder<BoundContainedType>> typeSupplier = () -> {
+ IHolder<BoundContainedType> oldHolder = boundHolder;
+
+ /*
+ * Bind the value if it hasn't been bound before
+ */
+ if (!holderBound) {
+ oldHolder = oldSupplier.get().unwrap(binder);
+ }
+
+ /*
+ * Apply all the pending actions
+ */
+ return pendingActions.reduceAux(oldHolder, (action, state) -> {
+ return state.transform(action);
+ }, (value) -> value);
+ };
+
+ return new BoundLazy<>(typeSupplier, bindr);
+ }
+
+ @Override
+ public <NewType> Function<BoundContainedType, IHolder<NewType>> lift(
+ Function<BoundContainedType, NewType> func) {
+ if (func == null) {
+ throw new NullPointerException(
+ "Function to lift must not be null");
+ }
+
+ return (val) -> {
+ return new Lazy<>(func.apply(val));
+ };
+ }
+
+ @Override
+ public <MappedType> IHolder<MappedType> map(
+ Function<BoundContainedType, MappedType> mapper) {
+ if (mapper == null) {
+ throw new NullPointerException("Mapper must not be null");
+ }
+
+ // Prepare a list of pending actions
+ IList<UnaryOperator<BoundContainedType>> pendingActions = new FunctionalList<>();
+ actions.forEach(pendingActions::add);
+
+ // Prepare the new supplier
+ Supplier<MappedType> typeSupplier = () -> {
+ IHolder<BoundContainedType> oldHolder = boundHolder;
+
+ // Bound the value if it hasn't been bound
+ 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) {
+ if (transformer == null) {
+ throw new NullPointerException("Transformer must not be null");
+ }
+
+ actions.add(transformer);
+
+ return this;
+ }
+
+ @Override
+ public <UnwrappedType> UnwrappedType unwrap(
+ Function<BoundContainedType, UnwrappedType> unwrapper) {
+ if (unwrapper == null) {
+ throw new NullPointerException("Unwrapper must not be null");
+ }
+
+ if (!holderBound) {
+ boundHolder = oldSupplier.get().unwrap(binder::apply);
+ }
+
+ return boundHolder.unwrap(unwrapper);
+ }
+} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/internals/BoundLazyPair.java b/BJC-Utils2/src/main/java/bjc/utils/data/internals/BoundLazyPair.java
new file mode 100644
index 0000000..977fb37
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/internals/BoundLazyPair.java
@@ -0,0 +1,241 @@
+package bjc.utils.data.internals;
+
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+import bjc.utils.data.IHolder;
+import bjc.utils.data.IPair;
+import bjc.utils.data.Identity;
+import bjc.utils.data.LazyPair;
+
+/**
+ * Implements a lazy pair that has been bound
+ */
+public class BoundLazyPair<OldLeft, OldRight, NewLeft, NewRight>
+ implements IPair<NewLeft, NewRight> {
+ /*
+ * The supplier of the left value
+ */
+ private Supplier<OldLeft> leftSupplier;
+ /*
+ * The supplier of the right value
+ */
+ private Supplier<OldRight> rightSupplier;
+
+ /*
+ * The binder to transform values
+ */
+ private BiFunction<OldLeft, OldRight, IPair<NewLeft, NewRight>> binder;
+
+ /*
+ * The bound pair
+ */
+ private IPair<NewLeft, NewRight> boundPair;
+
+ /*
+ * Whether the pair has been bound yet
+ */
+ private boolean pairBound;
+
+ public BoundLazyPair(Supplier<OldLeft> leftSupp,
+ Supplier<OldRight> rightSupp,
+ BiFunction<OldLeft, OldRight, IPair<NewLeft, NewRight>> bindr) {
+ leftSupplier = leftSupp;
+ rightSupplier = rightSupp;
+ binder = bindr;
+ }
+
+ @Override
+ public <BoundLeft, BoundRight> IPair<BoundLeft, BoundRight> bind(
+ BiFunction<NewLeft, NewRight, IPair<BoundLeft, BoundRight>> bindr) {
+ if (bindr == null) {
+ throw new NullPointerException("Binder must not be null");
+ }
+
+ IHolder<IPair<NewLeft, NewRight>> newPair = new Identity<>(
+ boundPair);
+ IHolder<Boolean> newPairMade = new Identity<>(pairBound);
+
+ Supplier<NewLeft> leftSupp = () -> {
+ if (!newPairMade.getValue()) {
+ newPair.replace(binder.apply(leftSupplier.get(),
+ rightSupplier.get()));
+
+ newPairMade.replace(true);
+ }
+
+ return newPair.unwrap((pair) -> pair.getLeft());
+ };
+
+ Supplier<NewRight> rightSupp = () -> {
+ if (!newPairMade.getValue()) {
+ newPair.replace(binder.apply(leftSupplier.get(),
+ rightSupplier.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) {
+ if (leftBinder == null) {
+ throw new NullPointerException("Left binder must not be null");
+ }
+
+ Supplier<NewLeft> leftSupp = () -> {
+ IPair<NewLeft, NewRight> newPair = boundPair;
+
+ if (!pairBound) {
+ newPair = binder.apply(leftSupplier.get(),
+ rightSupplier.get());
+ }
+
+ return newPair.getLeft();
+ };
+
+ return new HalfBoundLazyPair<>(leftSupp, leftBinder);
+ }
+
+ @Override
+ public <BoundRight> IPair<NewLeft, BoundRight> bindRight(
+ Function<NewRight, IPair<NewLeft, BoundRight>> rightBinder) {
+ if (rightBinder == null) {
+ throw new NullPointerException(
+ "Right binder must not be null");
+ }
+
+ Supplier<NewRight> rightSupp = () -> {
+ IPair<NewLeft, NewRight> newPair = boundPair;
+
+ if (!pairBound) {
+ newPair = binder.apply(leftSupplier.get(),
+ rightSupplier.get());
+ }
+
+ return newPair.getRight();
+ };
+
+ return new HalfBoundLazyPair<>(rightSupp, rightBinder);
+ }
+
+ @Override
+ public <OtherLeft, OtherRight, CombinedLeft, CombinedRight> IPair<CombinedLeft, CombinedRight> combine(
+ IPair<OtherLeft, OtherRight> otherPair,
+ BiFunction<NewLeft, OtherLeft, CombinedLeft> leftCombiner,
+ BiFunction<NewRight, OtherRight, CombinedRight> rightCombiner) {
+ if (otherPair == null) {
+ throw new NullPointerException("Other pair must not be null");
+ } else if (leftCombiner == null) {
+ throw new NullPointerException(
+ "Left combiner must not be null");
+ } else if (rightCombiner == null) {
+ throw new NullPointerException(
+ "Right combiner must not be null");
+ }
+
+ return otherPair.bind((otherLeft, otherRight) -> {
+ return bind((leftVal, rightVal) -> {
+ return new LazyPair<>(
+ leftCombiner.apply(leftVal, otherLeft),
+ rightCombiner.apply(rightVal, otherRight));
+ });
+ });
+ }
+
+ @Override
+ public <NewLeftType> IPair<NewLeftType, NewRight> mapLeft(
+ Function<NewLeft, NewLeftType> mapper) {
+ if (mapper == null) {
+ throw new NullPointerException("Mapper must not be null");
+ }
+
+ Supplier<NewLeftType> leftSupp = () -> {
+ if (!pairBound) {
+ NewLeft leftVal = binder
+ .apply(leftSupplier.get(), rightSupplier.get())
+ .getLeft();
+
+ return mapper.apply(leftVal);
+ }
+
+ return mapper.apply(boundPair.getLeft());
+ };
+
+ Supplier<NewRight> rightSupp = () -> {
+ if (!pairBound) {
+ return binder
+ .apply(leftSupplier.get(), rightSupplier.get())
+ .getRight();
+ }
+
+ return boundPair.getRight();
+ };
+
+ return new LazyPair<>(leftSupp, rightSupp);
+ }
+
+ @Override
+ public <NewRightType> IPair<NewLeft, NewRightType> mapRight(
+ Function<NewRight, NewRightType> mapper) {
+ if (mapper == null) {
+ throw new NullPointerException("Mapper must not be null");
+ }
+
+ Supplier<NewLeft> leftSupp = () -> {
+ if (!pairBound) {
+ return binder
+ .apply(leftSupplier.get(), rightSupplier.get())
+ .getLeft();
+ }
+
+ return boundPair.getLeft();
+ };
+
+ Supplier<NewRightType> rightSupp = () -> {
+ if (!pairBound) {
+ NewRight rightVal = binder
+ .apply(leftSupplier.get(), rightSupplier.get())
+ .getRight();
+
+ return mapper.apply(rightVal);
+ }
+
+ return mapper.apply(boundPair.getRight());
+ };
+
+ return new LazyPair<>(leftSupp, rightSupp);
+ }
+
+ @Override
+ public <MergedType> MergedType merge(
+ BiFunction<NewLeft, NewRight, MergedType> merger) {
+ if (merger == null) {
+ throw new NullPointerException("Merger must not be null");
+ }
+
+ if (!pairBound) {
+ boundPair = binder.apply(leftSupplier.get(),
+ rightSupplier.get());
+
+ pairBound = true;
+ }
+
+ return boundPair.merge(merger);
+ }
+
+ @Override
+ public String toString() {
+ if (pairBound) {
+ return boundPair.toString();
+ }
+
+ return "(un-materialized)";
+ }
+} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/internals/BoundListHolder.java b/BJC-Utils2/src/main/java/bjc/utils/data/internals/BoundListHolder.java
new file mode 100644
index 0000000..7a3eaa8
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/internals/BoundListHolder.java
@@ -0,0 +1,86 @@
+package bjc.utils.data.internals;
+
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+
+import bjc.utils.data.IHolder;
+import bjc.utils.data.ListHolder;
+import bjc.utils.funcdata.IList;
+
+/*
+ * Holds a list, converted into a holder
+ */
+public class BoundListHolder<ContainedType> implements IHolder<ContainedType> {
+ private IList<IHolder<ContainedType>> heldHolders;
+
+ public BoundListHolder(IList<IHolder<ContainedType>> toHold) {
+ heldHolders = toHold;
+ }
+
+ @Override
+ public <BoundType> IHolder<BoundType> bind(
+ Function<ContainedType, IHolder<BoundType>> binder) {
+ if (binder == null) {
+ throw new NullPointerException("Binder must not be null");
+ }
+
+ IList<IHolder<BoundType>> boundHolders = heldHolders
+ .map((containedHolder) -> {
+ return containedHolder.bind(binder);
+ });
+
+ return new BoundListHolder<>(boundHolders);
+ }
+
+ @Override
+ public <NewType> Function<ContainedType, IHolder<NewType>> lift(
+ Function<ContainedType, NewType> func) {
+ if (func == null) {
+ throw new NullPointerException(
+ "Function to lift must not be null");
+ }
+
+ return (val) -> {
+ return new ListHolder<>(func.apply(val));
+ };
+ }
+
+ @Override
+ public <MappedType> IHolder<MappedType> map(
+ Function<ContainedType, MappedType> mapper) {
+ if (mapper == null) {
+ throw new NullPointerException("Mapper must not be null");
+ }
+
+ IList<IHolder<MappedType>> mappedHolders = heldHolders
+ .map((containedHolder) -> {
+ return containedHolder.map(mapper);
+ });
+
+ return new BoundListHolder<>(mappedHolders);
+ }
+
+ @Override
+ public IHolder<ContainedType> transform(
+ UnaryOperator<ContainedType> transformer) {
+ if (transformer == null) {
+ throw new NullPointerException("Transformer must not be null");
+ }
+
+ heldHolders.forEach((containedHolder) -> {
+ containedHolder.transform(transformer);
+ });
+
+ return this;
+ }
+
+ @Override
+ public <UnwrappedType> UnwrappedType unwrap(
+ Function<ContainedType, UnwrappedType> unwrapper) {
+ if (unwrapper == null) {
+ throw new NullPointerException("Unwrapper must not be null");
+ }
+
+ return heldHolders.randItem().unwrap(unwrapper);
+ }
+} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/internals/HalfBoundLazyPair.java b/BJC-Utils2/src/main/java/bjc/utils/data/internals/HalfBoundLazyPair.java
new file mode 100644
index 0000000..1e8d109
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/internals/HalfBoundLazyPair.java
@@ -0,0 +1,163 @@
+package bjc.utils.data.internals;
+
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+import bjc.utils.data.IHolder;
+import bjc.utils.data.IPair;
+import bjc.utils.data.Identity;
+import bjc.utils.data.LazyPair;
+
+/*
+ * A lazy pair, with only one side bound
+ */
+public 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 <OtherLeft, OtherRight, CombinedLeft, CombinedRight> IPair<CombinedLeft, CombinedRight> combine(
+ IPair<OtherLeft, OtherRight> otherPair,
+ BiFunction<NewLeft, OtherLeft, CombinedLeft> leftCombiner,
+ BiFunction<NewRight, OtherRight, CombinedRight> rightCombiner) {
+ return otherPair.bind((otherLeft, otherRight) -> {
+ return bind((leftVal, rightVal) -> {
+ return new LazyPair<>(
+ leftCombiner.apply(leftVal, otherLeft),
+ rightCombiner.apply(rightVal, otherRight));
+ });
+ });
+ }
+
+ @Override
+ public <NewLeftType> IPair<NewLeftType, NewRight> mapLeft(
+ Function<NewLeft, NewLeftType> mapper) {
+ Supplier<NewLeftType> leftSupp = () -> {
+ if (pairBound) {
+ return mapper.apply(boundPair.getLeft());
+ }
+
+ NewLeft leftVal = binder.apply(oldSupplier.get()).getLeft();
+
+ return mapper.apply(leftVal);
+ };
+
+ Supplier<NewRight> rightSupp = () -> {
+ if (pairBound) {
+ return boundPair.getRight();
+ }
+
+ return binder.apply(oldSupplier.get()).getRight();
+ };
+
+ return new LazyPair<>(leftSupp, rightSupp);
+ }
+
+ @Override
+ public <NewRightType> IPair<NewLeft, NewRightType> mapRight(
+ Function<NewRight, NewRightType> mapper) {
+ Supplier<NewLeft> leftSupp = () -> {
+ if (pairBound) {
+ return boundPair.getLeft();
+ }
+
+ return binder.apply(oldSupplier.get()).getLeft();
+ };
+
+ Supplier<NewRightType> rightSupp = () -> {
+ if (pairBound) {
+ return mapper.apply(boundPair.getRight());
+ }
+
+ NewRight rightVal = binder.apply(oldSupplier.get()).getRight();
+
+ return mapper.apply(rightVal);
+ };
+
+ return new LazyPair<>(leftSupp, rightSupp);
+ }
+
+ @Override
+ public <MergedType> MergedType merge(
+ BiFunction<NewLeft, NewRight, MergedType> merger) {
+ if (!pairBound) {
+ boundPair = binder.apply(oldSupplier.get());
+
+ pairBound = true;
+ }
+
+ return boundPair.merge(merger);
+ }
+} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/internals/WrappedLazy.java b/BJC-Utils2/src/main/java/bjc/utils/data/internals/WrappedLazy.java
new file mode 100644
index 0000000..7f0b8db
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/internals/WrappedLazy.java
@@ -0,0 +1,62 @@
+package bjc.utils.data.internals;
+
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+
+import bjc.utils.data.IHolder;
+import bjc.utils.data.Lazy;
+
+public class WrappedLazy<ContainedType> implements IHolder<ContainedType> {
+ private IHolder<IHolder<ContainedType>> held;
+
+ public WrappedLazy(IHolder<ContainedType> wrappedHolder) {
+ held = new Lazy<>(wrappedHolder);
+ }
+
+ // This has an extra parameter, because otherwise it erases to the same
+ // as the public one
+ private WrappedLazy(IHolder<IHolder<ContainedType>> wrappedHolder, boolean dummy) {
+ held = wrappedHolder;
+ }
+
+ @Override
+ public <BoundType> IHolder<BoundType> bind(Function<ContainedType, IHolder<BoundType>> binder) {
+ IHolder<IHolder<BoundType>> newHolder = held.map((containedHolder) -> {
+ return containedHolder.bind(binder);
+ });
+
+ return new WrappedLazy<>(newHolder, false);
+ }
+
+ @Override
+ public <NewType> Function<ContainedType, IHolder<NewType>> lift(Function<ContainedType, NewType> func) {
+ return (val) -> {
+ return new Lazy<>(func.apply(val));
+ };
+ }
+
+ @Override
+ public <MappedType> IHolder<MappedType> map(Function<ContainedType, MappedType> mapper) {
+ IHolder<IHolder<MappedType>> newHolder = held.map((containedHolder) -> {
+ return containedHolder.map(mapper);
+ });
+
+ return new WrappedLazy<>(newHolder, false);
+ }
+
+ @Override
+ public IHolder<ContainedType> transform(UnaryOperator<ContainedType> transformer) {
+ held.transform((containedHolder) -> {
+ return containedHolder.transform(transformer);
+ });
+
+ return this;
+ }
+
+ @Override
+ public <UnwrappedType> UnwrappedType unwrap(Function<ContainedType, UnwrappedType> unwrapper) {
+ return held.unwrap((containedHolder) -> {
+ return containedHolder.unwrap(unwrapper);
+ });
+ }
+}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/internals/WrappedOption.java b/BJC-Utils2/src/main/java/bjc/utils/data/internals/WrappedOption.java
new file mode 100644
index 0000000..65c2463
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/internals/WrappedOption.java
@@ -0,0 +1,83 @@
+package bjc.utils.data.internals;
+
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+
+import bjc.utils.data.IHolder;
+import bjc.utils.data.Option;
+
+public class WrappedOption<ContainedType> implements IHolder<ContainedType> {
+ private IHolder<IHolder<ContainedType>> held;
+
+ public WrappedOption(IHolder<ContainedType> seedValue) {
+ held = new Option<>(seedValue);
+ }
+
+ private WrappedOption(IHolder<IHolder<ContainedType>> toHold, boolean dummy) {
+ held = toHold;
+ }
+
+ @Override public <BoundType> IHolder<BoundType> bind(Function<ContainedType, IHolder<BoundType>> binder) {
+ IHolder<IHolder<BoundType>> newHolder = held.map((containedHolder) -> {
+ return containedHolder.bind((containedValue) -> {
+ if (containedValue == null) {
+ return new Option<>(null);
+ }
+
+ return binder.apply(containedValue);
+ });
+ });
+
+ return new WrappedOption<>(newHolder, false);
+ }
+
+ @Override
+ public <NewType> Function<ContainedType, IHolder<NewType>> lift(Function<ContainedType, NewType> func) {
+ return (val) -> {
+ return new Option<>(func.apply(val));
+ };
+ }
+
+ @Override
+ public <MappedType> IHolder<MappedType> map(Function<ContainedType, MappedType> mapper) {
+ IHolder<IHolder<MappedType>> newHolder = held.map((containedHolder) -> {
+ return containedHolder.map((containedValue) -> {
+ if (containedValue == null) {
+ return null;
+ }
+
+ return mapper.apply(containedValue);
+ });
+ });
+
+ return new WrappedOption<>(newHolder, false);
+ }
+
+ @Override
+ public IHolder<ContainedType> transform(UnaryOperator<ContainedType> transformer) {
+ held.transform((containedHolder) -> {
+ return containedHolder.transform((containedValue) -> {
+ if (containedValue == null) {
+ return null;
+ }
+
+ return transformer.apply(containedValue);
+ });
+ });
+
+ return this;
+ }
+
+ @Override
+ public <UnwrappedType> UnwrappedType unwrap(Function<ContainedType, UnwrappedType> unwrapper) {
+ return held.unwrap((containedHolder) -> {
+ return containedHolder.unwrap((containedValue) -> {
+ if (containedValue == null) {
+ return null;
+ }
+
+ return unwrapper.apply(containedValue);
+ });
+ });
+ }
+}