summaryrefslogtreecommitdiff
path: root/BJC-Utils2/src/main/java/bjc/utils/data/experimental
diff options
context:
space:
mode:
authorbculkin2442 <bjculkin@mix.wvu.edu>2016-04-11 21:54:44 -0400
committerbculkin2442 <bjculkin@mix.wvu.edu>2016-04-11 21:54:44 -0400
commitc8a00b789671d59589bcb5520c1e9d208bcc27f6 (patch)
tree6b64e3c78f56d025c78ab08a9edc038af0b6e821 /BJC-Utils2/src/main/java/bjc/utils/data/experimental
parenta716a7a53f85a6901128896da508d31c172011b4 (diff)
Work on restructing data.
Diffstat (limited to 'BJC-Utils2/src/main/java/bjc/utils/data/experimental')
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/experimental/IHolder.java18
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/experimental/IPair.java84
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/experimental/Identity.java82
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/experimental/Lazy.java39
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/experimental/LazyPair.java317
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/experimental/Pair.java63
6 files changed, 548 insertions, 55 deletions
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/IHolder.java b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/IHolder.java
index 2767897..7d1d7a0 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/IHolder.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/IHolder.java
@@ -15,8 +15,11 @@ import java.util.function.UnaryOperator;
public interface IHolder<ContainedType> {
/**
* Bind a function across the value in this container
- * @param <BoundType> The type of value in this container
- * @param binder The function to bind to the value
+ *
+ * @param <BoundType>
+ * The type of value in this container
+ * @param binder
+ * The function to bind to the value
* @return A holder from binding the value
*/
public <BoundType> IHolder<BoundType> bind(
@@ -82,4 +85,15 @@ public interface IHolder<ContainedType> {
*/
public <UnwrappedType> UnwrappedType unwrap(
Function<ContainedType, UnwrappedType> unwrapper);
+
+ /**
+ * Replace the held value with a new one
+ *
+ * @param newValue
+ * The value to hold instead
+ * @return The holder itself
+ */
+ public default IHolder<ContainedType> replace(ContainedType newValue) {
+ return transform((oldValue) -> newValue);
+ }
}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/IPair.java b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/IPair.java
new file mode 100644
index 0000000..fb9648e
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/IPair.java
@@ -0,0 +1,84 @@
+package bjc.utils.data.experimental;
+
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+/**
+ * Represents a pair of values
+ *
+ * @author ben
+ * @param <LeftType>
+ * The type of the left side of the pair
+ * @param <RightType>
+ * The type of the right side of the pair
+ *
+ */
+public interface IPair<LeftType, RightType> {
+ /**
+ * Bind a function to the left value in this pair
+ *
+ * @param <BoundLeft>
+ * The type of the bound value
+ * @param leftBinder
+ * The function to use to bind
+ * @return A pair with the left type bound
+ */
+ public <BoundLeft> IPair<BoundLeft, RightType> bindLeft(
+ Function<LeftType, IPair<BoundLeft, RightType>> leftBinder);
+
+ /**
+ * Bind a function to the right value in this pair
+ *
+ * @param <BoundRight>
+ * The type of the bound value
+ * @param rightBinder
+ * The function to use to bind
+ * @return A pair with the right type bound
+ */
+ public <BoundRight> IPair<LeftType, BoundRight> bindRight(
+ Function<RightType, IPair<LeftType, BoundRight>> rightBinder);
+
+ /**
+ * Bind a function across the values in this pair
+ *
+ * @param <BoundLeft>
+ * The type of the bound left
+ * @param <BoundRight>
+ * The type of the bound right
+ * @param binder
+ * The function to bind with
+ * @return The bound pair
+ */
+ public <BoundLeft, BoundRight> IPair<BoundLeft, BoundRight> bind(
+ BiFunction<LeftType, RightType, IPair<BoundLeft, BoundRight>> binder);
+
+ /**
+ * Merge the two values in this pair into a single value
+ *
+ * @param <MergedType>
+ * The type of the single value
+ * @param merger
+ * The function to use for merging
+ * @return The pair, merged into a single value
+ */
+ public <MergedType> MergedType merge(
+ BiFunction<LeftType, RightType, MergedType> merger);
+
+ /**
+ * Get the value on the left side of the pair
+ *
+ * @return The value on the left side of the pair
+ */
+ public default LeftType getLeft() {
+ return merge((leftValue, rightValue) -> leftValue);
+ }
+
+ /**
+ * Get the value on the right side of the pair
+ *
+ * @return The value on the right side of the pair
+ */
+ public default RightType getRight() {
+ return merge((leftValue, rightValue) -> rightValue);
+ }
+}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Identity.java b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Identity.java
index 3cf0987..1780f2d 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Identity.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Identity.java
@@ -42,29 +42,32 @@ public class Identity<ContainedType> implements IHolder<ContainedType> {
return binder.apply(heldValue);
}
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
@Override
- public <MappedType> IHolder<MappedType> map(
- Function<ContainedType, MappedType> mapper) {
- return new Identity<>(mapper.apply(heldValue));
- }
-
- @Override
- public IHolder<ContainedType> transform(
- UnaryOperator<ContainedType> transformer) {
- heldValue = transformer.apply(heldValue);
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ } else if (obj == null) {
+ return false;
+ } else if (getClass() != obj.getClass()) {
+ return false;
+ }
- return this;
- }
+ Identity<?> other = (Identity<?>) obj;
- @Override
- public <UnwrappedType> UnwrappedType unwrap(
- Function<ContainedType, UnwrappedType> unwrapper) {
- return unwrapper.apply(heldValue);
- }
+ if (heldValue == null) {
+ if (other.heldValue != null) {
+ return false;
+ }
+ } else if (!heldValue.equals(other.heldValue)) {
+ return false;
+ }
- @Override
- public String toString() {
- return "holding[v=" + heldValue + "]";
+ return true;
}
/*
@@ -85,31 +88,28 @@ public class Identity<ContainedType> implements IHolder<ContainedType> {
return result;
}
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
@Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- } else if (obj == null) {
- return false;
- } else if (getClass() != obj.getClass()) {
- return false;
- }
+ public <MappedType> IHolder<MappedType> map(
+ Function<ContainedType, MappedType> mapper) {
+ return new Identity<>(mapper.apply(heldValue));
+ }
- Identity<?> other = (Identity<?>) obj;
+ @Override
+ public String toString() {
+ return "holding[v=" + heldValue + "]";
+ }
- if (heldValue == null) {
- if (other.heldValue != null) {
- return false;
- }
- } else if (!heldValue.equals(other.heldValue)) {
- return false;
- }
+ @Override
+ public IHolder<ContainedType> transform(
+ UnaryOperator<ContainedType> transformer) {
+ heldValue = transformer.apply(heldValue);
- return true;
+ return this;
+ }
+
+ @Override
+ public <UnwrappedType> UnwrappedType unwrap(
+ Function<ContainedType, UnwrappedType> unwrapper) {
+ return unwrapper.apply(heldValue);
}
} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Lazy.java b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Lazy.java
index e919fec..0d6fcef 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Lazy.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Lazy.java
@@ -26,8 +26,7 @@ public class Lazy<ContainedType> implements IHolder<ContainedType> {
private boolean holderBound;
- private IFunctionalList<UnaryOperator<BoundContainedType>> actions =
- new FunctionalList<>();
+ private IFunctionalList<UnaryOperator<BoundContainedType>> actions = new FunctionalList<>();
public BoundLazy(Supplier<IHolder<OldType>> supp,
Function<OldType, IHolder<BoundContainedType>> binder) {
@@ -38,8 +37,7 @@ public class Lazy<ContainedType> implements IHolder<ContainedType> {
@Override
public <BoundType> IHolder<BoundType> bind(
Function<BoundContainedType, IHolder<BoundType>> bindr) {
- IFunctionalList<UnaryOperator<BoundContainedType>> pendingActions =
- new FunctionalList<>();
+ IFunctionalList<UnaryOperator<BoundContainedType>> pendingActions = new FunctionalList<>();
actions.forEach(pendingActions::add);
@@ -62,8 +60,7 @@ public class Lazy<ContainedType> implements IHolder<ContainedType> {
@Override
public <MappedType> IHolder<MappedType> map(
Function<BoundContainedType, MappedType> mapper) {
- IFunctionalList<UnaryOperator<BoundContainedType>> pendingActions =
- new FunctionalList<>();
+ IFunctionalList<UnaryOperator<BoundContainedType>> pendingActions = new FunctionalList<>();
actions.forEach(pendingActions::add);
@@ -101,12 +98,19 @@ public class Lazy<ContainedType> implements IHolder<ContainedType> {
return boundHolder.unwrap(unwrapper);
}
+ @Override
+ public String toString() {
+ if (holderBound) {
+ return boundHolder.toString();
+ }
+
+ return "(unmaterialized)";
+ }
}
private Supplier<ContainedType> valueSupplier;
- private IFunctionalList<UnaryOperator<ContainedType>> actions =
- new FunctionalList<>();
+ private IFunctionalList<UnaryOperator<ContainedType>> actions = new FunctionalList<>();
private boolean valueMaterialized;
@@ -146,8 +150,7 @@ public class Lazy<ContainedType> implements IHolder<ContainedType> {
@Override
public <BoundType> IHolder<BoundType> bind(
Function<ContainedType, IHolder<BoundType>> binder) {
- IFunctionalList<UnaryOperator<ContainedType>> pendingActions =
- new FunctionalList<>();
+ IFunctionalList<UnaryOperator<ContainedType>> pendingActions = new FunctionalList<>();
actions.forEach(pendingActions::add);
@@ -167,8 +170,7 @@ public class Lazy<ContainedType> implements IHolder<ContainedType> {
@Override
public <MappedType> IHolder<MappedType> map(
Function<ContainedType, MappedType> mapper) {
- IFunctionalList<UnaryOperator<ContainedType>> pendingActions =
- new FunctionalList<>();
+ IFunctionalList<UnaryOperator<ContainedType>> pendingActions = new FunctionalList<>();
actions.forEach(pendingActions::add);
@@ -210,4 +212,17 @@ public class Lazy<ContainedType> implements IHolder<ContainedType> {
return unwrapper.apply(heldValue);
}
+
+ @Override
+ public String toString() {
+ if (valueMaterialized) {
+ if (actions.isEmpty()) {
+ return "value[v='" + heldValue + "']";
+ }
+
+ return "value[v='" + heldValue + "'] (has pending transforms)";
+ }
+
+ return "(unmaterialized)";
+ }
}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/LazyPair.java b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/LazyPair.java
new file mode 100644
index 0000000..04a4b61
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/LazyPair.java
@@ -0,0 +1,317 @@
+package bjc.utils.data.experimental;
+
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+/**
+ * A lazy implementation of a pair
+ *
+ * @author ben
+ *
+ * @param <LeftType>
+ * The type on the left side of the pair
+ * @param <RightType>
+ * The type on the right side of the pair
+ */
+public class LazyPair<LeftType, RightType>
+ implements IPair<LeftType, RightType> {
+ private static 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> 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 <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 <MergedType> MergedType merge(
+ BiFunction<NewLeft, NewRight, MergedType> merger) {
+ if (!pairBound) {
+ boundPair = binder.apply(oldSupplier.get());
+
+ pairBound = true;
+ }
+
+ return boundPair.merge(merger);
+ }
+ }
+
+ private static class BoundLazyPair<OldLeft, OldRight, NewLeft, NewRight>
+ implements IPair<NewLeft, NewRight> {
+ private Supplier<OldLeft> leftSupplier;
+ private Supplier<OldRight> rightSupplier;
+
+ private BiFunction<OldLeft, OldRight, IPair<NewLeft, NewRight>> binder;
+
+ private IPair<NewLeft, NewRight> boundPair;
+
+ 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> IPair<BoundLeft, NewRight> bindLeft(
+ Function<NewLeft, IPair<BoundLeft, NewRight>> leftBinder) {
+ 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) {
+ 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 <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);
+
+ return new BoundLazyPair<>(() -> {
+ if (!newPairMade.getValue()) {
+ newPair.replace(binder.apply(leftSupplier.get(),
+ rightSupplier.get()));
+
+ newPairMade.replace(false);
+ }
+
+ return newPair.unwrap((pair) -> pair.getLeft());
+ }, () -> {
+ if (!newPairMade.getValue()) {
+ newPair.replace(binder.apply(leftSupplier.get(),
+ rightSupplier.get()));
+
+ newPairMade.replace(false);
+ }
+
+ return newPair.unwrap((pair) -> pair.getRight());
+ }, bindr);
+ }
+
+ @Override
+ public <MergedType> MergedType merge(
+ BiFunction<NewLeft, NewRight, MergedType> merger) {
+ if (!pairBound) {
+ boundPair = binder.apply(leftSupplier.get(),
+ rightSupplier.get());
+
+ pairBound = true;
+ }
+
+ return boundPair.merge(merger);
+ }
+ }
+
+ private LeftType leftValue;
+ private RightType rightValue;
+
+ private Supplier<LeftType> leftSupplier;
+ private Supplier<RightType> rightSupplier;
+
+ private boolean leftMaterialized;
+ private boolean rightMaterialized;
+
+ /**
+ * Create a new lazy pair, using the set value s
+ *
+ * @param leftVal
+ * The value for the left side of the pair
+ * @param rightVal
+ * The value for the right side of the pair
+ */
+ public LazyPair(LeftType leftVal, RightType rightVal) {
+ leftValue = leftVal;
+ rightValue = rightVal;
+
+ leftMaterialized = true;
+ rightMaterialized = true;
+ }
+
+ /**
+ * Create a new lazy pair from the given value sources
+ *
+ * @param leftSupp
+ * The source for a value on the left side of the pair
+ * @param rightSupp
+ * The source for a value on the right side of the pair
+ */
+ public LazyPair(Supplier<LeftType> leftSupp,
+ Supplier<RightType> rightSupp) {
+ leftSupplier = leftSupp;
+ rightSupplier = rightSupp;
+
+ leftMaterialized = false;
+ rightMaterialized = false;
+ }
+
+ @Override
+ public <BoundLeft> IPair<BoundLeft, RightType> bindLeft(
+ Function<LeftType, IPair<BoundLeft, RightType>> leftBinder) {
+ Supplier<LeftType> leftSupp = () -> {
+ if (leftMaterialized) {
+ return leftValue;
+ }
+
+ return leftSupplier.get();
+ };
+
+ return new HalfBoundLazyPair<>(leftSupp, leftBinder);
+ }
+
+ @Override
+ public <BoundRight> IPair<LeftType, BoundRight> bindRight(
+ Function<RightType, IPair<LeftType, BoundRight>> rightBinder) {
+ Supplier<RightType> rightSupp = () -> {
+ if (rightMaterialized) {
+ return rightValue;
+ }
+
+ return rightSupplier.get();
+ };
+
+ return new HalfBoundLazyPair<>(rightSupp, rightBinder);
+ }
+
+ @Override
+ public <BoundLeft, BoundRight> IPair<BoundLeft, BoundRight> bind(
+ BiFunction<LeftType, RightType, IPair<BoundLeft, BoundRight>> binder) {
+ return new BoundLazyPair<>(leftSupplier, rightSupplier, binder);
+ }
+
+ @Override
+ public <MergedType> MergedType merge(
+ BiFunction<LeftType, RightType, MergedType> merger) {
+ if (!leftMaterialized) {
+ leftValue = leftSupplier.get();
+
+ leftMaterialized = true;
+ }
+
+ if (!rightMaterialized) {
+ rightValue = rightSupplier.get();
+
+ rightMaterialized = true;
+ }
+
+ return merger.apply(leftValue, rightValue);
+ }
+
+ @Override
+ public LeftType getLeft() {
+ if (!leftMaterialized) {
+ leftValue = leftSupplier.get();
+
+ leftMaterialized = true;
+ }
+
+ return leftValue;
+ }
+
+ @Override
+ public RightType getRight() {
+ if (!rightMaterialized) {
+ rightValue = rightSupplier.get();
+
+ rightMaterialized = true;
+ }
+
+ return rightValue;
+ }
+}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Pair.java b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Pair.java
new file mode 100644
index 0000000..87378d7
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Pair.java
@@ -0,0 +1,63 @@
+package bjc.utils.data.experimental;
+
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+/**
+ * A pair of values, with nothing special about them.
+ *
+ * @author ben
+ *
+ * @param <LeftType>
+ * The type of the left value
+ * @param <RightType>
+ * The type of the right value
+ */
+public class Pair<LeftType, RightType>
+ implements IPair<LeftType, RightType> {
+ private LeftType leftValue;
+ private RightType rightValue;
+
+ /**
+ * Create a new pair with both sides set to null
+ */
+ public Pair() {
+ }
+
+ /**
+ * Create a new pair with both sides set to the specified values
+ *
+ * @param left
+ * The value of the left side
+ * @param right
+ * The value of the right side
+ */
+ public Pair(LeftType left, RightType right) {
+ leftValue = left;
+ rightValue = right;
+ }
+
+ @Override
+ public <BoundLeft> IPair<BoundLeft, RightType> bindLeft(
+ Function<LeftType, IPair<BoundLeft, RightType>> leftBinder) {
+ return leftBinder.apply(leftValue);
+ }
+
+ @Override
+ public <BoundRight> IPair<LeftType, BoundRight> bindRight(
+ Function<RightType, IPair<LeftType, BoundRight>> rightBinder) {
+ return rightBinder.apply(rightValue);
+ }
+
+ @Override
+ public <BoundLeft, BoundRight> IPair<BoundLeft, BoundRight> bind(
+ BiFunction<LeftType, RightType, IPair<BoundLeft, BoundRight>> binder) {
+ return binder.apply(leftValue, rightValue);
+ }
+
+ @Override
+ public <MergedType> MergedType merge(
+ BiFunction<LeftType, RightType, MergedType> merger) {
+ return merger.apply(leftValue, rightValue);
+ }
+} \ No newline at end of file