summaryrefslogtreecommitdiff
path: root/src/main/java/bjc/data
diff options
context:
space:
mode:
authorBen Culkin <scorpress@gmail.com>2020-12-03 19:21:38 -0500
committerBen Culkin <scorpress@gmail.com>2020-12-03 19:21:38 -0500
commit0a8f34c27c6ef93c5c94d17728af62c7607e225f (patch)
tree3bbbbb6d62649c7411e7ae3d53a75786255ed84e /src/main/java/bjc/data
parent097a33bc2ecaa64a664550ddd62ccd8de47c51d0 (diff)
Rename types to match Java style
This renames several interfaces that had names like IWhatever, since that isn't a style that Java uses
Diffstat (limited to 'src/main/java/bjc/data')
-rw-r--r--src/main/java/bjc/data/Context.java (renamed from src/main/java/bjc/data/IContext.java)4
-rw-r--r--src/main/java/bjc/data/Contexts.java18
-rw-r--r--src/main/java/bjc/data/Either.java22
-rw-r--r--src/main/java/bjc/data/Holder.java (renamed from src/main/java/bjc/data/IHolder.java)26
-rw-r--r--src/main/java/bjc/data/IPair.java250
-rw-r--r--src/main/java/bjc/data/ITree.java286
-rw-r--r--src/main/java/bjc/data/Identity.java12
-rw-r--r--src/main/java/bjc/data/Lazy.java22
-rw-r--r--src/main/java/bjc/data/LazyPair.java22
-rw-r--r--src/main/java/bjc/data/ListHolder.java22
-rw-r--r--src/main/java/bjc/data/Option.java12
-rw-r--r--src/main/java/bjc/data/Pair.java306
-rw-r--r--src/main/java/bjc/data/SimplePair.java154
-rw-r--r--src/main/java/bjc/data/SimpleTree.java446
-rw-r--r--src/main/java/bjc/data/TopDownTransformIterator.java48
-rw-r--r--src/main/java/bjc/data/Tree.java606
-rw-r--r--src/main/java/bjc/data/internals/BoundLazy.java38
-rw-r--r--src/main/java/bjc/data/internals/BoundLazyPair.java40
-rw-r--r--src/main/java/bjc/data/internals/BoundListHolder.java24
-rw-r--r--src/main/java/bjc/data/internals/HalfBoundLazyPair.java40
-rw-r--r--src/main/java/bjc/data/internals/WrappedLazy.java24
-rw-r--r--src/main/java/bjc/data/internals/WrappedOption.java24
22 files changed, 1223 insertions, 1223 deletions
diff --git a/src/main/java/bjc/data/IContext.java b/src/main/java/bjc/data/Context.java
index e519501..7efdc4d 100644
--- a/src/main/java/bjc/data/IContext.java
+++ b/src/main/java/bjc/data/Context.java
@@ -5,7 +5,7 @@ package bjc.data;
* @author Ben Culkin
*
*/
-public interface IContext {
+public interface Context {
/**
* Register an object with this context.
*
@@ -19,7 +19,7 @@ public interface IContext {
*
* @return The parent of this context.
*/
- IContext getParent();
+ Context getParent();
/**
* Get an object from this context.
diff --git a/src/main/java/bjc/data/Contexts.java b/src/main/java/bjc/data/Contexts.java
index 75c8480..b028ad1 100644
--- a/src/main/java/bjc/data/Contexts.java
+++ b/src/main/java/bjc/data/Contexts.java
@@ -12,7 +12,7 @@ public class Contexts {
/**
* The null context, which always throws an exception.
*/
- public static final IContext NULL = new NullContextImpl();
+ public static final Context NULL = new NullContextImpl();
private Contexts() {
throw new UnsupportedOperationException();
@@ -23,7 +23,7 @@ public class Contexts {
*
* @return A context with no parent.
*/
- public static IContext create() {
+ public static Context create() {
return new ContextImpl(NULL);
}
@@ -34,13 +34,13 @@ public class Contexts {
*
* @return A context with the given context as its parent.
*/
- public static IContext create(IContext parent) {
+ public static Context create(Context parent) {
return new ContextImpl(parent);
}
- private static class NullContextImpl implements IContext {
+ private static class NullContextImpl implements Context {
@Override
- public IContext getParent() {
+ public Context getParent() {
return this;
}
@@ -60,13 +60,13 @@ public class Contexts {
}
}
- private static class ContextImpl implements IContext {
+ private static class ContextImpl implements Context {
- private final IContext parent;
+ private final Context parent;
private final Map<String, Object> objects;
- public ContextImpl(IContext parent) {
+ public ContextImpl(Context parent) {
this.parent = parent;
this.objects = new HashMap<>();
}
@@ -96,7 +96,7 @@ public class Contexts {
}
@Override
- public IContext getParent() {
+ public Context getParent() {
return parent;
}
}
diff --git a/src/main/java/bjc/data/Either.java b/src/main/java/bjc/data/Either.java
index 0ac3181..e4bc63d 100644
--- a/src/main/java/bjc/data/Either.java
+++ b/src/main/java/bjc/data/Either.java
@@ -15,7 +15,7 @@ import java.util.function.Function;
* The type that could be on the right.
*
*/
-public class Either<LeftType, RightType> implements IPair<LeftType, RightType> {
+public class Either<LeftType, RightType> implements Pair<LeftType, RightType> {
/**
* Create a new either with the left value occupied.
*
@@ -73,16 +73,16 @@ public class Either<LeftType, RightType> implements IPair<LeftType, RightType> {
}
@Override
- public <BoundLeft, BoundRight> IPair<BoundLeft, BoundRight> bind(
- final BiFunction<LeftType, RightType, IPair<BoundLeft, BoundRight>> binder) {
+ public <BoundLeft, BoundRight> Pair<BoundLeft, BoundRight> bind(
+ final BiFunction<LeftType, RightType, Pair<BoundLeft, BoundRight>> binder) {
if (binder == null) throw new NullPointerException("Binder must not be null");
return binder.apply(leftVal, rightVal);
}
@Override
- public <BoundLeft> IPair<BoundLeft, RightType>
- bindLeft(final Function<LeftType, IPair<BoundLeft, RightType>> leftBinder) {
+ public <BoundLeft> Pair<BoundLeft, RightType>
+ bindLeft(final Function<LeftType, Pair<BoundLeft, RightType>> leftBinder) {
if (leftBinder == null) throw new NullPointerException("Left binder must not be null");
if (isLeft) return leftBinder.apply(leftVal);
@@ -90,8 +90,8 @@ public class Either<LeftType, RightType> implements IPair<LeftType, RightType> {
}
@Override
- public <BoundRight> IPair<LeftType, BoundRight> bindRight(
- final Function<RightType, IPair<LeftType, BoundRight>> rightBinder) {
+ public <BoundRight> Pair<LeftType, BoundRight> bindRight(
+ final Function<RightType, Pair<LeftType, BoundRight>> rightBinder) {
if (rightBinder == null) throw new NullPointerException("Right binder must not be null");
if (isLeft) return new Either<>(leftVal, null);
@@ -100,8 +100,8 @@ public class Either<LeftType, RightType> implements IPair<LeftType, RightType> {
@Override
public <OtherLeft, OtherRight, CombinedLeft, CombinedRight>
- IPair<CombinedLeft, CombinedRight>
- combine(final IPair<OtherLeft, OtherRight> otherPair,
+ Pair<CombinedLeft, CombinedRight>
+ combine(final Pair<OtherLeft, OtherRight> otherPair,
final BiFunction<LeftType, OtherLeft, CombinedLeft> leftCombiner,
final BiFunction<RightType, OtherRight,
CombinedRight> rightCombiner) {
@@ -129,7 +129,7 @@ public class Either<LeftType, RightType> implements IPair<LeftType, RightType> {
}
@Override
- public <NewLeft> IPair<NewLeft, RightType>
+ public <NewLeft> Pair<NewLeft, RightType>
mapLeft(final Function<LeftType, NewLeft> mapper) {
if (mapper == null) throw new NullPointerException("Mapper must not be null");
@@ -138,7 +138,7 @@ public class Either<LeftType, RightType> implements IPair<LeftType, RightType> {
}
@Override
- public <NewRight> IPair<LeftType, NewRight>
+ public <NewRight> Pair<LeftType, NewRight>
mapRight(final Function<RightType, NewRight> mapper) {
if (mapper == null) throw new NullPointerException("Mapper must not be null");
diff --git a/src/main/java/bjc/data/IHolder.java b/src/main/java/bjc/data/Holder.java
index e0d39aa..f01812e 100644
--- a/src/main/java/bjc/data/IHolder.java
+++ b/src/main/java/bjc/data/Holder.java
@@ -18,7 +18,7 @@ import bjc.funcdata.theory.Functor;
* @param <ContainedType>
* The type of value held.
*/
-public interface IHolder<ContainedType> extends Functor<ContainedType> {
+public interface Holder<ContainedType> extends Functor<ContainedType> {
/**
* Bind a function across the value in this container.
*
@@ -30,8 +30,8 @@ public interface IHolder<ContainedType> extends Functor<ContainedType> {
*
* @return A holder from binding the value.
*/
- public <BoundType> IHolder<BoundType>
- bind(Function<ContainedType, IHolder<BoundType>> binder);
+ public <BoundType> Holder<BoundType>
+ bind(Function<ContainedType, Holder<BoundType>> binder);
/**
* Apply an action to the value.
@@ -51,14 +51,14 @@ public interface IHolder<ContainedType> extends Functor<ContainedType> {
default <ArgType, ReturnType> Function<Functor<ArgType>, Functor<ReturnType>>
fmap(final Function<ArgType, ReturnType> func) {
return argumentFunctor -> {
- if (!(argumentFunctor instanceof IHolder<?>)) {
+ if (!(argumentFunctor instanceof Holder<?>)) {
final String msg
= "This functor only supports mapping over instances of IHolder";
throw new IllegalArgumentException(msg);
}
- final IHolder<ArgType> holder = (IHolder<ArgType>) argumentFunctor;
+ final Holder<ArgType> holder = (Holder<ArgType>) argumentFunctor;
return holder.map(func);
};
@@ -80,7 +80,7 @@ public interface IHolder<ContainedType> extends Functor<ContainedType> {
*
* @return The function lifted over the holder.
*/
- public <NewType> Function<ContainedType, IHolder<NewType>>
+ public <NewType> Function<ContainedType, Holder<NewType>>
lift(Function<ContainedType, NewType> func);
/**
@@ -88,7 +88,7 @@ public interface IHolder<ContainedType> extends Functor<ContainedType> {
*
* @return A lazy version of this holder.
*/
- public default IHolder<ContainedType> makeLazy() {
+ public default Holder<ContainedType> makeLazy() {
return new WrappedLazy<>(this);
}
@@ -97,7 +97,7 @@ public interface IHolder<ContainedType> extends Functor<ContainedType> {
*
* @return A list version of this holder.
*/
- public default IHolder<ContainedType> makeList() {
+ public default Holder<ContainedType> makeList() {
return new BoundListHolder<>(new FunctionalList<>(this));
}
@@ -106,7 +106,7 @@ public interface IHolder<ContainedType> extends Functor<ContainedType> {
*
* @return An optional version of this holder.
*/
- public default IHolder<ContainedType> makeOptional() {
+ public default Holder<ContainedType> makeOptional() {
return new WrappedOption<>(this);
}
@@ -123,7 +123,7 @@ public interface IHolder<ContainedType> extends Functor<ContainedType> {
*
* @return A holder with the mapped value
*/
- public <MappedType> IHolder<MappedType>
+ public <MappedType> Holder<MappedType>
map(Function<ContainedType, MappedType> mapper);
/**
@@ -134,7 +134,7 @@ public interface IHolder<ContainedType> extends Functor<ContainedType> {
*
* @return The holder itself.
*/
- public default IHolder<ContainedType> replace(final ContainedType newValue) {
+ public default Holder<ContainedType> replace(final ContainedType newValue) {
return transform(oldValue -> newValue);
}
@@ -146,7 +146,7 @@ public interface IHolder<ContainedType> extends Functor<ContainedType> {
*
* @return The holder itself, for easy chaining.
*/
- public IHolder<ContainedType> transform(UnaryOperator<ContainedType> transformer);
+ public Holder<ContainedType> transform(UnaryOperator<ContainedType> transformer);
/**
* Unwrap the value contained in this holder so that it is no longer held.
@@ -171,7 +171,7 @@ public interface IHolder<ContainedType> extends Functor<ContainedType> {
*
* @return An instance of IHolder containing that value.
*/
- static <ElementType> IHolder<ElementType> of(ElementType contained) {
+ static <ElementType> Holder<ElementType> of(ElementType contained) {
return new Identity<>(contained);
}
}
diff --git a/src/main/java/bjc/data/IPair.java b/src/main/java/bjc/data/IPair.java
deleted file mode 100644
index f7d7956..0000000
--- a/src/main/java/bjc/data/IPair.java
+++ /dev/null
@@ -1,250 +0,0 @@
-package bjc.data;
-
-import java.util.function.BiConsumer;
-import java.util.function.BiFunction;
-import java.util.function.Function;
-
-import bjc.funcdata.theory.Bifunctor;
-
-/**
- * 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> extends Bifunctor<LeftType, RightType> {
- /**
- * 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);
-
- /**
- * 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);
-
- /**
- * Pairwise combine two pairs together.
- *
- * @param <OtherLeft>
- * The left type of the other pair.
- *
- * @param <OtherRight>
- * The right type of the other pair.
- *
- * @param otherPair
- * The pair to combine with.
- *
- * @return The pairs, pairwise combined together.
- */
- public default <OtherLeft, OtherRight>
- IPair<IPair<LeftType, OtherLeft>, IPair<RightType, OtherRight>>
- combine(final IPair<OtherLeft, OtherRight> otherPair) {
- return combine(otherPair,
- Pair<LeftType, OtherLeft>::new,
- Pair<RightType, OtherRight>::new);
- }
-
- /**
- * Combine the contents of two pairs together.
- *
- * @param <OtherLeft>
- * The type of the left value of the other pair.
- *
- * @param <OtherRight>
- * The type of the right value of the other pair.
- *
- * @param <CombinedLeft>
- * The type of the left value of the combined pair.
- *
- * @param <CombinedRight>
- * The type of the right value of the combined pair.
- *
- * @param otherPair
- * The other pair to combine with.
- *
- * @param leftCombiner
- * The function to combine the left values with.
- *
- * @param rightCombiner
- * The function to combine the right values with.
- *
- * @return A pair with its values combined.
- */
- public <OtherLeft, OtherRight, CombinedLeft, CombinedRight>
- IPair<CombinedLeft, CombinedRight>
- combine(IPair<OtherLeft, OtherRight> otherPair,
- BiFunction<LeftType, OtherLeft, CombinedLeft> leftCombiner,
- BiFunction<RightType, OtherRight, CombinedRight> rightCombiner);
-
- /**
- * Immediately perfom the specified action with the contents of this pair.
- *
- * @param consumer
- * The action to perform on the pair.
- */
- public default void doWith(final BiConsumer<LeftType, RightType> consumer) {
- merge((leftValue, rightValue) -> {
- consumer.accept(leftValue, rightValue);
-
- return null;
- });
- }
-
- @Override
- default <OldLeft, OldRight, NewLeft> LeftBifunctorMap<OldLeft, OldRight, NewLeft>
- fmapLeft(final Function<OldLeft, NewLeft> func) {
- return argumentPair -> {
- if (!(argumentPair instanceof IPair<?, ?>)) {
- final String msg
- = "This function can only be applied to instances of IPair";
-
- throw new IllegalArgumentException(msg);
- }
-
- final IPair<OldLeft, OldRight> argPair
- = (IPair<OldLeft, OldRight>) argumentPair;
-
- return argPair.mapLeft(func);
- };
- }
-
- @Override
- default <OldLeft, OldRight, NewRight> RightBifunctorMap<OldLeft, OldRight, NewRight>
- fmapRight(final Function<OldRight, NewRight> func) {
- return argumentPair -> {
- if (!(argumentPair instanceof IPair<?, ?>)) {
- final String msg
- = "This function can only be applied to instances of IPair";
-
- throw new IllegalArgumentException(msg);
- }
-
- final IPair<OldLeft, OldRight> argPair
- = (IPair<OldLeft, OldRight>) argumentPair;
-
- return argPair.mapRight(func);
- };
- }
-
- /**
- * Get the value on the left side of the pair.
- *
- * @return The value on the left side of the pair.
- */
- @Override
- 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.
- */
- @Override
- public default RightType getRight() {
- return merge((leftValue, rightValue) -> rightValue);
- }
-
- /**
- * Transform the value on the left side of the pair.
- *
- * Doesn't modify the pair.
- *
- * @param <NewLeft>
- * The new type of the left part of the pair.
- *
- * @param mapper
- * The function to use to transform the left part of the pair.
- *
- * @return The pair, with its left part transformed.
- */
- public <NewLeft> IPair<NewLeft, RightType>
- mapLeft(Function<LeftType, NewLeft> mapper);
-
- /**
- * Transform the value on the right side of the pair.
- *
- * Doesn't modify the pair.
- *
- * @param <NewRight>
- * The new type of the right part of the pair.
- *
- * @param mapper
- * The function to use to transform the right part of the
- * pair.
- *
- * @return The pair, with its right part transformed.
- */
- public <NewRight> IPair<LeftType, NewRight>
- mapRight(Function<RightType, NewRight> mapper);
-
- /**
- * 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);
-
- /**
- * Static pair constructor.
- *
- * @param left
- * The left side of the pair.
- * @param right
- * The right side of the pair.
- * @return A pair, with the specified left/right side.
- */
- public static <T1, T2> IPair<T1, T2> pair(T1 left, T2 right) {
- return new Pair<>(left, right);
- }
-}
diff --git a/src/main/java/bjc/data/ITree.java b/src/main/java/bjc/data/ITree.java
deleted file mode 100644
index 7f9c67e..0000000
--- a/src/main/java/bjc/data/ITree.java
+++ /dev/null
@@ -1,286 +0,0 @@
-package bjc.data;
-
-import java.util.function.BiFunction;
-import java.util.function.Consumer;
-import java.util.function.Function;
-import java.util.function.Predicate;
-import java.util.function.UnaryOperator;
-
-import bjc.funcdata.IList;
-import bjc.funcdata.bst.TreeLinearizationMethod;
-
-/**
- * A node in a homogeneous tree with a unlimited amount of children.
- *
- * @author ben
- *
- * @param <ContainedType>
- * The type of data contained in the tree nodes.
- *
- */
-public interface ITree<ContainedType> {
- /**
- * Append a child to this node.
- *
- * @param child
- * The child to append to this node.
- */
- void addChild(ITree<ContainedType> child);
-
- /**
- * Append a child to this node.
- *
- * @param child
- * The child to append to this node.
- */
- void addChild(ContainedType child);
-
- /**
- * Prepend a child to this node.
- *
- * @param child
- * The child to prepend to this node.
- */
- void prependChild(ITree<ContainedType> child);
-
- /**
- * Collapse a tree into a single version.
- *
- * @param <NewType>
- * The intermediate type being folded.
- *
- * @param <ReturnedType>
- * The type that is the end result.
- *
- * @param leafTransform
- * The function to use to convert leaf values.
- *
- * @param nodeCollapser
- * The function to use to convert internal nodes and
- * their children.
- *
- * @param resultTransformer
- * The function to use to convert a state to the
- * returned version.
- *
- * @return The final transformed state.
- */
- <NewType, ReturnedType> ReturnedType collapse(
- Function<ContainedType, NewType> leafTransform,
- BiFunction<ContainedType, IList<NewType>, NewType> nodeCollapser,
- Function<NewType, ReturnedType> resultTransformer);
-
- /**
- * Execute a given action for each of this tree's children.
- *
- * @param action
- * The action to execute for each child.
- */
- void doForChildren(Consumer<ITree<ContainedType>> action);
-
- /**
- * Expand the nodes of a tree into trees, and then merge the contents of those
- * trees into a single tree.
- *
- * @param mapper
- * The function to use to map values into trees.
- *
- * @return A tree, with some nodes expanded into trees.
- */
- default ITree<ContainedType>
- flatMapTree(final Function<ContainedType, ITree<ContainedType>> mapper) {
- return topDownTransform(dat -> TopDownTransformResult.PUSHDOWN, node -> {
- if (node.getChildrenCount() > 0) {
- final ITree<ContainedType> parent = node.transformHead(mapper);
-
- node.doForChildren(parent::addChild);
-
- return parent;
- }
-
- return node.transformHead(mapper);
- });
- }
-
- /**
- * Get the specified child of this tree.
- *
- * @param childNo
- * The number of the child to get.
- *
- * @return The specified child of this tree.
- */
- default ITree<ContainedType> getChild(final int childNo) {
- return transformChild(childNo, child -> child);
- }
-
- /**
- * Get a count of the number of direct children this node has.
- *
- * @return The number of direct children this node has.
- */
- int getChildrenCount();
-
- /**
- * Get a count of the number of direct children this node has.
- *
- * @return The number of direct children this node has.
- */
- default int size() {
- return getChildrenCount();
- }
-
- /**
- * Get the data stored in this node.
- *
- * @return The data stored in this node.
- */
- default ContainedType getHead() {
- return transformHead(head -> head);
- }
-
- /**
- * Rebuild the tree with the same structure, but different nodes.
- *
- * @param <MappedType>
- * The type of the new tree.
- *
- * @param leafTransformer
- * The function to use to transform leaf tokens.
- *
- * @param internalTransformer
- * The function to use to transform internal tokens.
- *
- * @return The tree, with the nodes changed.
- */
- <MappedType> ITree<MappedType> rebuildTree(
- Function<ContainedType, MappedType> leafTransformer,
- Function<ContainedType, MappedType> internalTransformer);
-
- /**
- * Transform some of the nodes in this tree.
- *
- * @param nodePicker
- * The predicate to use to pick nodes to transform.
- *
- * @param transformer
- * The function to use to transform picked nodes.
- */
- void selectiveTransform(Predicate<ContainedType> nodePicker,
- UnaryOperator<ContainedType> transformer);
-
- /**
- * Do a top-down transform of the tree.
- *
- * @param transformPicker
- * The function to use to pick how to progress.
- *
- * @param transformer
- * The function used to transform picked subtrees.
- *
- * @return The tree with the transform applied to picked subtrees.
- */
- ITree<ContainedType> topDownTransform(
- Function<ContainedType, TopDownTransformResult> transformPicker,
- UnaryOperator<ITree<ContainedType>> transformer);
-
- /**
- * Transform one of this nodes children.
- *
- * @param <TransformedType>
- * The type of the transformed value.
- *
- * @param childNo
- * The number of the child to transform.
- *
- * @param transformer
- * The function to use to transform the value.
- *
- * @return The transformed value.
- *
- * @throws IllegalArgumentException
- * if the childNo is out of bounds (0 &lt;=
- * childNo &lt;= childCount()).
- */
- <TransformedType> TransformedType transformChild(int childNo,
- Function<ITree<ContainedType>, TransformedType> transformer);
-
- /**
- * Transform the value that is the head of this node.
- *
- * @param <TransformedType>
- * The type of the transformed value.
- *
- * @param transformer
- * The function to use to transform the value.
- *
- * @return The transformed value.
- */
- <TransformedType> TransformedType
- transformHead(Function<ContainedType, TransformedType> transformer);
-
- /**
- * Transform the tree into a tree with a different type of token.
- *
- * @param <MappedType>
- * The type of the new tree.
- *
- * @param transformer
- * The function to use to transform tokens.
- *
- * @return A tree with the token types transformed.
- */
- default <MappedType> ITree<MappedType>
- transformTree(final Function<ContainedType, MappedType> transformer) {
- return rebuildTree(transformer, transformer);
- }
-
- /**
- * Perform an action on each part of the tree.
- *
- * @param linearizationMethod
- * The way to traverse the tree.
- *
- * @param action
- * The action to perform on each tree node.
- */
- void traverse(TreeLinearizationMethod linearizationMethod,
- Consumer<ContainedType> action);
-
- /**
- * Find the farthest to right child that satisfies the given predicate.
- *
- * @param childPred
- * The predicate to satisfy.
- *
- * @return The index of the right-most child that satisfies the predicate, or -1
- * if one doesn't exist.
- */
- int revFind(Predicate<ITree<ContainedType>> childPred);
-
- /**
- * Check if this tree contains any nodes that satisfy the predicate.
- *
- * @param pred
- * The predicate to look for.
- *
- * @return Whether or not any items satisfied the predicate.
- */
- default boolean containsMatching(Predicate<ContainedType> pred) {
- Toggle<Boolean> tog = new OneWayToggle<>(false, true);
-
- traverse(TreeLinearizationMethod.POSTORDER, val -> {
- if (pred.test(val)) tog.get();
- });
-
- return tog.get();
- }
-
- /**
- * Set the head of the tree.
- *
- * @param dat
- * The value to set as the head of the tree.
- */
- void setHead(ContainedType dat);
-}
diff --git a/src/main/java/bjc/data/Identity.java b/src/main/java/bjc/data/Identity.java
index 75b4ecd..e488072 100644
--- a/src/main/java/bjc/data/Identity.java
+++ b/src/main/java/bjc/data/Identity.java
@@ -11,7 +11,7 @@ import java.util.function.UnaryOperator;
* @param <ContainedType>
* The type contained in the holder.
*/
-public class Identity<ContainedType> implements IHolder<ContainedType> {
+public class Identity<ContainedType> implements Holder<ContainedType> {
/* The held value. */
private ContainedType heldValue;
@@ -31,8 +31,8 @@ public class Identity<ContainedType> implements IHolder<ContainedType> {
}
@Override
- public <BoundType> IHolder<BoundType>
- bind(final Function<ContainedType, IHolder<BoundType>> binder) {
+ public <BoundType> Holder<BoundType>
+ bind(final Function<ContainedType, Holder<BoundType>> binder) {
return binder.apply(heldValue);
}
@@ -64,7 +64,7 @@ public class Identity<ContainedType> implements IHolder<ContainedType> {
}
@Override
- public <NewType> Function<ContainedType, IHolder<NewType>>
+ public <NewType> Function<ContainedType, Holder<NewType>>
lift(final Function<ContainedType, NewType> func) {
return val -> {
return new Identity<>(func.apply(val));
@@ -72,7 +72,7 @@ public class Identity<ContainedType> implements IHolder<ContainedType> {
}
@Override
- public <MappedType> IHolder<MappedType>
+ public <MappedType> Holder<MappedType>
map(final Function<ContainedType, MappedType> mapper) {
return new Identity<>(mapper.apply(heldValue));
}
@@ -83,7 +83,7 @@ public class Identity<ContainedType> implements IHolder<ContainedType> {
}
@Override
- public IHolder<ContainedType>
+ public Holder<ContainedType>
transform(final UnaryOperator<ContainedType> transformer) {
heldValue = transformer.apply(heldValue);
diff --git a/src/main/java/bjc/data/Lazy.java b/src/main/java/bjc/data/Lazy.java
index 8573325..5fcd2ae 100644
--- a/src/main/java/bjc/data/Lazy.java
+++ b/src/main/java/bjc/data/Lazy.java
@@ -6,7 +6,7 @@ import java.util.function.UnaryOperator;
import bjc.data.internals.BoundLazy;
import bjc.funcdata.FunctionalList;
-import bjc.funcdata.IList;
+import bjc.funcdata.ListEx;
/**
* A holder that holds a means to create a value, but doesn't actually compute
@@ -17,7 +17,7 @@ import bjc.funcdata.IList;
* @param <ContainedType>
* The type of the value being held.
*/
-public class Lazy<ContainedType> implements IHolder<ContainedType> {
+public class Lazy<ContainedType> implements Holder<ContainedType> {
/* The supplier of the type. */
private Supplier<ContainedType> valueSupplier;
/* The actual type value. */
@@ -26,7 +26,7 @@ public class Lazy<ContainedType> implements IHolder<ContainedType> {
private boolean valueMaterialized;
/* The list of pending actions on the value. */
- private IList<UnaryOperator<ContainedType>> actions = new FunctionalList<>();
+ private ListEx<UnaryOperator<ContainedType>> actions = new FunctionalList<>();
/**
* Create a new lazy value from the specified seed value.
@@ -54,16 +54,16 @@ public class Lazy<ContainedType> implements IHolder<ContainedType> {
/* Create a new value from a supplier and a list of actions. */
private Lazy(final Supplier<ContainedType> supp,
- final IList<UnaryOperator<ContainedType>> pendingActions) {
+ final ListEx<UnaryOperator<ContainedType>> pendingActions) {
valueSupplier = supp;
actions = pendingActions;
}
@Override
- public <BoundType> IHolder<BoundType>
- bind(final Function<ContainedType, IHolder<BoundType>> binder) {
- final IList<UnaryOperator<ContainedType>> pendingActions = new FunctionalList<>();
+ public <BoundType> Holder<BoundType>
+ bind(final Function<ContainedType, Holder<BoundType>> binder) {
+ final ListEx<UnaryOperator<ContainedType>> pendingActions = new FunctionalList<>();
for (UnaryOperator<ContainedType> action : actions) {
pendingActions.add(action);
@@ -79,15 +79,15 @@ public class Lazy<ContainedType> implements IHolder<ContainedType> {
}
@Override
- public <NewType> Function<ContainedType, IHolder<NewType>>
+ public <NewType> Function<ContainedType, Holder<NewType>>
lift(final Function<ContainedType, NewType> func) {
return val -> new Lazy<>(func.apply(val));
}
@Override
- public <MappedType> IHolder<MappedType>
+ public <MappedType> Holder<MappedType>
map(final Function<ContainedType, MappedType> mapper) {
- final IList<UnaryOperator<ContainedType>> pendingActions = new FunctionalList<>();
+ final ListEx<UnaryOperator<ContainedType>> pendingActions = new FunctionalList<>();
for (UnaryOperator<ContainedType> action : actions) {
pendingActions.add(action);
@@ -126,7 +126,7 @@ public class Lazy<ContainedType> implements IHolder<ContainedType> {
}
@Override
- public IHolder<ContainedType>
+ public Holder<ContainedType>
transform(final UnaryOperator<ContainedType> transformer) {
actions.add(transformer);
diff --git a/src/main/java/bjc/data/LazyPair.java b/src/main/java/bjc/data/LazyPair.java
index 2481cd7..048254a 100644
--- a/src/main/java/bjc/data/LazyPair.java
+++ b/src/main/java/bjc/data/LazyPair.java
@@ -18,7 +18,7 @@ import bjc.data.internals.HalfBoundLazyPair;
* @param <RightType>
* The type on the right side of the pair.
*/
-public class LazyPair<LeftType, RightType> implements IPair<LeftType, RightType> {
+public class LazyPair<LeftType, RightType> implements Pair<LeftType, RightType> {
/* The supplier for the left value. */
private Supplier<LeftType> leftSupplier;
/* The left value. */
@@ -70,14 +70,14 @@ public class LazyPair<LeftType, RightType> implements IPair<LeftType, RightType>
}
@Override
- public <BoundLeft, BoundRight> IPair<BoundLeft, BoundRight> bind(
- final BiFunction<LeftType, RightType, IPair<BoundLeft, BoundRight>> binder) {
+ public <BoundLeft, BoundRight> Pair<BoundLeft, BoundRight> bind(
+ final BiFunction<LeftType, RightType, Pair<BoundLeft, BoundRight>> binder) {
return new BoundLazyPair<>(leftSupplier, rightSupplier, binder);
}
@Override
- public <BoundLeft> IPair<BoundLeft, RightType>
- bindLeft(final Function<LeftType, IPair<BoundLeft, RightType>> leftBinder) {
+ public <BoundLeft> Pair<BoundLeft, RightType>
+ bindLeft(final Function<LeftType, Pair<BoundLeft, RightType>> leftBinder) {
final Supplier<LeftType> leftSupp = () -> {
if (leftMaterialized) return leftValue;
@@ -88,8 +88,8 @@ public class LazyPair<LeftType, RightType> implements IPair<LeftType, RightType>
}
@Override
- public <BoundRight> IPair<LeftType, BoundRight> bindRight(
- final Function<RightType, IPair<LeftType, BoundRight>> rightBinder) {
+ public <BoundRight> Pair<LeftType, BoundRight> bindRight(
+ final Function<RightType, Pair<LeftType, BoundRight>> rightBinder) {
final Supplier<RightType> rightSupp = () -> {
if (rightMaterialized) return rightValue;
@@ -101,8 +101,8 @@ public class LazyPair<LeftType, RightType> implements IPair<LeftType, RightType>
@Override
public <OtherLeft, OtherRight, CombinedLeft, CombinedRight>
- IPair<CombinedLeft, CombinedRight>
- combine(final IPair<OtherLeft, OtherRight> otherPair,
+ Pair<CombinedLeft, CombinedRight>
+ combine(final Pair<OtherLeft, OtherRight> otherPair,
final BiFunction<LeftType, OtherLeft, CombinedLeft> leftCombiner,
final BiFunction<RightType, OtherRight,
CombinedRight> rightCombiner) {
@@ -139,7 +139,7 @@ public class LazyPair<LeftType, RightType> implements IPair<LeftType, RightType>
}
@Override
- public <NewLeft> IPair<NewLeft, RightType>
+ public <NewLeft> Pair<NewLeft, RightType>
mapLeft(final Function<LeftType, NewLeft> mapper) {
final Supplier<NewLeft> leftSupp = () -> {
if (leftMaterialized) return mapper.apply(leftValue);
@@ -157,7 +157,7 @@ public class LazyPair<LeftType, RightType> implements IPair<LeftType, RightType>
}
@Override
- public <NewRight> IPair<LeftType, NewRight>
+ public <NewRight> Pair<LeftType, NewRight>
mapRight(final Function<RightType, NewRight> mapper) {
final Supplier<LeftType> leftSupp = () -> {
if (leftMaterialized) return leftValue;
diff --git a/src/main/java/bjc/data/ListHolder.java b/src/main/java/bjc/data/ListHolder.java
index 79c900d..c8a75ff 100644
--- a/src/main/java/bjc/data/ListHolder.java
+++ b/src/main/java/bjc/data/ListHolder.java
@@ -5,7 +5,7 @@ import java.util.function.UnaryOperator;
import bjc.data.internals.BoundListHolder;
import bjc.funcdata.FunctionalList;
-import bjc.funcdata.IList;
+import bjc.funcdata.ListEx;
/**
* A holder that represents a set of non-deterministic computations.
@@ -15,8 +15,8 @@ import bjc.funcdata.IList;
* @param <ContainedType>
* The type of contained value.
*/
-public class ListHolder<ContainedType> implements IHolder<ContainedType> {
- private IList<ContainedType> heldValues;
+public class ListHolder<ContainedType> implements Holder<ContainedType> {
+ private ListEx<ContainedType> heldValues;
/**
* Create a new list holder.
@@ -36,34 +36,34 @@ public class ListHolder<ContainedType> implements IHolder<ContainedType> {
}
/* Create a new holder with values. */
- private ListHolder(final IList<ContainedType> toHold) {
+ private ListHolder(final ListEx<ContainedType> toHold) {
heldValues = toHold;
}
@Override
- public <BoundType> IHolder<BoundType>
- bind(final Function<ContainedType, IHolder<BoundType>> binder) {
- final IList<IHolder<BoundType>> boundValues = heldValues.map(binder);
+ public <BoundType> Holder<BoundType>
+ bind(final Function<ContainedType, Holder<BoundType>> binder) {
+ final ListEx<Holder<BoundType>> boundValues = heldValues.map(binder);
return new BoundListHolder<>(boundValues);
}
@Override
- public <NewType> Function<ContainedType, IHolder<NewType>>
+ public <NewType> Function<ContainedType, Holder<NewType>>
lift(final Function<ContainedType, NewType> func) {
return val -> new ListHolder<>(new FunctionalList<>(func.apply(val)));
}
@Override
- public <MappedType> IHolder<MappedType>
+ public <MappedType> Holder<MappedType>
map(final Function<ContainedType, MappedType> mapper) {
- final IList<MappedType> mappedValues = heldValues.map(mapper);
+ final ListEx<MappedType> mappedValues = heldValues.map(mapper);
return new ListHolder<>(mappedValues);
}
@Override
- public IHolder<ContainedType>
+ public Holder<ContainedType>
transform(final UnaryOperator<ContainedType> transformer) {
heldValues = heldValues.map(transformer);
diff --git a/src/main/java/bjc/data/Option.java b/src/main/java/bjc/data/Option.java
index 84e71a2..6c76d59 100644
--- a/src/main/java/bjc/data/Option.java
+++ b/src/main/java/bjc/data/Option.java
@@ -11,7 +11,7 @@ import java.util.function.UnaryOperator;
* @param <ContainedType>
* The type of the value that may or may not be held.
*/
-public class Option<ContainedType> implements IHolder<ContainedType> {
+public class Option<ContainedType> implements Holder<ContainedType> {
private ContainedType held;
/**
@@ -25,21 +25,21 @@ public class Option<ContainedType> implements IHolder<ContainedType> {
}
@Override
- public <BoundType> IHolder<BoundType>
- bind(final Function<ContainedType, IHolder<BoundType>> binder) {
+ public <BoundType> Holder<BoundType>
+ bind(final Function<ContainedType, Holder<BoundType>> binder) {
if (held == null) return new Option<>(null);
return binder.apply(held);
}
@Override
- public <NewType> Function<ContainedType, IHolder<NewType>>
+ public <NewType> Function<ContainedType, Holder<NewType>>
lift(final Function<ContainedType, NewType> func) {
return val -> new Option<>(func.apply(val));
}
@Override
- public <MappedType> IHolder<MappedType>
+ public <MappedType> Holder<MappedType>
map(final Function<ContainedType, MappedType> mapper) {
if (held == null) return new Option<>(null);
@@ -47,7 +47,7 @@ public class Option<ContainedType> implements IHolder<ContainedType> {
}
@Override
- public IHolder<ContainedType>
+ public Holder<ContainedType>
transform(final UnaryOperator<ContainedType> transformer) {
if (held != null) held = transformer.apply(held);
diff --git a/src/main/java/bjc/data/Pair.java b/src/main/java/bjc/data/Pair.java
index ea2f82f..42a28f8 100644
--- a/src/main/java/bjc/data/Pair.java
+++ b/src/main/java/bjc/data/Pair.java
@@ -1,154 +1,250 @@
package bjc.data;
+import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
+import bjc.funcdata.theory.Bifunctor;
+
/**
- * A pair of values, with nothing special about them.
+ * Represents a pair of values.
*
* @author ben
*
* @param <LeftType>
- * The type of the left value.
+ * The type of the left side of the pair.
*
* @param <RightType>
- * The type of the right value.
+ * The type of the right side of the pair.
+ *
*/
-public class Pair<LeftType, RightType> implements IPair<LeftType, RightType> {
- /* The left value. */
- private LeftType leftValue;
- /* The right value. */
- private RightType rightValue;
-
- /** Create a new pair with both sides set to null. */
- public Pair() {
- // Do nothing :)
- }
-
+public interface Pair<LeftType, RightType> extends Bifunctor<LeftType, RightType> {
/**
- * Create a new pair with both sides set to the specified values.
+ * Bind a function across the values in this pair.
*
- * @param left
- * The value of the left side.
+ * @param <BoundLeft>
+ * The type of the bound left.
*
- * @param right
- * The value of the right side.
+ * @param <BoundRight>
+ * The type of the bound right.
+ *
+ * @param binder
+ * The function to bind with.
+ *
+ * @return The bound pair.
*/
- public Pair(final LeftType left, final RightType right) {
- leftValue = left;
- rightValue = right;
- }
-
- @Override
- public <BoundLeft, BoundRight> IPair<BoundLeft, BoundRight> bind(
- final BiFunction<LeftType, RightType, IPair<BoundLeft, BoundRight>> binder) {
- if (binder == null) throw new NullPointerException("Binder must not be null.");
+ public <BoundLeft, BoundRight> Pair<BoundLeft, BoundRight>
+ bind(BiFunction<LeftType, RightType, Pair<BoundLeft, BoundRight>> binder);
- return binder.apply(leftValue, rightValue);
- }
+ /**
+ * 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> Pair<BoundLeft, RightType>
+ bindLeft(Function<LeftType, Pair<BoundLeft, RightType>> leftBinder);
- @Override
- public <BoundLeft> IPair<BoundLeft, RightType>
- bindLeft(final Function<LeftType, IPair<BoundLeft, RightType>> leftBinder) {
- if (leftBinder == null) throw new NullPointerException("Binder must not be null");
+ /**
+ * 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> Pair<LeftType, BoundRight>
+ bindRight(Function<RightType, Pair<LeftType, BoundRight>> rightBinder);
- return leftBinder.apply(leftValue);
+ /**
+ * Pairwise combine two pairs together.
+ *
+ * @param <OtherLeft>
+ * The left type of the other pair.
+ *
+ * @param <OtherRight>
+ * The right type of the other pair.
+ *
+ * @param otherPair
+ * The pair to combine with.
+ *
+ * @return The pairs, pairwise combined together.
+ */
+ public default <OtherLeft, OtherRight>
+ Pair<Pair<LeftType, OtherLeft>, Pair<RightType, OtherRight>>
+ combine(final Pair<OtherLeft, OtherRight> otherPair) {
+ return combine(otherPair,
+ SimplePair<LeftType, OtherLeft>::new,
+ SimplePair<RightType, OtherRight>::new);
}
- @Override
- public <BoundRight> IPair<LeftType, BoundRight> bindRight(
- final Function<RightType, IPair<LeftType, BoundRight>> rightBinder) {
- if (rightBinder == null) throw new NullPointerException("Binder must not be null");
+ /**
+ * Combine the contents of two pairs together.
+ *
+ * @param <OtherLeft>
+ * The type of the left value of the other pair.
+ *
+ * @param <OtherRight>
+ * The type of the right value of the other pair.
+ *
+ * @param <CombinedLeft>
+ * The type of the left value of the combined pair.
+ *
+ * @param <CombinedRight>
+ * The type of the right value of the combined pair.
+ *
+ * @param otherPair
+ * The other pair to combine with.
+ *
+ * @param leftCombiner
+ * The function to combine the left values with.
+ *
+ * @param rightCombiner
+ * The function to combine the right values with.
+ *
+ * @return A pair with its values combined.
+ */
+ public <OtherLeft, OtherRight, CombinedLeft, CombinedRight>
+ Pair<CombinedLeft, CombinedRight>
+ combine(Pair<OtherLeft, OtherRight> otherPair,
+ BiFunction<LeftType, OtherLeft, CombinedLeft> leftCombiner,
+ BiFunction<RightType, OtherRight, CombinedRight> rightCombiner);
- return rightBinder.apply(rightValue);
- }
+ /**
+ * Immediately perfom the specified action with the contents of this pair.
+ *
+ * @param consumer
+ * The action to perform on the pair.
+ */
+ public default void doWith(final BiConsumer<LeftType, RightType> consumer) {
+ merge((leftValue, rightValue) -> {
+ consumer.accept(leftValue, rightValue);
- @Override
- public <OtherLeft, OtherRight, CombinedLeft, CombinedRight>
- IPair<CombinedLeft, CombinedRight>
- combine(final IPair<OtherLeft, OtherRight> otherPair,
- final BiFunction<LeftType, OtherLeft, CombinedLeft> leftCombiner,
- final BiFunction<RightType, OtherRight,
- CombinedRight> rightCombiner) {
- return otherPair.bind((otherLeft, otherRight) -> {
- final CombinedLeft left = leftCombiner.apply(leftValue, otherLeft);
- final CombinedRight right = rightCombiner.apply(rightValue, otherRight);
-
- return new Pair<>(left, right);
+ return null;
});
}
@Override
- public <NewLeft> IPair<NewLeft, RightType>
- mapLeft(final Function<LeftType, NewLeft> mapper) {
- if (mapper == null) throw new NullPointerException("Mapper must not be null");
+ default <OldLeft, OldRight, NewLeft> LeftBifunctorMap<OldLeft, OldRight, NewLeft>
+ fmapLeft(final Function<OldLeft, NewLeft> func) {
+ return argumentPair -> {
+ if (!(argumentPair instanceof Pair<?, ?>)) {
+ final String msg
+ = "This function can only be applied to instances of IPair";
- return new Pair<>(mapper.apply(leftValue), rightValue);
- }
+ throw new IllegalArgumentException(msg);
+ }
- @Override
- public <NewRight> IPair<LeftType, NewRight>
- mapRight(final Function<RightType, NewRight> mapper) {
- if (mapper == null) throw new NullPointerException("Mapper must not be null");
+ final Pair<OldLeft, OldRight> argPair
+ = (Pair<OldLeft, OldRight>) argumentPair;
- return new Pair<>(leftValue, mapper.apply(rightValue));
+ return argPair.mapLeft(func);
+ };
}
@Override
- public <MergedType> MergedType
- merge(final BiFunction<LeftType, RightType, MergedType> merger) {
- if (merger == null) throw new NullPointerException("Merger must not be null");
+ default <OldLeft, OldRight, NewRight> RightBifunctorMap<OldLeft, OldRight, NewRight>
+ fmapRight(final Function<OldRight, NewRight> func) {
+ return argumentPair -> {
+ if (!(argumentPair instanceof Pair<?, ?>)) {
+ final String msg
+ = "This function can only be applied to instances of IPair";
- return merger.apply(leftValue, rightValue);
- }
+ throw new IllegalArgumentException(msg);
+ }
- @Override
- public String toString() {
- return String.format("Pair [leftValue='%s', rightValue='%s']", leftValue,
- rightValue);
+ final Pair<OldLeft, OldRight> argPair
+ = (Pair<OldLeft, OldRight>) argumentPair;
+
+ return argPair.mapRight(func);
+ };
}
+ /**
+ * Get the value on the left side of the pair.
+ *
+ * @return The value on the left side of the pair.
+ */
@Override
- public LeftType getLeft() {
- return leftValue;
+ 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.
+ */
@Override
- public RightType getRight() {
- return rightValue;
+ public default RightType getRight() {
+ return merge((leftValue, rightValue) -> rightValue);
}
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
+ /**
+ * Transform the value on the left side of the pair.
+ *
+ * Doesn't modify the pair.
+ *
+ * @param <NewLeft>
+ * The new type of the left part of the pair.
+ *
+ * @param mapper
+ * The function to use to transform the left part of the pair.
+ *
+ * @return The pair, with its left part transformed.
+ */
+ public <NewLeft> Pair<NewLeft, RightType>
+ mapLeft(Function<LeftType, NewLeft> mapper);
- result = prime * result + (leftValue == null ? 0 : leftValue.hashCode());
- result = prime * result + (rightValue == null ? 0 : rightValue.hashCode());
+ /**
+ * Transform the value on the right side of the pair.
+ *
+ * Doesn't modify the pair.
+ *
+ * @param <NewRight>
+ * The new type of the right part of the pair.
+ *
+ * @param mapper
+ * The function to use to transform the right part of the
+ * pair.
+ *
+ * @return The pair, with its right part transformed.
+ */
+ public <NewRight> Pair<LeftType, NewRight>
+ mapRight(Function<RightType, NewRight> mapper);
- return result;
- }
+ /**
+ * 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);
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) return true;
- if (obj == null) return false;
- if (!(obj instanceof Pair<?, ?>)) return false;
-
- final Pair<?, ?> other = (Pair<?, ?>) obj;
-
- if (leftValue == null) {
- if (other.leftValue != null) return false;
- } else if (!leftValue.equals(other.leftValue)) {
- return false;
- }
-
- if (rightValue == null) {
- if (other.rightValue != null) return false;
- } else if (!rightValue.equals(other.rightValue)) {
- return false;
- }
-
- return true;
+ /**
+ * Static pair constructor.
+ *
+ * @param left
+ * The left side of the pair.
+ * @param right
+ * The right side of the pair.
+ * @return A pair, with the specified left/right side.
+ */
+ public static <T1, T2> Pair<T1, T2> pair(T1 left, T2 right) {
+ return new SimplePair<>(left, right);
}
}
diff --git a/src/main/java/bjc/data/SimplePair.java b/src/main/java/bjc/data/SimplePair.java
new file mode 100644
index 0000000..48f5ca3
--- /dev/null
+++ b/src/main/java/bjc/data/SimplePair.java
@@ -0,0 +1,154 @@
+package bjc.data;
+
+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 SimplePair<LeftType, RightType> implements Pair<LeftType, RightType> {
+ /* The left value. */
+ private LeftType leftValue;
+ /* The right value. */
+ private RightType rightValue;
+
+ /** Create a new pair with both sides set to null. */
+ public SimplePair() {
+ // Do nothing :)
+ }
+
+ /**
+ * 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 SimplePair(final LeftType left, final RightType right) {
+ leftValue = left;
+ rightValue = right;
+ }
+
+ @Override
+ public <BoundLeft, BoundRight> Pair<BoundLeft, BoundRight> bind(
+ final BiFunction<LeftType, RightType, Pair<BoundLeft, BoundRight>> binder) {
+ if (binder == null) throw new NullPointerException("Binder must not be null.");
+
+ return binder.apply(leftValue, rightValue);
+ }
+
+ @Override
+ public <BoundLeft> Pair<BoundLeft, RightType>
+ bindLeft(final Function<LeftType, Pair<BoundLeft, RightType>> leftBinder) {
+ if (leftBinder == null) throw new NullPointerException("Binder must not be null");
+
+ return leftBinder.apply(leftValue);
+ }
+
+ @Override
+ public <BoundRight> Pair<LeftType, BoundRight> bindRight(
+ final Function<RightType, Pair<LeftType, BoundRight>> rightBinder) {
+ if (rightBinder == null) throw new NullPointerException("Binder must not be null");
+
+ return rightBinder.apply(rightValue);
+ }
+
+ @Override
+ public <OtherLeft, OtherRight, CombinedLeft, CombinedRight>
+ Pair<CombinedLeft, CombinedRight>
+ combine(final Pair<OtherLeft, OtherRight> otherPair,
+ final BiFunction<LeftType, OtherLeft, CombinedLeft> leftCombiner,
+ final BiFunction<RightType, OtherRight,
+ CombinedRight> rightCombiner) {
+ return otherPair.bind((otherLeft, otherRight) -> {
+ final CombinedLeft left = leftCombiner.apply(leftValue, otherLeft);
+ final CombinedRight right = rightCombiner.apply(rightValue, otherRight);
+
+ return new SimplePair<>(left, right);
+ });
+ }
+
+ @Override
+ public <NewLeft> Pair<NewLeft, RightType>
+ mapLeft(final Function<LeftType, NewLeft> mapper) {
+ if (mapper == null) throw new NullPointerException("Mapper must not be null");
+
+ return new SimplePair<>(mapper.apply(leftValue), rightValue);
+ }
+
+ @Override
+ public <NewRight> Pair<LeftType, NewRight>
+ mapRight(final Function<RightType, NewRight> mapper) {
+ if (mapper == null) throw new NullPointerException("Mapper must not be null");
+
+ return new SimplePair<>(leftValue, mapper.apply(rightValue));
+ }
+
+ @Override
+ public <MergedType> MergedType
+ merge(final BiFunction<LeftType, RightType, MergedType> merger) {
+ if (merger == null) throw new NullPointerException("Merger must not be null");
+
+ return merger.apply(leftValue, rightValue);
+ }
+
+ @Override
+ public String toString() {
+ return String.format("Pair [leftValue='%s', rightValue='%s']", leftValue,
+ rightValue);
+ }
+
+ @Override
+ public LeftType getLeft() {
+ return leftValue;
+ }
+
+ @Override
+ public RightType getRight() {
+ return rightValue;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+
+ result = prime * result + (leftValue == null ? 0 : leftValue.hashCode());
+ result = prime * result + (rightValue == null ? 0 : rightValue.hashCode());
+
+ return result;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) return true;
+ if (obj == null) return false;
+ if (!(obj instanceof SimplePair<?, ?>)) return false;
+
+ final SimplePair<?, ?> other = (SimplePair<?, ?>) obj;
+
+ if (leftValue == null) {
+ if (other.leftValue != null) return false;
+ } else if (!leftValue.equals(other.leftValue)) {
+ return false;
+ }
+
+ if (rightValue == null) {
+ if (other.rightValue != null) return false;
+ } else if (!rightValue.equals(other.rightValue)) {
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/src/main/java/bjc/data/SimpleTree.java b/src/main/java/bjc/data/SimpleTree.java
new file mode 100644
index 0000000..7d9fb6d
--- /dev/null
+++ b/src/main/java/bjc/data/SimpleTree.java
@@ -0,0 +1,446 @@
+package bjc.data;
+
+import java.util.function.BiFunction;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.function.UnaryOperator;
+
+import bjc.funcdata.FunctionalList;
+import bjc.funcdata.ListEx;
+import bjc.funcdata.bst.TreeLinearizationMethod;
+
+/**
+ * A node in a homogeneous tree.
+ *
+ * @author ben
+ *
+ * @param <ContainedType>
+ * The type contained in the tree.
+ */
+public class SimpleTree<ContainedType> implements Tree<ContainedType> {
+ /* The data/label for this node. */
+ private ContainedType data;
+
+ /* The children of this node. */
+ private ListEx<Tree<ContainedType>> children;
+
+ /* Whether this node has children. */
+ /*
+ * @NOTE Why have both this boolean and childCount? Why not just do a childCount
+ * == 0 whenever you'd check hasChildren?
+ *
+ * - Because hasChildren is set once and not reset, and really what it
+ * indicates is that children has been allocated.
+ */
+ private boolean hasChildren;
+ /* The number of children this node has. */
+ private int childCount = 0;
+
+ /* The ID of this node. */
+ private int ID;
+ /* The next ID to assign to a node. */
+ private static int nextID = 0;
+
+ /**
+ * Create a new leaf node in a tree.
+ */
+ public SimpleTree() {
+ this(null);
+ }
+
+ /**
+ * Create a new leaf node in a tree.
+ *
+ * @param leaf
+ * The data to store as a leaf node.
+ */
+ public SimpleTree(final ContainedType leaf) {
+ data = leaf;
+
+ hasChildren = false;
+
+ ID = nextID++;
+ }
+
+ /**
+ * Create a new tree node with the specified children.
+ *
+ * @param leaf
+ * The data to hold in this node.
+ *
+ * @param childrn
+ * A list of children for this node.
+ */
+ public SimpleTree(final ContainedType leaf, final ListEx<Tree<ContainedType>> childrn) {
+ this(leaf);
+
+ hasChildren = true;
+
+ childCount = childrn.getSize();
+
+ children = childrn;
+ }
+
+ /**
+ * Create a new tree node with the specified children.
+ *
+ * @param leaf
+ * The data to hold in this node.
+ *
+ * @param childrn
+ * A list of children for this node.
+ */
+ @SafeVarargs
+ public SimpleTree(final ContainedType leaf, final Tree<ContainedType>... childrn) {
+ this(leaf);
+
+ hasChildren = true;
+
+ childCount = 0;
+
+ children = new FunctionalList<>();
+
+ for (final Tree<ContainedType> child : childrn) {
+ children.add(child);
+
+ childCount++;
+ }
+ }
+
+ @Override
+ public void addChild(final ContainedType child) {
+ addChild(new SimpleTree<>(child));
+ }
+
+ @Override
+ public void addChild(final Tree<ContainedType> child) {
+ if (hasChildren == false) {
+ hasChildren = true;
+
+ children = new FunctionalList<>();
+ }
+
+ childCount++;
+
+ children.add(child);
+ }
+
+ @Override
+ public void prependChild(final Tree<ContainedType> child) {
+ if (hasChildren == false) {
+ hasChildren = true;
+
+ children = new FunctionalList<>();
+ }
+
+ childCount++;
+
+ children.prepend(child);
+ }
+
+ @Override
+ public void doForChildren(final Consumer<Tree<ContainedType>> action) {
+ if (childCount > 0) children.forEach(action);
+ }
+
+ @Override
+ public int getChildrenCount() {
+ return childCount;
+ }
+
+ @Override
+ public int revFind(final Predicate<Tree<ContainedType>> childPred) {
+ if (childCount == 0) return -1;
+
+ for (int i = childCount - 1; i >= 0; i--) {
+ if (childPred.test(getChild(i))) return i;
+ }
+
+ return -1;
+ }
+
+ @Override
+ public void traverse(final TreeLinearizationMethod linearizationMethod,
+ final Consumer<ContainedType> action) {
+ if (hasChildren) {
+ switch (linearizationMethod) {
+ case INORDER:
+ if (childCount != 2) {
+ final String msg = "Can only do in-order traversal for binary trees.";
+
+ throw new IllegalArgumentException(msg);
+ }
+
+ children.getByIndex(0).traverse(linearizationMethod, action);
+
+ action.accept(data);
+
+ children.getByIndex(1).traverse(linearizationMethod, action);
+ break;
+ case POSTORDER:
+ children.forEach(child -> child.traverse(linearizationMethod, action));
+
+ action.accept(data);
+ break;
+ case PREORDER:
+ action.accept(data);
+
+ children.forEach(child -> child.traverse(linearizationMethod, action));
+ break;
+ default:
+ break;
+
+ }
+ } else {
+ action.accept(data);
+ }
+ }
+
+ @Override
+ public <NewType, ReturnedType> ReturnedType collapse(
+ final Function<ContainedType, NewType> leafTransform,
+ final BiFunction<ContainedType, ListEx<NewType>, NewType> nodeCollapser,
+ final Function<NewType, ReturnedType> resultTransformer) {
+ return resultTransformer.apply(internalCollapse(leafTransform, nodeCollapser));
+ }
+
+ @Override
+ public Tree<ContainedType>
+ flatMapTree(final Function<ContainedType, Tree<ContainedType>> mapper) {
+ if (hasChildren) {
+ final Tree<ContainedType> flatMappedData = mapper.apply(data);
+
+ final ListEx<Tree<ContainedType>> mappedChildren
+ = children.map(child -> child.flatMapTree(mapper));
+
+ mappedChildren.forEach(flatMappedData::addChild);
+
+ return flatMappedData;
+ }
+
+ return mapper.apply(data);
+ }
+
+ /*
+ * Do a collapse of this tree.
+ */
+
+ private <NewType> NewType internalCollapse(
+ final Function<ContainedType, NewType> leafTransform,
+ final BiFunction<ContainedType, ListEx<NewType>, NewType> nodeCollapser) {
+ if (hasChildren) {
+ final ListEx<NewType> collapsedChildren = children.map(child -> {
+ final NewType collapsed = child.collapse(leafTransform, nodeCollapser,
+ subTreeVal -> subTreeVal);
+
+ return collapsed;
+ });
+
+ return nodeCollapser.apply(data, collapsedChildren);
+ }
+
+ return leafTransform.apply(data);
+ }
+
+ private void internalToString(final StringBuilder builder, final int indentLevel,
+ final boolean initial) {
+ if (!initial) {
+ for (int i = 0; i < indentLevel; i++) builder.append(">\t");
+ }
+
+ builder.append("Node #");
+ builder.append(ID);
+ builder.append(": ");
+ builder.append(data == null ? "(null)" : data.toString());
+ builder.append("\n");
+
+ if (hasChildren) {
+ children.forEach(child -> {
+ if (child instanceof SimpleTree<?>) {
+ final SimpleTree<ContainedType> kid = (SimpleTree<ContainedType>) child;
+
+ kid.internalToString(builder, indentLevel + 1, false);
+ } else {
+ for (int i = 0; i < indentLevel + 1; i++) {
+ builder.append(">\t");
+ }
+
+ builder.append("Unknown node of type ");
+ builder.append(child.getClass().getName());
+ builder.append("\n");
+ }
+ });
+ }
+ }
+
+ @Override
+ public <MappedType> Tree<MappedType> rebuildTree(
+ final Function<ContainedType, MappedType> leafTransformer,
+ final Function<ContainedType, MappedType> operatorTransformer) {
+ if (hasChildren) {
+ final ListEx<Tree<MappedType>> mappedChildren =
+ children.map(child ->
+ child.rebuildTree(leafTransformer, operatorTransformer));
+
+ final MappedType mapData = operatorTransformer.apply(data);
+ return new SimpleTree<>(mapData, mappedChildren);
+ }
+
+ return new SimpleTree<>(leafTransformer.apply(data));
+ }
+
+ @Override
+ public void selectiveTransform(final Predicate<ContainedType> nodePicker,
+ final UnaryOperator<ContainedType> transformer) {
+ if (hasChildren) {
+ children.forEach(child -> child.selectiveTransform(nodePicker, transformer));
+ } else {
+ data = transformer.apply(data);
+ }
+ }
+
+ @Override
+ public Tree<ContainedType> topDownTransform(
+ final Function<ContainedType, TopDownTransformResult> transformPicker,
+ final UnaryOperator<Tree<ContainedType>> transformer) {
+ final TopDownTransformResult transformResult = transformPicker.apply(data);
+
+ switch (transformResult) {
+ case PASSTHROUGH:
+ Tree<ContainedType> result = new SimpleTree<>(data);
+
+ if (hasChildren) {
+ children.forEach(child -> {
+ final Tree<ContainedType> kid
+ = child.topDownTransform(transformPicker, transformer);
+
+ result.addChild(kid);
+ });
+ }
+
+ return result;
+ case SKIP:
+ return this;
+ case TRANSFORM:
+ return transformer.apply(this);
+ case RTRANSFORM:
+ return transformer.apply(this).topDownTransform(transformPicker, transformer);
+ case PUSHDOWN:
+ result = new SimpleTree<>(data);
+
+ if (hasChildren) {
+ children.forEach(child -> {
+ final Tree<ContainedType> kid
+ = child.topDownTransform(transformPicker, transformer);
+
+ result.addChild(kid);
+ });
+ }
+
+ return transformer.apply(result);
+ case PULLUP:
+ final Tree<ContainedType> intermediateResult = transformer.apply(this);
+
+ result = new SimpleTree<>(intermediateResult.getHead());
+
+ intermediateResult.doForChildren(child -> {
+ final Tree<ContainedType> kid
+ = child.topDownTransform(transformPicker, transformer);
+
+ result.addChild(kid);
+ });
+
+ return result;
+ default:
+ final String msg = String.format("Recieved unknown transform result type %s",
+ transformResult);
+
+ throw new IllegalArgumentException(msg);
+ }
+ }
+
+ @Override
+ public <TransformedType> TransformedType transformChild(final int childNo,
+ final Function<Tree<ContainedType>, TransformedType> transformer) {
+ if (childNo < 0 || childNo > childCount - 1) {
+ final String msg = String.format("Child index #%d is invalid", childNo);
+
+ throw new IllegalArgumentException(msg);
+ }
+
+ final Tree<ContainedType> selectedKid = children.getByIndex(childNo);
+
+ return transformer.apply(selectedKid);
+ }
+
+ @Override
+ public Tree<ContainedType> getChild(final int childNo) {
+ if (childNo < 0 || childNo > childCount - 1) {
+ final String msg = String.format("Child index #%d is invalid", childNo);
+
+ throw new IllegalArgumentException(msg);
+ }
+ return children.getByIndex(childNo);
+ }
+
+ @Override
+ public <TransformedType> TransformedType
+ transformHead(final Function<ContainedType, TransformedType> transformer) {
+ return transformer.apply(data);
+ }
+
+ @Override
+ public void setHead(ContainedType dat) {
+ this.data = dat;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+
+ result = prime * result + childCount;
+ result = prime * result + (children == null ? 0 : children.hashCode());
+ result = prime * result + (data == null ? 0 : data.hashCode());
+
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+
+ internalToString(builder, 1, true);
+
+ /* Delete a trailing nl. */
+ builder.deleteCharAt(builder.length() - 1);
+
+ return builder.toString();
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) return true;
+ if (obj == null) return false;
+ if (!(obj instanceof SimpleTree<?>)) return false;
+
+ final SimpleTree<?> other = (SimpleTree<?>) obj;
+
+ if (data == null) {
+ if (other.data != null) return false;
+ } else if (!data.equals(other.data)) {
+ return false;
+ }
+
+ if (childCount != other.childCount) return false;
+
+ if (children == null) {
+ if (other.children != null) return false;
+ } else if (!children.equals(other.children)) {
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/src/main/java/bjc/data/TopDownTransformIterator.java b/src/main/java/bjc/data/TopDownTransformIterator.java
index cf211d3..28df590 100644
--- a/src/main/java/bjc/data/TopDownTransformIterator.java
+++ b/src/main/java/bjc/data/TopDownTransformIterator.java
@@ -26,7 +26,7 @@ import java.util.function.Function;
* The type of the nodes in the tree.
*/
public class TopDownTransformIterator<ContainedType>
- implements Iterator<ITree<ContainedType>> {
+ implements Iterator<Tree<ContainedType>> {
/**
* Alias type for a tree transformation.
*
@@ -35,8 +35,8 @@ public class TopDownTransformIterator<ContainedType>
* @param <ContainedType>
* The type contained in the tree.
*/
- public interface TreeTransform<ContainedType> extends BiFunction<ITree<ContainedType>,
- Consumer<Iterator<ITree<ContainedType>>>, ITree<ContainedType>> {
+ public interface TreeTransform<ContainedType> extends BiFunction<Tree<ContainedType>,
+ Consumer<Iterator<Tree<ContainedType>>>, Tree<ContainedType>> {
// Alias type; no body is needed
}
@@ -49,19 +49,19 @@ public class TopDownTransformIterator<ContainedType>
*/
private final TreeTransform<ContainedType> transform;
- private ITree<ContainedType> preParent;
- private ITree<ContainedType> postParent;
+ private Tree<ContainedType> preParent;
+ private Tree<ContainedType> postParent;
- private final Deque<ITree<ContainedType>> preChildren;
- private final Deque<ITree<ContainedType>> postChildren;
+ private final Deque<Tree<ContainedType>> preChildren;
+ private final Deque<Tree<ContainedType>> postChildren;
private TopDownTransformIterator<ContainedType> curChild;
private boolean done;
private boolean initial;
- private final Deque<Iterator<ITree<ContainedType>>> toYield;
- private Iterator<ITree<ContainedType>> currYield;
+ private final Deque<Iterator<Tree<ContainedType>>> toYield;
+ private Iterator<Tree<ContainedType>> currYield;
/**
* Create a new tree iterator.
@@ -76,7 +76,7 @@ public class TopDownTransformIterator<ContainedType>
public TopDownTransformIterator(
final Function<ContainedType, TopDownTransformResult> pickr,
final TreeTransform<ContainedType> transfrm,
- final ITree<ContainedType> tree) {
+ final Tree<ContainedType> tree) {
preParent = tree;
preChildren = new LinkedList<>();
@@ -96,7 +96,7 @@ public class TopDownTransformIterator<ContainedType>
* @param src
* The nodes to yield.
*/
- public void addYield(final Iterator<ITree<ContainedType>> src) {
+ public void addYield(final Iterator<Tree<ContainedType>> src) {
if (currYield != null) toYield.push(currYield);
currYield = src;
@@ -115,7 +115,7 @@ public class TopDownTransformIterator<ContainedType>
*
* @return The next yielded value.
*/
- public ITree<ContainedType> flushYields(final ITree<ContainedType> val) {
+ public Tree<ContainedType> flushYields(final Tree<ContainedType> val) {
if (currYield != null) {
/*
* We have non-sentinel values to yield.
@@ -144,14 +144,14 @@ public class TopDownTransformIterator<ContainedType>
}
@Override
- public ITree<ContainedType> next() {
+ public Tree<ContainedType> next() {
if (done) throw new NoSuchElementException();
/*
* Flush any values that need to be yielded.
*/
if (currYield != null) {
- ITree<ContainedType> yeld = flushYields(null);
+ Tree<ContainedType> yeld = flushYields(null);
if (yeld != null) return yeld;
}
@@ -164,7 +164,7 @@ public class TopDownTransformIterator<ContainedType>
switch (res) {
case PASSTHROUGH:
- postParent = new Tree<>(preParent.getHead());
+ postParent = new SimpleTree<>(preParent.getHead());
if (preParent.getChildrenCount() != 0) {
for (int i = 0; i < preParent.getChildrenCount(); i++) {
@@ -198,12 +198,12 @@ public class TopDownTransformIterator<ContainedType>
done = true;
return flushYields(
- transform.apply(new Tree<>(preParent.getHead()), this::addYield));
+ transform.apply(new SimpleTree<>(preParent.getHead()), this::addYield));
case PULLUP:
- final ITree<ContainedType> intRes
+ final Tree<ContainedType> intRes
= transform.apply(preParent, this::addYield);
- postParent = new Tree<>(intRes.getHead());
+ postParent = new SimpleTree<>(intRes.getHead());
if (intRes.getChildrenCount() != 0) {
for (int i = 0; i < intRes.getChildrenCount(); i++) {
@@ -228,22 +228,22 @@ public class TopDownTransformIterator<ContainedType>
curChild = new TopDownTransformIterator<>(picker, transform,
preChildren.pop());
- final ITree<ContainedType> res = curChild.next();
+ final Tree<ContainedType> res = curChild.next();
// System.out.println("\t\tTRACE: adding node " + res + " to children");
postChildren.add(res);
return flushYields(res);
}
- ITree<ContainedType> res = null;
+ Tree<ContainedType> res = null;
if (postParent == null) {
- res = new Tree<>(preParent.getHead());
+ res = new SimpleTree<>(preParent.getHead());
// System.out.println("\t\tTRACE: adding nodes " + postChildren + " to " +
// res);
- for (final ITree<ContainedType> child : postChildren) {
+ for (final Tree<ContainedType> child : postChildren) {
res.addChild(child);
}
@@ -254,7 +254,7 @@ public class TopDownTransformIterator<ContainedType>
// System.out.println("\t\tTRACE: adding nodes " + postChildren + " to " +
// res);
- for (final ITree<ContainedType> child : postChildren) {
+ for (final Tree<ContainedType> child : postChildren) {
res.addChild(child);
}
}
@@ -263,7 +263,7 @@ public class TopDownTransformIterator<ContainedType>
return flushYields(res);
}
- final ITree<ContainedType> res = curChild.next();
+ final Tree<ContainedType> res = curChild.next();
// System.out.println("\t\tTRACE: adding node " + res + " to children");
postChildren.add(res);
diff --git a/src/main/java/bjc/data/Tree.java b/src/main/java/bjc/data/Tree.java
index d0cfe3d..3e16e02 100644
--- a/src/main/java/bjc/data/Tree.java
+++ b/src/main/java/bjc/data/Tree.java
@@ -6,441 +6,281 @@ import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
-import bjc.funcdata.FunctionalList;
-import bjc.funcdata.IList;
+import bjc.funcdata.ListEx;
import bjc.funcdata.bst.TreeLinearizationMethod;
/**
- * A node in a homogeneous tree.
+ * A node in a homogeneous tree with a unlimited amount of children.
*
* @author ben
*
* @param <ContainedType>
- * The type contained in the tree.
+ * The type of data contained in the tree nodes.
+ *
*/
-public class Tree<ContainedType> implements ITree<ContainedType> {
- /* The data/label for this node. */
- private ContainedType data;
-
- /* The children of this node. */
- private IList<ITree<ContainedType>> children;
-
- /* Whether this node has children. */
- /*
- * @NOTE Why have both this boolean and childCount? Why not just do a childCount
- * == 0 whenever you'd check hasChildren?
- *
- * - Because hasChildren is set once and not reset, and really what it
- * indicates is that children has been allocated.
+public interface Tree<ContainedType> {
+ /**
+ * Append a child to this node.
+ *
+ * @param child
+ * The child to append to this node.
*/
- private boolean hasChildren;
- /* The number of children this node has. */
- private int childCount = 0;
-
- /* The ID of this node. */
- private int ID;
- /* The next ID to assign to a node. */
- private static int nextID = 0;
+ void addChild(Tree<ContainedType> child);
/**
- * Create a new leaf node in a tree.
+ * Append a child to this node.
+ *
+ * @param child
+ * The child to append to this node.
*/
- public Tree() {
- this(null);
- }
+ void addChild(ContainedType child);
/**
- * Create a new leaf node in a tree.
+ * Prepend a child to this node.
*
- * @param leaf
- * The data to store as a leaf node.
+ * @param child
+ * The child to prepend to this node.
*/
- public Tree(final ContainedType leaf) {
- data = leaf;
-
- hasChildren = false;
-
- ID = nextID++;
- }
+ void prependChild(Tree<ContainedType> child);
/**
- * Create a new tree node with the specified children.
+ * Collapse a tree into a single version.
+ *
+ * @param <NewType>
+ * The intermediate type being folded.
+ *
+ * @param <ReturnedType>
+ * The type that is the end result.
+ *
+ * @param leafTransform
+ * The function to use to convert leaf values.
+ *
+ * @param nodeCollapser
+ * The function to use to convert internal nodes and
+ * their children.
*
- * @param leaf
- * The data to hold in this node.
+ * @param resultTransformer
+ * The function to use to convert a state to the
+ * returned version.
*
- * @param childrn
- * A list of children for this node.
+ * @return The final transformed state.
*/
- public Tree(final ContainedType leaf, final IList<ITree<ContainedType>> childrn) {
- this(leaf);
+ <NewType, ReturnedType> ReturnedType collapse(
+ Function<ContainedType, NewType> leafTransform,
+ BiFunction<ContainedType, ListEx<NewType>, NewType> nodeCollapser,
+ Function<NewType, ReturnedType> resultTransformer);
- hasChildren = true;
-
- childCount = childrn.getSize();
-
- children = childrn;
- }
+ /**
+ * Execute a given action for each of this tree's children.
+ *
+ * @param action
+ * The action to execute for each child.
+ */
+ void doForChildren(Consumer<Tree<ContainedType>> action);
/**
- * Create a new tree node with the specified children.
+ * Expand the nodes of a tree into trees, and then merge the contents of those
+ * trees into a single tree.
*
- * @param leaf
- * The data to hold in this node.
+ * @param mapper
+ * The function to use to map values into trees.
*
- * @param childrn
- * A list of children for this node.
+ * @return A tree, with some nodes expanded into trees.
*/
- @SafeVarargs
- public Tree(final ContainedType leaf, final ITree<ContainedType>... childrn) {
- this(leaf);
-
- hasChildren = true;
-
- childCount = 0;
-
- children = new FunctionalList<>();
-
- for (final ITree<ContainedType> child : childrn) {
- children.add(child);
-
- childCount++;
- }
- }
-
- @Override
- public void addChild(final ContainedType child) {
- addChild(new Tree<>(child));
- }
-
- @Override
- public void addChild(final ITree<ContainedType> child) {
- if (hasChildren == false) {
- hasChildren = true;
-
- children = new FunctionalList<>();
- }
-
- childCount++;
-
- children.add(child);
- }
-
- @Override
- public void prependChild(final ITree<ContainedType> child) {
- if (hasChildren == false) {
- hasChildren = true;
-
- children = new FunctionalList<>();
- }
-
- childCount++;
-
- children.prepend(child);
- }
-
- @Override
- public void doForChildren(final Consumer<ITree<ContainedType>> action) {
- if (childCount > 0) children.forEach(action);
- }
-
- @Override
- public int getChildrenCount() {
- return childCount;
- }
-
- @Override
- public int revFind(final Predicate<ITree<ContainedType>> childPred) {
- if (childCount == 0) return -1;
-
- for (int i = childCount - 1; i >= 0; i--) {
- if (childPred.test(getChild(i))) return i;
- }
-
- return -1;
- }
-
- @Override
- public void traverse(final TreeLinearizationMethod linearizationMethod,
- final Consumer<ContainedType> action) {
- if (hasChildren) {
- switch (linearizationMethod) {
- case INORDER:
- if (childCount != 2) {
- final String msg = "Can only do in-order traversal for binary trees.";
-
- throw new IllegalArgumentException(msg);
- }
-
- children.getByIndex(0).traverse(linearizationMethod, action);
+ default Tree<ContainedType>
+ flatMapTree(final Function<ContainedType, Tree<ContainedType>> mapper) {
+ return topDownTransform(dat -> TopDownTransformResult.PUSHDOWN, node -> {
+ if (node.getChildrenCount() > 0) {
+ final Tree<ContainedType> parent = node.transformHead(mapper);
- action.accept(data);
-
- children.getByIndex(1).traverse(linearizationMethod, action);
- break;
- case POSTORDER:
- children.forEach(child -> child.traverse(linearizationMethod, action));
-
- action.accept(data);
- break;
- case PREORDER:
- action.accept(data);
-
- children.forEach(child -> child.traverse(linearizationMethod, action));
- break;
- default:
- break;
+ node.doForChildren(parent::addChild);
+ return parent;
}
- } else {
- action.accept(data);
- }
- }
-
- @Override
- public <NewType, ReturnedType> ReturnedType collapse(
- final Function<ContainedType, NewType> leafTransform,
- final BiFunction<ContainedType, IList<NewType>, NewType> nodeCollapser,
- final Function<NewType, ReturnedType> resultTransformer) {
- return resultTransformer.apply(internalCollapse(leafTransform, nodeCollapser));
- }
-
- @Override
- public ITree<ContainedType>
- flatMapTree(final Function<ContainedType, ITree<ContainedType>> mapper) {
- if (hasChildren) {
- final ITree<ContainedType> flatMappedData = mapper.apply(data);
-
- final IList<ITree<ContainedType>> mappedChildren
- = children.map(child -> child.flatMapTree(mapper));
-
- mappedChildren.forEach(flatMappedData::addChild);
-
- return flatMappedData;
- }
- return mapper.apply(data);
+ return node.transformHead(mapper);
+ });
}
- /*
- * Do a collapse of this tree.
+ /**
+ * Get the specified child of this tree.
+ *
+ * @param childNo
+ * The number of the child to get.
+ *
+ * @return The specified child of this tree.
*/
-
- private <NewType> NewType internalCollapse(
- final Function<ContainedType, NewType> leafTransform,
- final BiFunction<ContainedType, IList<NewType>, NewType> nodeCollapser) {
- if (hasChildren) {
- final IList<NewType> collapsedChildren = children.map(child -> {
- final NewType collapsed = child.collapse(leafTransform, nodeCollapser,
- subTreeVal -> subTreeVal);
-
- return collapsed;
- });
-
- return nodeCollapser.apply(data, collapsedChildren);
- }
-
- return leafTransform.apply(data);
- }
-
- private void internalToString(final StringBuilder builder, final int indentLevel,
- final boolean initial) {
- if (!initial) {
- for (int i = 0; i < indentLevel; i++) builder.append(">\t");
- }
-
- builder.append("Node #");
- builder.append(ID);
- builder.append(": ");
- builder.append(data == null ? "(null)" : data.toString());
- builder.append("\n");
-
- if (hasChildren) {
- children.forEach(child -> {
- if (child instanceof Tree<?>) {
- final Tree<ContainedType> kid = (Tree<ContainedType>) child;
-
- kid.internalToString(builder, indentLevel + 1, false);
- } else {
- for (int i = 0; i < indentLevel + 1; i++) {
- builder.append(">\t");
- }
-
- builder.append("Unknown node of type ");
- builder.append(child.getClass().getName());
- builder.append("\n");
- }
- });
- }
+ default Tree<ContainedType> getChild(final int childNo) {
+ return transformChild(childNo, child -> child);
}
- @Override
- public <MappedType> ITree<MappedType> rebuildTree(
- final Function<ContainedType, MappedType> leafTransformer,
- final Function<ContainedType, MappedType> operatorTransformer) {
- if (hasChildren) {
- final IList<ITree<MappedType>> mappedChildren =
- children.map(child ->
- child.rebuildTree(leafTransformer, operatorTransformer));
-
- final MappedType mapData = operatorTransformer.apply(data);
- return new Tree<>(mapData, mappedChildren);
- }
-
- return new Tree<>(leafTransformer.apply(data));
- }
+ /**
+ * Get a count of the number of direct children this node has.
+ *
+ * @return The number of direct children this node has.
+ */
+ int getChildrenCount();
- @Override
- public void selectiveTransform(final Predicate<ContainedType> nodePicker,
- final UnaryOperator<ContainedType> transformer) {
- if (hasChildren) {
- children.forEach(child -> child.selectiveTransform(nodePicker, transformer));
- } else {
- data = transformer.apply(data);
- }
+ /**
+ * Get a count of the number of direct children this node has.
+ *
+ * @return The number of direct children this node has.
+ */
+ default int size() {
+ return getChildrenCount();
}
- @Override
- public ITree<ContainedType> topDownTransform(
- final Function<ContainedType, TopDownTransformResult> transformPicker,
- final UnaryOperator<ITree<ContainedType>> transformer) {
- final TopDownTransformResult transformResult = transformPicker.apply(data);
-
- switch (transformResult) {
- case PASSTHROUGH:
- ITree<ContainedType> result = new Tree<>(data);
-
- if (hasChildren) {
- children.forEach(child -> {
- final ITree<ContainedType> kid
- = child.topDownTransform(transformPicker, transformer);
-
- result.addChild(kid);
- });
- }
-
- return result;
- case SKIP:
- return this;
- case TRANSFORM:
- return transformer.apply(this);
- case RTRANSFORM:
- return transformer.apply(this).topDownTransform(transformPicker, transformer);
- case PUSHDOWN:
- result = new Tree<>(data);
-
- if (hasChildren) {
- children.forEach(child -> {
- final ITree<ContainedType> kid
- = child.topDownTransform(transformPicker, transformer);
-
- result.addChild(kid);
- });
- }
-
- return transformer.apply(result);
- case PULLUP:
- final ITree<ContainedType> intermediateResult = transformer.apply(this);
-
- result = new Tree<>(intermediateResult.getHead());
-
- intermediateResult.doForChildren(child -> {
- final ITree<ContainedType> kid
- = child.topDownTransform(transformPicker, transformer);
-
- result.addChild(kid);
- });
-
- return result;
- default:
- final String msg = String.format("Recieved unknown transform result type %s",
- transformResult);
-
- throw new IllegalArgumentException(msg);
- }
+ /**
+ * Get the data stored in this node.
+ *
+ * @return The data stored in this node.
+ */
+ default ContainedType getHead() {
+ return transformHead(head -> head);
}
- @Override
- public <TransformedType> TransformedType transformChild(final int childNo,
- final Function<ITree<ContainedType>, TransformedType> transformer) {
- if (childNo < 0 || childNo > childCount - 1) {
- final String msg = String.format("Child index #%d is invalid", childNo);
-
- throw new IllegalArgumentException(msg);
- }
-
- final ITree<ContainedType> selectedKid = children.getByIndex(childNo);
+ /**
+ * Rebuild the tree with the same structure, but different nodes.
+ *
+ * @param <MappedType>
+ * The type of the new tree.
+ *
+ * @param leafTransformer
+ * The function to use to transform leaf tokens.
+ *
+ * @param internalTransformer
+ * The function to use to transform internal tokens.
+ *
+ * @return The tree, with the nodes changed.
+ */
+ <MappedType> Tree<MappedType> rebuildTree(
+ Function<ContainedType, MappedType> leafTransformer,
+ Function<ContainedType, MappedType> internalTransformer);
- return transformer.apply(selectedKid);
- }
+ /**
+ * Transform some of the nodes in this tree.
+ *
+ * @param nodePicker
+ * The predicate to use to pick nodes to transform.
+ *
+ * @param transformer
+ * The function to use to transform picked nodes.
+ */
+ void selectiveTransform(Predicate<ContainedType> nodePicker,
+ UnaryOperator<ContainedType> transformer);
- @Override
- public ITree<ContainedType> getChild(final int childNo) {
- if (childNo < 0 || childNo > childCount - 1) {
- final String msg = String.format("Child index #%d is invalid", childNo);
+ /**
+ * Do a top-down transform of the tree.
+ *
+ * @param transformPicker
+ * The function to use to pick how to progress.
+ *
+ * @param transformer
+ * The function used to transform picked subtrees.
+ *
+ * @return The tree with the transform applied to picked subtrees.
+ */
+ Tree<ContainedType> topDownTransform(
+ Function<ContainedType, TopDownTransformResult> transformPicker,
+ UnaryOperator<Tree<ContainedType>> transformer);
- throw new IllegalArgumentException(msg);
- }
- return children.getByIndex(childNo);
- }
+ /**
+ * Transform one of this nodes children.
+ *
+ * @param <TransformedType>
+ * The type of the transformed value.
+ *
+ * @param childNo
+ * The number of the child to transform.
+ *
+ * @param transformer
+ * The function to use to transform the value.
+ *
+ * @return The transformed value.
+ *
+ * @throws IllegalArgumentException
+ * if the childNo is out of bounds (0 &lt;=
+ * childNo &lt;= childCount()).
+ */
+ <TransformedType> TransformedType transformChild(int childNo,
+ Function<Tree<ContainedType>, TransformedType> transformer);
- @Override
- public <TransformedType> TransformedType
- transformHead(final Function<ContainedType, TransformedType> transformer) {
- return transformer.apply(data);
- }
+ /**
+ * Transform the value that is the head of this node.
+ *
+ * @param <TransformedType>
+ * The type of the transformed value.
+ *
+ * @param transformer
+ * The function to use to transform the value.
+ *
+ * @return The transformed value.
+ */
+ <TransformedType> TransformedType
+ transformHead(Function<ContainedType, TransformedType> transformer);
- @Override
- public void setHead(ContainedType dat) {
- this.data = dat;
+ /**
+ * Transform the tree into a tree with a different type of token.
+ *
+ * @param <MappedType>
+ * The type of the new tree.
+ *
+ * @param transformer
+ * The function to use to transform tokens.
+ *
+ * @return A tree with the token types transformed.
+ */
+ default <MappedType> Tree<MappedType>
+ transformTree(final Function<ContainedType, MappedType> transformer) {
+ return rebuildTree(transformer, transformer);
}
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
-
- result = prime * result + childCount;
- result = prime * result + (children == null ? 0 : children.hashCode());
- result = prime * result + (data == null ? 0 : data.hashCode());
-
- return result;
- }
+ /**
+ * Perform an action on each part of the tree.
+ *
+ * @param linearizationMethod
+ * The way to traverse the tree.
+ *
+ * @param action
+ * The action to perform on each tree node.
+ */
+ void traverse(TreeLinearizationMethod linearizationMethod,
+ Consumer<ContainedType> action);
- @Override
- public String toString() {
- final StringBuilder builder = new StringBuilder();
+ /**
+ * Find the farthest to right child that satisfies the given predicate.
+ *
+ * @param childPred
+ * The predicate to satisfy.
+ *
+ * @return The index of the right-most child that satisfies the predicate, or -1
+ * if one doesn't exist.
+ */
+ int revFind(Predicate<Tree<ContainedType>> childPred);
- internalToString(builder, 1, true);
+ /**
+ * Check if this tree contains any nodes that satisfy the predicate.
+ *
+ * @param pred
+ * The predicate to look for.
+ *
+ * @return Whether or not any items satisfied the predicate.
+ */
+ default boolean containsMatching(Predicate<ContainedType> pred) {
+ Toggle<Boolean> tog = new OneWayToggle<>(false, true);
- /* Delete a trailing nl. */
- builder.deleteCharAt(builder.length() - 1);
+ traverse(TreeLinearizationMethod.POSTORDER, val -> {
+ if (pred.test(val)) tog.get();
+ });
- return builder.toString();
+ return tog.get();
}
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) return true;
- if (obj == null) return false;
- if (!(obj instanceof Tree<?>)) return false;
-
- final Tree<?> other = (Tree<?>) obj;
-
- if (data == null) {
- if (other.data != null) return false;
- } else if (!data.equals(other.data)) {
- return false;
- }
-
- if (childCount != other.childCount) return false;
-
- if (children == null) {
- if (other.children != null) return false;
- } else if (!children.equals(other.children)) {
- return false;
- }
-
- return true;
- }
+ /**
+ * Set the head of the tree.
+ *
+ * @param dat
+ * The value to set as the head of the tree.
+ */
+ void setHead(ContainedType dat);
}
diff --git a/src/main/java/bjc/data/internals/BoundLazy.java b/src/main/java/bjc/data/internals/BoundLazy.java
index a350a2b..0e0e95c 100644
--- a/src/main/java/bjc/data/internals/BoundLazy.java
+++ b/src/main/java/bjc/data/internals/BoundLazy.java
@@ -4,10 +4,10 @@ import java.util.function.Function;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
-import bjc.data.IHolder;
+import bjc.data.Holder;
import bjc.data.Lazy;
import bjc.funcdata.FunctionalList;
-import bjc.funcdata.IList;
+import bjc.funcdata.ListEx;
/**
* Implements a lazy holder that has been bound.
@@ -19,21 +19,21 @@ import bjc.funcdata.IList;
* The type of the new bound value.
*/
public class BoundLazy<OldType, BoundContainedType>
- implements IHolder<BoundContainedType> {
+ implements Holder<BoundContainedType> {
/* The old value. */
- private final Supplier<IHolder<OldType>> oldSupplier;
+ private final Supplier<Holder<OldType>> oldSupplier;
/* The function to use to transform the old value into a new value. */
- private final Function<OldType, IHolder<BoundContainedType>> binder;
+ private final Function<OldType, Holder<BoundContainedType>> binder;
/* The bound value being held. */
- private IHolder<BoundContainedType> boundHolder;
+ private Holder<BoundContainedType> boundHolder;
/* Whether the bound value has been actualized or not. */
private boolean holderBound;
/* Transformations currently pending on the bound value. */
- private final IList<UnaryOperator<BoundContainedType>> actions
+ private final ListEx<UnaryOperator<BoundContainedType>> actions
= new FunctionalList<>();
/**
@@ -45,20 +45,20 @@ public class BoundLazy<OldType, BoundContainedType>
* @param binder
* The function to use to bind the old value to the new one.
*/
- public BoundLazy(final Supplier<IHolder<OldType>> supp,
- final Function<OldType, IHolder<BoundContainedType>> binder) {
+ public BoundLazy(final Supplier<Holder<OldType>> supp,
+ final Function<OldType, Holder<BoundContainedType>> binder) {
oldSupplier = supp;
this.binder = binder;
}
@Override
- public <BoundType> IHolder<BoundType>
- bind(final Function<BoundContainedType, IHolder<BoundType>> bindr) {
+ public <BoundType> Holder<BoundType>
+ bind(final Function<BoundContainedType, Holder<BoundType>> bindr) {
if (bindr == null)
throw new NullPointerException("Binder must not be null");
/* Prepare a list of pending actions. */
- final IList<UnaryOperator<BoundContainedType>> pendingActions
+ final ListEx<UnaryOperator<BoundContainedType>> pendingActions
= new FunctionalList<>();
for (UnaryOperator<BoundContainedType> pendAct : actions) {
@@ -66,8 +66,8 @@ public class BoundLazy<OldType, BoundContainedType>
}
/* Create the new supplier of a value. */
- final Supplier<IHolder<BoundContainedType>> typeSupplier = () -> {
- IHolder<BoundContainedType> oldHolder = boundHolder;
+ final Supplier<Holder<BoundContainedType>> typeSupplier = () -> {
+ Holder<BoundContainedType> oldHolder = boundHolder;
/* Bind the value if it hasn't been bound before. */
if (!holderBound) {
@@ -83,7 +83,7 @@ public class BoundLazy<OldType, BoundContainedType>
}
@Override
- public <NewType> Function<BoundContainedType, IHolder<NewType>>
+ public <NewType> Function<BoundContainedType, Holder<NewType>>
lift(final Function<BoundContainedType, NewType> func) {
if (func == null)
throw new NullPointerException("Function to lift must not be null");
@@ -94,13 +94,13 @@ public class BoundLazy<OldType, BoundContainedType>
}
@Override
- public <MappedType> IHolder<MappedType>
+ public <MappedType> Holder<MappedType>
map(final Function<BoundContainedType, MappedType> mapper) {
if (mapper == null)
throw new NullPointerException("Mapper must not be null");
/* Prepare a list of pending actions. */
- final IList<UnaryOperator<BoundContainedType>> pendingActions
+ final ListEx<UnaryOperator<BoundContainedType>> pendingActions
= new FunctionalList<>();
for (UnaryOperator<BoundContainedType> pendAct : actions) {
@@ -109,7 +109,7 @@ public class BoundLazy<OldType, BoundContainedType>
/* Prepare the new supplier. */
final Supplier<MappedType> typeSupplier = () -> {
- IHolder<BoundContainedType> oldHolder = boundHolder;
+ Holder<BoundContainedType> oldHolder = boundHolder;
/* Bound the value if it hasn't been bound. */
if (!holderBound) {
@@ -133,7 +133,7 @@ public class BoundLazy<OldType, BoundContainedType>
}
@Override
- public IHolder<BoundContainedType>
+ public Holder<BoundContainedType>
transform(final UnaryOperator<BoundContainedType> transformer) {
if (transformer == null)
throw new NullPointerException("Transformer must not be null");
diff --git a/src/main/java/bjc/data/internals/BoundLazyPair.java b/src/main/java/bjc/data/internals/BoundLazyPair.java
index e081c04..91981de 100644
--- a/src/main/java/bjc/data/internals/BoundLazyPair.java
+++ b/src/main/java/bjc/data/internals/BoundLazyPair.java
@@ -4,8 +4,8 @@ import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
-import bjc.data.IHolder;
-import bjc.data.IPair;
+import bjc.data.Holder;
+import bjc.data.Pair;
import bjc.data.Identity;
import bjc.data.LazyPair;
@@ -16,17 +16,17 @@ import bjc.data.LazyPair;
*/
@SuppressWarnings("javadoc")
public class BoundLazyPair<OldLeft, OldRight, NewLeft, NewRight>
- implements IPair<NewLeft, NewRight> {
+ implements Pair<NewLeft, NewRight> {
/* The supplier of the left value. */
private final Supplier<OldLeft> leftSupplier;
/* The supplier of the right value. */
private final Supplier<OldRight> rightSupplier;
/* The binder to transform values. */
- private final BiFunction<OldLeft, OldRight, IPair<NewLeft, NewRight>> binder;
+ private final BiFunction<OldLeft, OldRight, Pair<NewLeft, NewRight>> binder;
/* The bound pair. */
- private IPair<NewLeft, NewRight> boundPair;
+ private Pair<NewLeft, NewRight> boundPair;
/* Whether the pair has been bound yet. */
private boolean pairBound;
@@ -46,20 +46,20 @@ public class BoundLazyPair<OldLeft, OldRight, NewLeft, NewRight>
*/
public BoundLazyPair(final Supplier<OldLeft> leftSupp,
final Supplier<OldRight> rightSupp,
- final BiFunction<OldLeft, OldRight, IPair<NewLeft, NewRight>> bindr) {
+ final BiFunction<OldLeft, OldRight, Pair<NewLeft, NewRight>> bindr) {
leftSupplier = leftSupp;
rightSupplier = rightSupp;
binder = bindr;
}
@Override
- public <BoundLeft, BoundRight> IPair<BoundLeft, BoundRight> bind(
- final BiFunction<NewLeft, NewRight, IPair<BoundLeft, BoundRight>> bindr) {
+ public <BoundLeft, BoundRight> Pair<BoundLeft, BoundRight> bind(
+ final BiFunction<NewLeft, NewRight, Pair<BoundLeft, BoundRight>> bindr) {
if (bindr == null)
throw new NullPointerException("Binder must not be null");
- final IHolder<IPair<NewLeft, NewRight>> newPair = new Identity<>(boundPair);
- final IHolder<Boolean> newPairMade = new Identity<>(pairBound);
+ final Holder<Pair<NewLeft, NewRight>> newPair = new Identity<>(boundPair);
+ final Holder<Boolean> newPairMade = new Identity<>(pairBound);
final Supplier<NewLeft> leftSupp = () -> {
if (!newPairMade.getValue()) {
@@ -91,13 +91,13 @@ public class BoundLazyPair<OldLeft, OldRight, NewLeft, NewRight>
}
@Override
- public <BoundLeft> IPair<BoundLeft, NewRight>
- bindLeft(final Function<NewLeft, IPair<BoundLeft, NewRight>> leftBinder) {
+ public <BoundLeft> Pair<BoundLeft, NewRight>
+ bindLeft(final Function<NewLeft, Pair<BoundLeft, NewRight>> leftBinder) {
if (leftBinder == null)
throw new NullPointerException("Left binder must not be null");
final Supplier<NewLeft> leftSupp = () -> {
- IPair<NewLeft, NewRight> newPair = boundPair;
+ Pair<NewLeft, NewRight> newPair = boundPair;
if (!pairBound) {
/*
@@ -113,13 +113,13 @@ public class BoundLazyPair<OldLeft, OldRight, NewLeft, NewRight>
}
@Override
- public <BoundRight> IPair<NewLeft, BoundRight>
- bindRight(final Function<NewRight, IPair<NewLeft, BoundRight>> rightBinder) {
+ public <BoundRight> Pair<NewLeft, BoundRight>
+ bindRight(final Function<NewRight, Pair<NewLeft, BoundRight>> rightBinder) {
if (rightBinder == null)
throw new NullPointerException("Right binder must not be null");
final Supplier<NewRight> rightSupp = () -> {
- IPair<NewLeft, NewRight> newPair = boundPair;
+ Pair<NewLeft, NewRight> newPair = boundPair;
if (!pairBound) {
/*
@@ -136,8 +136,8 @@ public class BoundLazyPair<OldLeft, OldRight, NewLeft, NewRight>
@Override
public <OtherLeft, OtherRight, CombinedLeft, CombinedRight>
- IPair<CombinedLeft, CombinedRight>
- combine(final IPair<OtherLeft, OtherRight> otherPair,
+ Pair<CombinedLeft, CombinedRight>
+ combine(final Pair<OtherLeft, OtherRight> otherPair,
final BiFunction<NewLeft, OtherLeft, CombinedLeft> leftCombiner,
final BiFunction<NewRight, OtherRight, CombinedRight> rightCombiner) {
if (otherPair == null) {
@@ -157,7 +157,7 @@ public class BoundLazyPair<OldLeft, OldRight, NewLeft, NewRight>
}
@Override
- public <NewLeftType> IPair<NewLeftType, NewRight>
+ public <NewLeftType> Pair<NewLeftType, NewRight>
mapLeft(final Function<NewLeft, NewLeftType> mapper) {
if (mapper == null)
throw new NullPointerException("Mapper must not be null");
@@ -184,7 +184,7 @@ public class BoundLazyPair<OldLeft, OldRight, NewLeft, NewRight>
}
@Override
- public <NewRightType> IPair<NewLeft, NewRightType>
+ public <NewRightType> Pair<NewLeft, NewRightType>
mapRight(final Function<NewRight, NewRightType> mapper) {
if (mapper == null)
throw new NullPointerException("Mapper must not be null");
diff --git a/src/main/java/bjc/data/internals/BoundListHolder.java b/src/main/java/bjc/data/internals/BoundListHolder.java
index 1193c8d..c944252 100644
--- a/src/main/java/bjc/data/internals/BoundListHolder.java
+++ b/src/main/java/bjc/data/internals/BoundListHolder.java
@@ -3,9 +3,9 @@ package bjc.data.internals;
import java.util.function.Function;
import java.util.function.UnaryOperator;
-import bjc.data.IHolder;
+import bjc.data.Holder;
import bjc.data.ListHolder;
-import bjc.funcdata.IList;
+import bjc.funcdata.ListEx;
/**
* Holds a list, converted into a holder.
@@ -13,9 +13,9 @@ import bjc.funcdata.IList;
* @author Ben Culkin
*/
@SuppressWarnings("javadoc")
-public class BoundListHolder<ContainedType> implements IHolder<ContainedType> {
+public class BoundListHolder<ContainedType> implements Holder<ContainedType> {
/* The list of contained holders. */
- private final IList<IHolder<ContainedType>> heldHolders;
+ private final ListEx<Holder<ContainedType>> heldHolders;
/**
* Create a new list of holders.
@@ -23,17 +23,17 @@ public class BoundListHolder<ContainedType> implements IHolder<ContainedType> {
* @param toHold
* The list of holders to, well, hold.
*/
- public BoundListHolder(final IList<IHolder<ContainedType>> toHold) {
+ public BoundListHolder(final ListEx<Holder<ContainedType>> toHold) {
heldHolders = toHold;
}
@Override
- public <BoundType> IHolder<BoundType>
- bind(final Function<ContainedType, IHolder<BoundType>> binder) {
+ public <BoundType> Holder<BoundType>
+ bind(final Function<ContainedType, Holder<BoundType>> binder) {
if (binder == null)
throw new NullPointerException("Binder must not be null");
- final IList<IHolder<BoundType>> boundHolders
+ final ListEx<Holder<BoundType>> boundHolders
= heldHolders.map(containedHolder -> {
return containedHolder.bind(binder);
});
@@ -42,7 +42,7 @@ public class BoundListHolder<ContainedType> implements IHolder<ContainedType> {
}
@Override
- public <NewType> Function<ContainedType, IHolder<NewType>>
+ public <NewType> Function<ContainedType, Holder<NewType>>
lift(final Function<ContainedType, NewType> func) {
if (func == null)
throw new NullPointerException("Function to lift must not be null");
@@ -53,12 +53,12 @@ public class BoundListHolder<ContainedType> implements IHolder<ContainedType> {
}
@Override
- public <MappedType> IHolder<MappedType>
+ public <MappedType> Holder<MappedType>
map(final Function<ContainedType, MappedType> mapper) {
if (mapper == null)
throw new NullPointerException("Mapper must not be null");
- final IList<IHolder<MappedType>> mappedHolders
+ final ListEx<Holder<MappedType>> mappedHolders
= heldHolders.map(containedHolder -> {
return containedHolder.map(mapper);
});
@@ -67,7 +67,7 @@ public class BoundListHolder<ContainedType> implements IHolder<ContainedType> {
}
@Override
- public IHolder<ContainedType>
+ public Holder<ContainedType>
transform(final UnaryOperator<ContainedType> transformer) {
if (transformer == null)
throw new NullPointerException("Transformer must not be null");
diff --git a/src/main/java/bjc/data/internals/HalfBoundLazyPair.java b/src/main/java/bjc/data/internals/HalfBoundLazyPair.java
index 6bcb6ae..849b973 100644
--- a/src/main/java/bjc/data/internals/HalfBoundLazyPair.java
+++ b/src/main/java/bjc/data/internals/HalfBoundLazyPair.java
@@ -4,8 +4,8 @@ import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
-import bjc.data.IHolder;
-import bjc.data.IPair;
+import bjc.data.Holder;
+import bjc.data.Pair;
import bjc.data.Identity;
import bjc.data.LazyPair;
@@ -24,15 +24,15 @@ import bjc.data.LazyPair;
*/
@SuppressWarnings("javadoc")
public class HalfBoundLazyPair<OldType, NewLeft, NewRight>
- implements IPair<NewLeft, NewRight> {
+ implements Pair<NewLeft, NewRight> {
/* The supplier of the old value. */
private final Supplier<OldType> oldSupplier;
/* The function to transform the old value into a new pair. */
- private final Function<OldType, IPair<NewLeft, NewRight>> binder;
+ private final Function<OldType, Pair<NewLeft, NewRight>> binder;
/* The new bound pair. */
- private IPair<NewLeft, NewRight> boundPair;
+ private Pair<NewLeft, NewRight> boundPair;
/* Has the pair been bound yet or not? */
private boolean pairBound;
@@ -46,16 +46,16 @@ public class HalfBoundLazyPair<OldType, NewLeft, NewRight>
* The function to use to create the pair from the old value.
*/
public HalfBoundLazyPair(final Supplier<OldType> oldSupp,
- final Function<OldType, IPair<NewLeft, NewRight>> bindr) {
+ final Function<OldType, Pair<NewLeft, NewRight>> bindr) {
oldSupplier = oldSupp;
binder = bindr;
}
@Override
- public <BoundLeft, BoundRight> IPair<BoundLeft, BoundRight> bind(
- final BiFunction<NewLeft, NewRight, IPair<BoundLeft, BoundRight>> bindr) {
- final IHolder<IPair<NewLeft, NewRight>> newPair = new Identity<>(boundPair);
- final IHolder<Boolean> newPairMade = new Identity<>(pairBound);
+ public <BoundLeft, BoundRight> Pair<BoundLeft, BoundRight> bind(
+ final BiFunction<NewLeft, NewRight, Pair<BoundLeft, BoundRight>> bindr) {
+ final Holder<Pair<NewLeft, NewRight>> newPair = new Identity<>(boundPair);
+ final Holder<Boolean> newPairMade = new Identity<>(pairBound);
final Supplier<NewLeft> leftSupp = () -> {
if (!newPairMade.getValue()) {
@@ -81,10 +81,10 @@ public class HalfBoundLazyPair<OldType, NewLeft, NewRight>
}
@Override
- public <BoundLeft> IPair<BoundLeft, NewRight>
- bindLeft(final Function<NewLeft, IPair<BoundLeft, NewRight>> leftBinder) {
+ public <BoundLeft> Pair<BoundLeft, NewRight>
+ bindLeft(final Function<NewLeft, Pair<BoundLeft, NewRight>> leftBinder) {
final Supplier<NewLeft> leftSupp = () -> {
- IPair<NewLeft, NewRight> newPair = boundPair;
+ Pair<NewLeft, NewRight> newPair = boundPair;
if (!pairBound) {
newPair = binder.apply(oldSupplier.get());
@@ -97,10 +97,10 @@ public class HalfBoundLazyPair<OldType, NewLeft, NewRight>
}
@Override
- public <BoundRight> IPair<NewLeft, BoundRight>
- bindRight(final Function<NewRight, IPair<NewLeft, BoundRight>> rightBinder) {
+ public <BoundRight> Pair<NewLeft, BoundRight>
+ bindRight(final Function<NewRight, Pair<NewLeft, BoundRight>> rightBinder) {
final Supplier<NewRight> rightSupp = () -> {
- IPair<NewLeft, NewRight> newPair = boundPair;
+ Pair<NewLeft, NewRight> newPair = boundPair;
if (!pairBound) {
newPair = binder.apply(oldSupplier.get());
@@ -114,8 +114,8 @@ public class HalfBoundLazyPair<OldType, NewLeft, NewRight>
@Override
public <OtherLeft, OtherRight, CombinedLeft, CombinedRight>
- IPair<CombinedLeft, CombinedRight>
- combine(final IPair<OtherLeft, OtherRight> otherPair,
+ Pair<CombinedLeft, CombinedRight>
+ combine(final Pair<OtherLeft, OtherRight> otherPair,
final BiFunction<NewLeft, OtherLeft, CombinedLeft> leftCombiner,
final BiFunction<NewRight, OtherRight, CombinedRight> rightCombiner) {
return otherPair.bind((otherLeft, otherRight) -> bind((leftVal, rightVal) -> {
@@ -127,7 +127,7 @@ public class HalfBoundLazyPair<OldType, NewLeft, NewRight>
}
@Override
- public <NewLeftType> IPair<NewLeftType, NewRight>
+ public <NewLeftType> Pair<NewLeftType, NewRight>
mapLeft(final Function<NewLeft, NewLeftType> mapper) {
final Supplier<NewLeftType> leftSupp = () -> {
if (pairBound)
@@ -149,7 +149,7 @@ public class HalfBoundLazyPair<OldType, NewLeft, NewRight>
}
@Override
- public <NewRightType> IPair<NewLeft, NewRightType>
+ public <NewRightType> Pair<NewLeft, NewRightType>
mapRight(final Function<NewRight, NewRightType> mapper) {
final Supplier<NewLeft> leftSupp = () -> {
if (pairBound)
diff --git a/src/main/java/bjc/data/internals/WrappedLazy.java b/src/main/java/bjc/data/internals/WrappedLazy.java
index cda86fd..624fb1b 100644
--- a/src/main/java/bjc/data/internals/WrappedLazy.java
+++ b/src/main/java/bjc/data/internals/WrappedLazy.java
@@ -3,7 +3,7 @@ package bjc.data.internals;
import java.util.function.Function;
import java.util.function.UnaryOperator;
-import bjc.data.IHolder;
+import bjc.data.Holder;
import bjc.data.Lazy;
/**
@@ -13,9 +13,9 @@ import bjc.data.Lazy;
* @param <ContainedType>
* The type of the wrapped value.
*/
-public class WrappedLazy<ContainedType> implements IHolder<ContainedType> {
+public class WrappedLazy<ContainedType> implements Holder<ContainedType> {
/* Held value. */
- private final IHolder<IHolder<ContainedType>> held;
+ private final Holder<Holder<ContainedType>> held;
/**
* Create a new wrapped lazy value.
@@ -23,7 +23,7 @@ public class WrappedLazy<ContainedType> implements IHolder<ContainedType> {
* @param wrappedHolder
* The holder to make lazy.
*/
- public WrappedLazy(final IHolder<ContainedType> wrappedHolder) {
+ public WrappedLazy(final Holder<ContainedType> wrappedHolder) {
held = new Lazy<>(wrappedHolder);
}
@@ -34,15 +34,15 @@ public class WrappedLazy<ContainedType> implements IHolder<ContainedType> {
* This is a case where reified generics would be useful, because then the
* compiler could know which one we meant without the dummy parameter.
*/
- private WrappedLazy(final IHolder<IHolder<ContainedType>> wrappedHolder,
+ private WrappedLazy(final Holder<Holder<ContainedType>> wrappedHolder,
@SuppressWarnings("unused") final boolean dummy) {
held = wrappedHolder;
}
@Override
- public <BoundType> IHolder<BoundType>
- bind(final Function<ContainedType, IHolder<BoundType>> binder) {
- final IHolder<IHolder<BoundType>> newHolder = held.map(containedHolder -> {
+ public <BoundType> Holder<BoundType>
+ bind(final Function<ContainedType, Holder<BoundType>> binder) {
+ final Holder<Holder<BoundType>> newHolder = held.map(containedHolder -> {
return containedHolder.bind(binder);
});
@@ -50,7 +50,7 @@ public class WrappedLazy<ContainedType> implements IHolder<ContainedType> {
}
@Override
- public <NewType> Function<ContainedType, IHolder<NewType>>
+ public <NewType> Function<ContainedType, Holder<NewType>>
lift(final Function<ContainedType, NewType> func) {
return val -> {
return new Lazy<>(func.apply(val));
@@ -58,9 +58,9 @@ public class WrappedLazy<ContainedType> implements IHolder<ContainedType> {
}
@Override
- public <MappedType> IHolder<MappedType>
+ public <MappedType> Holder<MappedType>
map(final Function<ContainedType, MappedType> mapper) {
- final IHolder<IHolder<MappedType>> newHolder = held.map(containedHolder -> {
+ final Holder<Holder<MappedType>> newHolder = held.map(containedHolder -> {
return containedHolder.map(mapper);
});
@@ -68,7 +68,7 @@ public class WrappedLazy<ContainedType> implements IHolder<ContainedType> {
}
@Override
- public IHolder<ContainedType>
+ public Holder<ContainedType>
transform(final UnaryOperator<ContainedType> transformer) {
held.transform(containedHolder -> {
return containedHolder.transform(transformer);
diff --git a/src/main/java/bjc/data/internals/WrappedOption.java b/src/main/java/bjc/data/internals/WrappedOption.java
index 6becc16..f46d501 100644
--- a/src/main/java/bjc/data/internals/WrappedOption.java
+++ b/src/main/java/bjc/data/internals/WrappedOption.java
@@ -3,7 +3,7 @@ package bjc.data.internals;
import java.util.function.Function;
import java.util.function.UnaryOperator;
-import bjc.data.IHolder;
+import bjc.data.Holder;
import bjc.data.Option;
/**
@@ -13,9 +13,9 @@ import bjc.data.Option;
* @param <ContainedType>
* The wrapped type.
*/
-public class WrappedOption<ContainedType> implements IHolder<ContainedType> {
+public class WrappedOption<ContainedType> implements Holder<ContainedType> {
/* The held value. */
- private final IHolder<IHolder<ContainedType>> held;
+ private final Holder<Holder<ContainedType>> held;
/**
* Create a new wrapped option.
@@ -23,7 +23,7 @@ public class WrappedOption<ContainedType> implements IHolder<ContainedType> {
* @param seedValue
* The value to wrap.
*/
- public WrappedOption(final IHolder<ContainedType> seedValue) {
+ public WrappedOption(final Holder<ContainedType> seedValue) {
held = new Option<>(seedValue);
}
@@ -31,15 +31,15 @@ public class WrappedOption<ContainedType> implements IHolder<ContainedType> {
* The dummy parameter is to ensure the compiler can pick the right method,
* because without this method erases to the same type as the public one.
*/
- private WrappedOption(final IHolder<IHolder<ContainedType>> toHold,
+ private WrappedOption(final Holder<Holder<ContainedType>> toHold,
@SuppressWarnings("unused") final boolean dummy) {
held = toHold;
}
@Override
- public <BoundType> IHolder<BoundType>
- bind(final Function<ContainedType, IHolder<BoundType>> binder) {
- final IHolder<IHolder<BoundType>> newHolder = held.map(containedHolder -> {
+ public <BoundType> Holder<BoundType>
+ bind(final Function<ContainedType, Holder<BoundType>> binder) {
+ final Holder<Holder<BoundType>> newHolder = held.map(containedHolder -> {
return containedHolder.bind((containedValue) -> {
if (containedValue == null)
return new Option<>(null);
@@ -52,7 +52,7 @@ public class WrappedOption<ContainedType> implements IHolder<ContainedType> {
}
@Override
- public <NewType> Function<ContainedType, IHolder<NewType>>
+ public <NewType> Function<ContainedType, Holder<NewType>>
lift(final Function<ContainedType, NewType> func) {
return val -> {
return new Option<>(func.apply(val));
@@ -60,9 +60,9 @@ public class WrappedOption<ContainedType> implements IHolder<ContainedType> {
}
@Override
- public <MappedType> IHolder<MappedType>
+ public <MappedType> Holder<MappedType>
map(final Function<ContainedType, MappedType> mapper) {
- final IHolder<IHolder<MappedType>> newHolder = held.map(containedHolder -> {
+ final Holder<Holder<MappedType>> newHolder = held.map(containedHolder -> {
return containedHolder.map((containedValue) -> {
if (containedValue == null)
return null;
@@ -75,7 +75,7 @@ public class WrappedOption<ContainedType> implements IHolder<ContainedType> {
}
@Override
- public IHolder<ContainedType>
+ public Holder<ContainedType>
transform(final UnaryOperator<ContainedType> transformer) {
held.transform(containedHolder -> {
return containedHolder.transform((containedValue) -> {