summaryrefslogtreecommitdiff
path: root/BJC-Utils2/src/main
diff options
context:
space:
mode:
authorbculkin2442 <bjculkin@mix.wvu.edu>2016-05-07 12:51:23 -0400
committerbculkin2442 <bjculkin@mix.wvu.edu>2016-05-07 12:51:23 -0400
commit87ae1dfc8d8cb7b51d7bda4750ce841bbe691cfc (patch)
tree290f31282898bd39300c70646c6fe2b65832886a /BJC-Utils2/src/main
parentfb7d03388e298258563c22abda1bd46cdaf991b7 (diff)
General changes
Diffstat (limited to 'BJC-Utils2/src/main')
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommandMode.java8
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/components/FileComponentRepository.java4
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/configuration/ConfigFile.java162
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/configuration/Configuration.java26
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/configuration/Configurator.java44
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/configuration/FieldMarker.java25
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/configuration/FieldType.java147
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/BoundLazy.java8
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/BoundLazyPair.java60
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/BoundListHolder.java61
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/HalfBoundLazyPair.java52
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/IHolder.java82
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/IPair.java72
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/Identity.java8
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/Lazy.java9
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/LazyPair.java48
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/ListHolder.java79
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/Option.java74
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/Pair.java16
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/WrappedLazy.java69
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/data/WrappedOption.java89
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalList.java10
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/PushdownMap.java91
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/theory/Bifunctor.java66
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/theory/Functor.java39
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/theory/package-info.java7
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcutils/StringUtils.java10
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/gui/HolderOutputPanel.java27
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/parserutils/StackBasedConfigReader.java37
29 files changed, 989 insertions, 441 deletions
diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommandMode.java b/BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommandMode.java
index a9c9054..0007616 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommandMode.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommandMode.java
@@ -82,11 +82,11 @@ public class GenericCommandMode implements ICommandMode {
} else {
ICommand aliasedCommand;
if (defaultHandlers.containsKey(commandName)) {
- aliasedCommand =
- defaultHandlers.get(commandName).createAlias();
+ aliasedCommand = defaultHandlers.get(commandName)
+ .createAlias();
} else {
- aliasedCommand =
- commandHandlers.get(commandName).createAlias();
+ aliasedCommand = commandHandlers.get(commandName)
+ .createAlias();
}
commandHandlers.put(aliasName, aliasedCommand);
diff --git a/BJC-Utils2/src/main/java/bjc/utils/components/FileComponentRepository.java b/BJC-Utils2/src/main/java/bjc/utils/components/FileComponentRepository.java
index bc1b990..e05afc0 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/components/FileComponentRepository.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/components/FileComponentRepository.java
@@ -57,7 +57,7 @@ public class FileComponentRepository<E extends IDescribedComponent>
* The function to use to convert files to components
*/
public FileComponentRepository(File directory,
- Function<File, E> componentReader) {
+ Function<File, ? extends E> componentReader) {
if (!directory.isDirectory()) {
throw new IllegalArgumentException("File " + directory
+ " is not a directory.\n"
@@ -123,7 +123,7 @@ public class FileComponentRepository<E extends IDescribedComponent>
return "Components read from directory " + sourceDirectory + ".";
}
- private void loadComponent(Function<File, E> componentReader,
+ private void loadComponent(Function<File, ? extends E> componentReader,
Path pth) {
try {
E component = componentReader.apply(pth.toFile());
diff --git a/BJC-Utils2/src/main/java/bjc/utils/configuration/ConfigFile.java b/BJC-Utils2/src/main/java/bjc/utils/configuration/ConfigFile.java
deleted file mode 100644
index aa436ee..0000000
--- a/BJC-Utils2/src/main/java/bjc/utils/configuration/ConfigFile.java
+++ /dev/null
@@ -1,162 +0,0 @@
-package bjc.utils.configuration;
-
-import java.io.InputStream;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Scanner;
-
-import javax.lang.model.SourceVersion;
-
-/**
- * A config file with support for categories, comments and other thins
- *
- * @author ben
- *
- */
-public class ConfigFile {
- /**
- * A category in a configuration file
- *
- * @author ben
- *
- */
- public static class ConfigCategory {
- private Map<String, ConfigCategory> children;
-
- /**
- * Create a new config category
- */
- public ConfigCategory() {
- children = new HashMap<>();
- }
-
- /**
- * Add a child category to this category
- *
- * @param childName
- * The name of the child
- * @param child
- * The child category
- */
- public void addChild(String childName, ConfigCategory child) {
- children.put(childName, child);
- }
- }
-
- private static Map<String, ConfigCategory> topLevelCategories;
-
- private static boolean isCommentMarker(String token) {
- switch (token) {
- case "#":
- case "//":
- return true;
- default:
- return false;
- }
- }
-
- /**
- * Parse the values in a config file from a stream
- *
- * @param source
- * The stream to parse values from
- * @return A config file with values parsed from the stream
- */
- public static ConfigFile parse(InputStream source) {
- Scanner scn = new Scanner(source);
-
- ConfigFile returnedFile = new ConfigFile();
-
- while (scn.hasNextLine()) {
- String currentLine = scn.nextLine();
-
- // Ignore blank lines
- if (currentLine.equals("")) {
- continue;
- }
-
- String[] currentTokens = currentLine.split(" ");
-
- // Ignore lines that start with a comment marker
- if (isCommentMarker(currentTokens[0])) {
- continue;
- } else if (SourceVersion.isName(currentTokens[0])
- && currentTokens[1].equals("{")) {
- topLevelCategories.put(currentTokens[0],
- parseCategory(currentTokens[0], scn));
- }
- }
-
- scn.close();
-
- return returnedFile;
- }
-
- private static ConfigCategory parseCategory(
- @SuppressWarnings("unused") String categoryName,
- Scanner inputSource) {
- ConfigCategory category = new ConfigCategory();
-
- String currentLine = inputSource.nextLine();
-
- String[] tokens = currentLine.split("\\s+ ");
-
- // Parse contents of category
- while (!tokens[0].equals("}")) {
- // Ignore lines starting with comment marker
- if (isCommentMarker(tokens[0])) {
- continue;
- }
-
- int initialCommandToken = 0;
-
- // Skip over blank tokens from lots of spacing
- for (int i = 0; i < tokens.length; i++) {
- String token = tokens[i];
-
- if (token.equals("")) {
- continue;
- } else {
- initialCommandToken = i;
- break;
- }
- }
-
- String[] relevantTokens = Arrays.copyOfRange(tokens,
- initialCommandToken, tokens.length);
-
- // Parse child subcategories
- if (SourceVersion.isName(relevantTokens[0])
- && relevantTokens[1].equals("{")) {
- parseCategory(relevantTokens[0], inputSource);
- } else {
- // Parse config fields
- parseEntry(category, relevantTokens);
- }
- currentLine = inputSource.nextLine();
-
- tokens = currentLine.split("\\s+ ");
- }
-
- return category;
- }
-
- private static void parseEntry(
- @SuppressWarnings("unused") ConfigCategory category,
- String[] entryParts) {
- String entry = String.join("", entryParts);
-
- String[] expParts = entry.split("=");
-
- String[] expSpecifiers = expParts[0].split(":");
-
- String expType = expSpecifiers[0];
- @SuppressWarnings("unused")
- String expName = expSpecifiers[1];
-
- switch (expType) {
-
- }
- }
-}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/configuration/Configuration.java b/BJC-Utils2/src/main/java/bjc/utils/configuration/Configuration.java
deleted file mode 100644
index 7944c44..0000000
--- a/BJC-Utils2/src/main/java/bjc/utils/configuration/Configuration.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package bjc.utils.configuration;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Annotation that marks a class as having a config file bound to it
- *
- * For this annotation to be valid to apply to the class, the class must
- * meet two qualities
- *
- * 1. Have a public no-args constructor
- *
- * 2. Have one or more fields annoted with a {@link FieldMarker} annotation
- *
- * @author ben
- *
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
-@Documented
-public @interface Configuration {
-} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/configuration/Configurator.java b/BJC-Utils2/src/main/java/bjc/utils/configuration/Configurator.java
deleted file mode 100644
index e116dea..0000000
--- a/BJC-Utils2/src/main/java/bjc/utils/configuration/Configurator.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package bjc.utils.configuration;
-
-import java.io.InputStream;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-
-/**
- * Bind the values in a prepared class to a config file
- *
- * @author ben
- *
- */
-public class Configurator {
- /**
- * Bind the values in a config file to the values in a class,
- * substituting default values if none are appropriate
- *
- * @param <E>
- * The type of the object to bind
- * @param clasz
- * The class of the object to bind
- * @param inputSource
- * The source to get input from
- * @return A instance of the provided class, with values filled in from
- * a config file
- */
- public static <E> E readConfig(Class<E> clasz,
- InputStream inputSource) {
- try {
- Constructor<E> noArgConstructor = clasz.getConstructor();
-
- E backingStore = noArgConstructor.newInstance();
-
- return backingStore;
- } catch (NoSuchMethodException | SecurityException
- | InstantiationException | IllegalAccessException
- | IllegalArgumentException | InvocationTargetException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
-
- return null;
- }
- }
-}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/configuration/FieldMarker.java b/BJC-Utils2/src/main/java/bjc/utils/configuration/FieldMarker.java
deleted file mode 100644
index 1d59fa3..0000000
--- a/BJC-Utils2/src/main/java/bjc/utils/configuration/FieldMarker.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package bjc.utils.configuration;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Annotation to bind a field to a field in a config file
- *
- * @author ben
- *
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.FIELD)
-@Documented
-public @interface FieldMarker {
- /**
- * The type of config field being represented
- *
- * @return The type of config field being represented
- */
- public FieldType value();
-}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/configuration/FieldType.java b/BJC-Utils2/src/main/java/bjc/utils/configuration/FieldType.java
deleted file mode 100644
index a1545e5..0000000
--- a/BJC-Utils2/src/main/java/bjc/utils/configuration/FieldType.java
+++ /dev/null
@@ -1,147 +0,0 @@
-package bjc.utils.configuration;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Container interface for field type markers
- *
- * There can't be a String field type, so for fields of a single string,
- * use FieldType itself
- *
- * @author ben
- *
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.FIELD)
-@Documented
-public @interface FieldType {
- /**
- * Marker to indicate a field as a single boolean flag
- *
- * @author Benjamin
- *
- */
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.FIELD)
- public @interface Flag {
- /**
- * The default value of the flag
- *
- * @return The default value of the flag
- */
- boolean value() default false;
- }
-
- /**
- * Marker to indicate a fields as an array of boolean flags
- *
- * @author Benjamin
- *
- */
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.FIELD)
- public @interface Flags {
- /**
- * The default value of the flags
- *
- * @return The default value of the flags
- */
- boolean[] value() default { false };
- }
-
- /**
- * Marker to indicate a field as a single floating point value
- *
- * @author Benjamin
- *
- */
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.FIELD)
- public @interface Float {
- /**
- * The default value of the number
- *
- * @return The default value of the number
- */
- double value() default 0.0;
- }
-
- /**
- * Marker to indicate a fields as an array of floating point values
- *
- * @author Benjamin
- *
- */
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.FIELD)
- public @interface Floats {
- /**
- * The default value of the numbers
- *
- * @return The default value of the numbers
- */
- double[] value() default { 0.0 };
- }
-
- /**
- * Marker to indicate a field as a single integral value
- *
- * @author Benjamin
- *
- */
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.FIELD)
- public @interface Integer {
- /**
- * The default value of the integer
- *
- * @return The default value of the integer
- */
- int value() default 0;
- }
-
- /**
- * Marker to indicate a fields as an array of integral values
- *
- * @author Benjamin
- *
- */
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.FIELD)
- public @interface Integers {
- /**
- * The default value of the integers
- *
- * @return The default value of the integers
- */
- int[] value() default { 0 };
- }
-
- /**
- * Marker to indicate a fields as an array of strings
- *
- * @author Benjamin
- *
- */
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.FIELD)
- public @interface Strings {
- /**
- * The default value of each of the strings
- *
- * @return The default value of each of the strings
- */
- String[] value() default { "" };
- }
-
- /**
- * The default value of the string
- *
- * @return The default value of the strings
- */
- public String value() default "";
-}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/BoundLazy.java b/BJC-Utils2/src/main/java/bjc/utils/data/BoundLazy.java
index ce47eb9..9ab3c05 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/data/BoundLazy.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/BoundLazy.java
@@ -96,4 +96,12 @@ class BoundLazy<OldType, BoundContainedType>
return boundHolder.unwrap(unwrapper);
}
+
+ @Override
+ public <NewType> Function<BoundContainedType, IHolder<NewType>> lift(
+ Function<BoundContainedType, NewType> func) {
+ return (val) -> {
+ return new Lazy<>(func.apply(val));
+ };
+ }
} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/BoundLazyPair.java b/BJC-Utils2/src/main/java/bjc/utils/data/BoundLazyPair.java
index a49bb9a..1635e06 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/data/BoundLazyPair.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/BoundLazyPair.java
@@ -90,8 +90,8 @@ class BoundLazyPair<OldLeft, OldRight, NewLeft, NewRight>
}
@Override
- public <MergedType> MergedType merge(
- BiFunction<NewLeft, NewRight, MergedType> merger) {
+ public <MergedType> MergedType
+ merge(BiFunction<NewLeft, NewRight, MergedType> merger) {
if (!pairBound) {
boundPair = binder.apply(leftSupplier.get(),
rightSupplier.get());
@@ -110,4 +110,60 @@ class BoundLazyPair<OldLeft, OldRight, NewLeft, NewRight>
return "(un-materialized)";
}
+
+ @Override
+ public <NewLeftType> IPair<NewLeftType, NewRight>
+ mapLeft(Function<NewLeft, NewLeftType> mapper) {
+ Supplier<NewLeftType> leftSupp = () -> {
+ if (!pairBound) {
+ NewLeft leftVal = binder
+ .apply(leftSupplier.get(), rightSupplier.get())
+ .getLeft();
+
+ return mapper.apply(leftVal);
+ }
+
+ return mapper.apply(boundPair.getLeft());
+ };
+
+ Supplier<NewRight> rightSupp = () -> {
+ if (!pairBound) {
+ return binder
+ .apply(leftSupplier.get(), rightSupplier.get())
+ .getRight();
+ }
+
+ return boundPair.getRight();
+ };
+
+ return new LazyPair<>(leftSupp, rightSupp);
+ }
+
+ @Override
+ public <NewRightType> IPair<NewLeft, NewRightType>
+ mapRight(Function<NewRight, NewRightType> mapper) {
+ Supplier<NewLeft> leftSupp = () -> {
+ if (!pairBound) {
+ return binder
+ .apply(leftSupplier.get(), rightSupplier.get())
+ .getLeft();
+ }
+
+ return boundPair.getLeft();
+ };
+
+ Supplier<NewRightType> rightSupp = () -> {
+ if (!pairBound) {
+ NewRight rightVal = binder
+ .apply(leftSupplier.get(), rightSupplier.get())
+ .getRight();
+
+ return mapper.apply(rightVal);
+ }
+
+ return mapper.apply(boundPair.getRight());
+ };
+
+ return new LazyPair<>(leftSupp, rightSupp);
+ }
} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/BoundListHolder.java b/BJC-Utils2/src/main/java/bjc/utils/data/BoundListHolder.java
new file mode 100644
index 0000000..fcb62f6
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/BoundListHolder.java
@@ -0,0 +1,61 @@
+package bjc.utils.data;
+
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+
+import bjc.utils.funcdata.IFunctionalList;
+
+class BoundListHolder<ContainedType> implements IHolder<ContainedType> {
+ private IFunctionalList<IHolder<ContainedType>> heldHolders;
+
+ public BoundListHolder(
+ IFunctionalList<IHolder<ContainedType>> toHold) {
+ heldHolders = toHold;
+ }
+
+ @Override
+ public <BoundType> IHolder<BoundType> bind(
+ Function<ContainedType, IHolder<BoundType>> binder) {
+ IFunctionalList<IHolder<BoundType>> boundHolders = heldHolders
+ .map((containedHolder) -> {
+ return containedHolder.bind(binder);
+ });
+
+ return new BoundListHolder<>(boundHolders);
+ }
+
+ @Override
+ public <MappedType> IHolder<MappedType> map(
+ Function<ContainedType, MappedType> mapper) {
+ IFunctionalList<IHolder<MappedType>> mappedHolders = heldHolders
+ .map((containedHolder) -> {
+ return containedHolder.map(mapper);
+ });
+
+ return new BoundListHolder<>(mappedHolders);
+ }
+
+ @Override
+ public IHolder<ContainedType> transform(
+ UnaryOperator<ContainedType> transformer) {
+ heldHolders.forEach((containedHolder) -> {
+ containedHolder.transform(transformer);
+ });
+
+ return this;
+ }
+
+ @Override
+ public <UnwrappedType> UnwrappedType unwrap(
+ Function<ContainedType, UnwrappedType> unwrapper) {
+ return heldHolders.randItem().unwrap(unwrapper);
+ }
+
+ @Override
+ public <NewType> Function<ContainedType, IHolder<NewType>> lift(
+ Function<ContainedType, NewType> func) {
+ return (val) -> {
+ return new ListHolder<>(func.apply(val));
+ };
+ }
+}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/HalfBoundLazyPair.java b/BJC-Utils2/src/main/java/bjc/utils/data/HalfBoundLazyPair.java
index 037dddf..9e26924 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/data/HalfBoundLazyPair.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/HalfBoundLazyPair.java
@@ -80,8 +80,8 @@ class HalfBoundLazyPair<OldType, NewLeft, NewRight>
}
@Override
- public <MergedType> MergedType merge(
- BiFunction<NewLeft, NewRight, MergedType> merger) {
+ public <MergedType> MergedType
+ merge(BiFunction<NewLeft, NewRight, MergedType> merger) {
if (!pairBound) {
boundPair = binder.apply(oldSupplier.get());
@@ -90,4 +90,52 @@ class HalfBoundLazyPair<OldType, NewLeft, NewRight>
return boundPair.merge(merger);
}
+
+ @Override
+ public <NewLeftType> IPair<NewLeftType, NewRight>
+ mapLeft(Function<NewLeft, NewLeftType> mapper) {
+ Supplier<NewLeftType> leftSupp = () -> {
+ if (pairBound) {
+ return mapper.apply(boundPair.getLeft());
+ }
+
+ NewLeft leftVal = binder.apply(oldSupplier.get()).getLeft();
+
+ return mapper.apply(leftVal);
+ };
+
+ Supplier<NewRight> rightSupp = () -> {
+ if (pairBound) {
+ return boundPair.getRight();
+ }
+
+ return binder.apply(oldSupplier.get()).getRight();
+ };
+
+ return new LazyPair<>(leftSupp, rightSupp);
+ }
+
+ @Override
+ public <NewRightType> IPair<NewLeft, NewRightType>
+ mapRight(Function<NewRight, NewRightType> mapper) {
+ Supplier<NewLeft> leftSupp = () -> {
+ if (pairBound) {
+ return boundPair.getLeft();
+ }
+
+ return binder.apply(oldSupplier.get()).getLeft();
+ };
+
+ Supplier<NewRightType> rightSupp = () -> {
+ if (pairBound) {
+ return mapper.apply(boundPair.getRight());
+ }
+
+ NewRight rightVal = binder.apply(oldSupplier.get()).getRight();
+
+ return mapper.apply(rightVal);
+ };
+
+ return new LazyPair<>(leftSupp, rightSupp);
+ }
} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/IHolder.java b/BJC-Utils2/src/main/java/bjc/utils/data/IHolder.java
index ecf3f14..58ae5db 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/data/IHolder.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/IHolder.java
@@ -4,6 +4,9 @@ import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.UnaryOperator;
+import bjc.utils.funcdata.FunctionalList;
+import bjc.utils.funcdata.theory.Functor;
+
/**
* A holder of a single value.
*
@@ -12,7 +15,7 @@ import java.util.function.UnaryOperator;
* @param <ContainedType>
* The type of value held
*/
-public interface IHolder<ContainedType> {
+public interface IHolder<ContainedType> extends Functor<ContainedType> {
/**
* Bind a function across the value in this container
*
@@ -22,8 +25,8 @@ public interface IHolder<ContainedType> {
* The function to bind to the value
* @return A holder from binding the value
*/
- public <BoundType> IHolder<BoundType> bind(
- Function<ContainedType, IHolder<BoundType>> binder);
+ public <BoundType> IHolder<BoundType>
+ bind(Function<ContainedType, IHolder<BoundType>> binder);
/**
* Apply an action to the value
@@ -31,7 +34,7 @@ public interface IHolder<ContainedType> {
* @param action
* The action to apply to the value
*/
- public default void doWith(Consumer<ContainedType> action) {
+ public default void doWith(Consumer<? super ContainedType> action) {
transform((value) -> {
action.accept(value);
@@ -39,13 +42,64 @@ public interface IHolder<ContainedType> {
});
}
+ @Override
+ default <ArgType, ReturnType>
+ Function<Functor<ArgType>, Functor<ReturnType>>
+ fmap(Function<ArgType, ReturnType> func) {
+ return (argumentFunctor) -> {
+ if (!(argumentFunctor instanceof IHolder<?>)) {
+ throw new IllegalArgumentException(
+ "This functor only supports mapping over instances of IHolder");
+ }
+
+ IHolder<ArgType> holder = (IHolder<ArgType>) argumentFunctor;
+
+ return holder.map(func);
+ };
+ }
+
+ @Override
+ public default ContainedType getValue() {
+ return unwrap((value) -> value);
+ }
+
/**
- * Get the value contained in this holder without changing it.
+ * Lifts a function to bind over this holder
*
- * @return The value held in this holder
+ * @param <NewType>
+ * The type of the functions return
+ * @param func
+ * The function to lift over the holder
+ * @return The function lifted over the holder
*/
- public default ContainedType getValue() {
- return unwrap((value) -> value);
+ public <NewType> Function<ContainedType, IHolder<NewType>>
+ lift(Function<ContainedType, NewType> func);
+
+ /**
+ * Make this holder lazy
+ *
+ * @return A lazy version of this holder
+ */
+ public default IHolder<ContainedType> makeLazy() {
+ return new WrappedLazy<>(this);
+ }
+
+ /**
+ * Make this holder a list
+ *
+ * @return A list version of this holder
+ */
+ public default IHolder<ContainedType> makeList() {
+ return new BoundListHolder<>(new FunctionalList<>(this));
+ }
+
+ /**
+ * Make this holder optional
+ *
+ * @return An optional version of this holder
+ */
+ public default IHolder<ContainedType> makeOptional() {
+ return new WrappedOption<>(this);
}
/**
@@ -60,8 +114,8 @@ public interface IHolder<ContainedType> {
* The function to do mapping with
* @return A holder with the mapped value
*/
- public <MappedType> IHolder<MappedType> map(
- Function<ContainedType, MappedType> mapper);
+ public <MappedType> IHolder<MappedType>
+ map(Function<ContainedType, MappedType> mapper);
/**
* Replace the held value with a new one
@@ -83,8 +137,8 @@ public interface IHolder<ContainedType> {
* The function to transform the value with
* @return The holder itself, for easy chaining
*/
- public IHolder<ContainedType> transform(
- UnaryOperator<ContainedType> transformer);
+ public IHolder<ContainedType>
+ transform(UnaryOperator<ContainedType> transformer);
/**
* Unwrap the value contained in this holder so that it is no longer
@@ -96,6 +150,6 @@ public interface IHolder<ContainedType> {
* The function to use to unwrap the value
* @return The unwrapped held value
*/
- public <UnwrappedType> UnwrappedType unwrap(
- Function<ContainedType, UnwrappedType> unwrapper);
+ public <UnwrappedType> UnwrappedType
+ unwrap(Function<ContainedType, UnwrappedType> unwrapper);
}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/IPair.java b/BJC-Utils2/src/main/java/bjc/utils/data/IPair.java
index 316074e..707724b 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/data/IPair.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/IPair.java
@@ -4,6 +4,8 @@ import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
+import bjc.utils.funcdata.theory.Bifunctor;
+
/**
* Represents a pair of values
*
@@ -14,7 +16,8 @@ import java.util.function.Function;
* The type of the right side of the pair
*
*/
-public interface IPair<LeftType, RightType> {
+public interface IPair<LeftType, RightType>
+ extends Bifunctor<LeftType, RightType> {
/**
* Bind a function across the values in this pair
*
@@ -68,11 +71,45 @@ public interface IPair<LeftType, RightType> {
});
}
+ @Override
+ default <OldLeft, OldRight, NewLeft>
+ Function<Bifunctor<OldLeft, OldRight>, Bifunctor<NewLeft, OldRight>>
+ fmapLeft(Function<OldLeft, NewLeft> func) {
+ return (argumentPair) -> {
+ if (!(argumentPair instanceof IPair<?, ?>)) {
+ throw new IllegalArgumentException(
+ "This function can only be applied to instances of IPair");
+ }
+
+ IPair<OldLeft, OldRight> argPair = (IPair<OldLeft, OldRight>) argumentPair;
+
+ return argPair.mapLeft(func);
+ };
+ }
+
+ @Override
+ default <OldLeft, OldRight, NewRight>
+ Function<Bifunctor<OldLeft, OldRight>, Bifunctor<OldLeft, NewRight>>
+
+ fmapRight(Function<OldRight, NewRight> func) {
+ return (argumentPair) -> {
+ if (!(argumentPair instanceof IPair<?, ?>)) {
+ throw new IllegalArgumentException(
+ "This function can only be applied to instances of IPair");
+ }
+
+ 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);
}
@@ -82,11 +119,40 @@ public interface IPair<LeftType, RightType> {
*
* @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>
@@ -95,6 +161,6 @@ public interface IPair<LeftType, RightType> {
* The function to use for merging
* @return The pair, merged into a single value
*/
- public <MergedType> MergedType merge(
- BiFunction<LeftType, RightType, MergedType> merger);
+ public <MergedType> MergedType
+ merge(BiFunction<LeftType, RightType, MergedType> merger);
}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/Identity.java b/BJC-Utils2/src/main/java/bjc/utils/data/Identity.java
index dcc7bef..f42ceb7 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/data/Identity.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/Identity.java
@@ -112,4 +112,12 @@ public class Identity<ContainedType> implements IHolder<ContainedType> {
Function<ContainedType, UnwrappedType> unwrapper) {
return unwrapper.apply(heldValue);
}
+
+ @Override
+ public <NewType> Function<ContainedType, IHolder<NewType>> lift(
+ Function<ContainedType, NewType> func) {
+ return (val) -> {
+ return new Identity<>(func.apply(val));
+ };
+ }
} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/Lazy.java b/BJC-Utils2/src/main/java/bjc/utils/data/Lazy.java
index 061486e..62b0bb0 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/data/Lazy.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/Lazy.java
@@ -133,4 +133,13 @@ public class Lazy<ContainedType> implements IHolder<ContainedType> {
return unwrapper.apply(heldValue);
}
+
+ @Override
+ public <NewType> Function<ContainedType, IHolder<NewType>> lift(
+ Function<ContainedType, NewType> func) {
+ // TODO Auto-generated method stub
+ return (val) -> {
+ return new Lazy<>(func.apply(val));
+ };
+ }
}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/LazyPair.java b/BJC-Utils2/src/main/java/bjc/utils/data/LazyPair.java
index b02d9cb..6f1be10 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/data/LazyPair.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/LazyPair.java
@@ -115,8 +115,8 @@ public class LazyPair<LeftType, RightType>
}
@Override
- public <MergedType> MergedType merge(
- BiFunction<LeftType, RightType, MergedType> merger) {
+ public <MergedType> MergedType
+ merge(BiFunction<LeftType, RightType, MergedType> merger) {
if (!leftMaterialized) {
leftValue = leftSupplier.get();
@@ -154,4 +154,48 @@ public class LazyPair<LeftType, RightType>
return sb.toString();
}
+
+ @Override
+ public <NewLeft> IPair<NewLeft, RightType>
+ mapLeft(Function<LeftType, NewLeft> mapper) {
+ Supplier<NewLeft> leftSupp = () -> {
+ if (leftMaterialized) {
+ return mapper.apply(leftValue);
+ }
+
+ return mapper.apply(leftSupplier.get());
+ };
+
+ Supplier<RightType> rightSupp = () -> {
+ if (rightMaterialized) {
+ return rightValue;
+ }
+
+ return rightSupplier.get();
+ };
+
+ return new LazyPair<>(leftSupp, rightSupp);
+ }
+
+ @Override
+ public <NewRight> IPair<LeftType, NewRight>
+ mapRight(Function<RightType, NewRight> mapper) {
+ Supplier<LeftType> leftSupp = () -> {
+ if (leftMaterialized) {
+ return leftValue;
+ }
+
+ return leftSupplier.get();
+ };
+
+ Supplier<NewRight> rightSupp = () -> {
+ if (rightMaterialized) {
+ return mapper.apply(rightValue);
+ }
+
+ return mapper.apply(rightSupplier.get());
+ };
+
+ return new LazyPair<>(leftSupp, rightSupp);
+ }
}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/ListHolder.java b/BJC-Utils2/src/main/java/bjc/utils/data/ListHolder.java
new file mode 100644
index 0000000..8dc33d3
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/ListHolder.java
@@ -0,0 +1,79 @@
+package bjc.utils.data;
+
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+
+import bjc.utils.funcdata.FunctionalList;
+import bjc.utils.funcdata.IFunctionalList;
+
+/**
+ * A holder that represents a set of non-deterministic computations
+ *
+ * @author ben
+ *
+ * @param <ContainedType>
+ * The type of contained value
+ */
+public class ListHolder<ContainedType> implements IHolder<ContainedType> {
+ private IFunctionalList<ContainedType> heldValues;
+
+ private ListHolder(IFunctionalList<ContainedType> toHold) {
+ heldValues = toHold;
+ }
+
+ /**
+ * Create a new list holder
+ *
+ * @param values
+ * The possible values for the computation
+ */
+ @SafeVarargs
+ public ListHolder(ContainedType... values) {
+ heldValues = new FunctionalList<>();
+
+ if (values != null) {
+ for (ContainedType containedValue : values) {
+ heldValues.add(containedValue);
+ }
+ }
+ }
+
+ @Override
+ public <BoundType> IHolder<BoundType> bind(
+ Function<ContainedType, IHolder<BoundType>> binder) {
+ IFunctionalList<IHolder<BoundType>> boundValues = heldValues
+ .map(binder);
+
+ return new BoundListHolder<>(boundValues);
+ }
+
+ @Override
+ public <MappedType> IHolder<MappedType> map(
+ Function<ContainedType, MappedType> mapper) {
+ IFunctionalList<MappedType> mappedValues = heldValues.map(mapper);
+
+ return new ListHolder<>(mappedValues);
+ }
+
+ @Override
+ public IHolder<ContainedType> transform(
+ UnaryOperator<ContainedType> transformer) {
+ heldValues = heldValues.map(transformer);
+
+ return this;
+ }
+
+ @Override
+ public <UnwrappedType> UnwrappedType unwrap(
+ Function<ContainedType, UnwrappedType> unwrapper) {
+ return unwrapper.apply(heldValues.randItem());
+ }
+
+ @Override
+ public <NewType> Function<ContainedType, IHolder<NewType>> lift(
+ Function<ContainedType, NewType> func) {
+ return (val) -> {
+ return new ListHolder<>(new FunctionalList<>(func.apply(val)));
+ };
+ }
+}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/Option.java b/BJC-Utils2/src/main/java/bjc/utils/data/Option.java
new file mode 100644
index 0000000..9f6d448
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/Option.java
@@ -0,0 +1,74 @@
+package bjc.utils.data;
+
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+
+/**
+ * A holder that may or may not contain a value
+ *
+ * @author ben
+ *
+ * @param <ContainedType>
+ * The type of the value that may or may not be held
+ */
+public class Option<ContainedType> implements IHolder<ContainedType> {
+ private ContainedType held;
+
+ /**
+ * Create a new optional, using the given initial value
+ *
+ * @param seedValue
+ * The initial value for the optional
+ */
+ public Option(ContainedType seedValue) {
+ held = seedValue;
+ }
+
+ @Override
+ public <BoundType> IHolder<BoundType> bind(
+ Function<ContainedType, IHolder<BoundType>> binder) {
+ if (held == null) {
+ return new Option<>(null);
+ }
+
+ return binder.apply(held);
+ }
+
+ @Override
+ public <MappedType> IHolder<MappedType> map(
+ Function<ContainedType, MappedType> mapper) {
+ if (held == null) {
+ return new Option<>(null);
+ }
+
+ return new Option<>(mapper.apply(held));
+ }
+
+ @Override
+ public IHolder<ContainedType> transform(
+ UnaryOperator<ContainedType> transformer) {
+ if (held != null) {
+ held = transformer.apply(held);
+ }
+
+ return this;
+ }
+
+ @Override
+ public <UnwrappedType> UnwrappedType unwrap(
+ Function<ContainedType, UnwrappedType> unwrapper) {
+ if (held == null) {
+ return null;
+ }
+
+ return unwrapper.apply(held);
+ }
+
+ @Override
+ public <NewType> Function<ContainedType, IHolder<NewType>> lift(
+ Function<ContainedType, NewType> func) {
+ return (val) -> {
+ return new Option<>(func.apply(val));
+ };
+ }
+}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/Pair.java b/BJC-Utils2/src/main/java/bjc/utils/data/Pair.java
index 05955b6..0d2c1b0 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/data/Pair.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/Pair.java
@@ -56,8 +56,8 @@ public class Pair<LeftType, RightType>
}
@Override
- public <MergedType> MergedType merge(
- BiFunction<LeftType, RightType, MergedType> merger) {
+ public <MergedType> MergedType
+ merge(BiFunction<LeftType, RightType, MergedType> merger) {
return merger.apply(leftValue, rightValue);
}
@@ -66,4 +66,16 @@ public class Pair<LeftType, RightType>
return "pair[l=" + leftValue.toString() + ", r="
+ rightValue.toString() + "]";
}
+
+ @Override
+ public <NewLeft> IPair<NewLeft, RightType>
+ mapLeft(Function<LeftType, NewLeft> mapper) {
+ return new Pair<>(mapper.apply(leftValue), rightValue);
+ }
+
+ @Override
+ public <NewRight> IPair<LeftType, NewRight>
+ mapRight(Function<RightType, NewRight> mapper) {
+ return new Pair<>(leftValue, mapper.apply(rightValue));
+ }
} \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/WrappedLazy.java b/BJC-Utils2/src/main/java/bjc/utils/data/WrappedLazy.java
new file mode 100644
index 0000000..737482c
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/WrappedLazy.java
@@ -0,0 +1,69 @@
+package bjc.utils.data;
+
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+
+class WrappedLazy<ContainedType> implements IHolder<ContainedType> {
+ private IHolder<IHolder<ContainedType>> held;
+
+ // This has an extra parameter, because otherwise it erases to the same
+ // as the public one
+ private WrappedLazy(IHolder<IHolder<ContainedType>> wrappedHolder,
+ @SuppressWarnings("unused") boolean dummy) {
+ held = wrappedHolder;
+ }
+
+ public WrappedLazy(IHolder<ContainedType> wrappedHolder) {
+ held = new Lazy<>(wrappedHolder);
+ }
+
+ @Override
+ public <BoundType> IHolder<BoundType> bind(
+ Function<ContainedType, IHolder<BoundType>> binder) {
+ IHolder<IHolder<BoundType>> newHolder = held
+ .map((containedHolder) -> {
+ return containedHolder.bind(binder);
+ });
+
+ return new WrappedLazy<>(newHolder, false);
+ }
+
+ @Override
+ public <MappedType> IHolder<MappedType> map(
+ Function<ContainedType, MappedType> mapper) {
+ IHolder<IHolder<MappedType>> newHolder = held
+ .map((containedHolder) -> {
+ return containedHolder.map(mapper);
+ });
+
+ return new WrappedLazy<>(newHolder, false);
+ }
+
+ @Override
+ public IHolder<ContainedType> transform(
+ UnaryOperator<ContainedType> transformer) {
+ // FIXME this smells bad to me, but I can't figure out how else to
+ // do it
+ held.transform((containedHolder) -> {
+ return containedHolder.transform(transformer);
+ });
+
+ return this;
+ }
+
+ @Override
+ public <UnwrappedType> UnwrappedType unwrap(
+ Function<ContainedType, UnwrappedType> unwrapper) {
+ return held.unwrap((containedHolder) -> {
+ return containedHolder.unwrap(unwrapper);
+ });
+ }
+
+ @Override
+ public <NewType> Function<ContainedType, IHolder<NewType>> lift(
+ Function<ContainedType, NewType> func) {
+ return (val) -> {
+ return new Lazy<>(func.apply(val));
+ };
+ }
+}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/WrappedOption.java b/BJC-Utils2/src/main/java/bjc/utils/data/WrappedOption.java
new file mode 100644
index 0000000..c36cafa
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/data/WrappedOption.java
@@ -0,0 +1,89 @@
+package bjc.utils.data;
+
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+
+class WrappedOption<ContainedType> implements IHolder<ContainedType> {
+ private IHolder<IHolder<ContainedType>> held;
+
+ private WrappedOption(IHolder<IHolder<ContainedType>> toHold,
+ @SuppressWarnings("unused") boolean dummy) {
+ held = toHold;
+ }
+
+ public WrappedOption(IHolder<ContainedType> seedValue) {
+ held = new Option<>(seedValue);
+ }
+
+ @Override
+ public <BoundType> IHolder<BoundType> bind(
+ Function<ContainedType, IHolder<BoundType>> binder) {
+ IHolder<IHolder<BoundType>> newHolder = held
+ .map((containedHolder) -> {
+ return containedHolder.bind((containedValue) -> {
+ if (containedValue == null) {
+ return new Option<>(null);
+ }
+
+ return binder.apply(containedValue);
+ });
+ });
+
+ return new WrappedOption<>(newHolder, false);
+ }
+
+ @Override
+ public <MappedType> IHolder<MappedType> map(
+ Function<ContainedType, MappedType> mapper) {
+ IHolder<IHolder<MappedType>> newHolder = held
+ .map((containedHolder) -> {
+ return containedHolder.map((containedValue) -> {
+ if (containedValue == null) {
+ return null;
+ }
+
+ return mapper.apply(containedValue);
+ });
+ });
+
+ return new WrappedOption<>(newHolder, false);
+ }
+
+ @Override
+ public IHolder<ContainedType> transform(
+ UnaryOperator<ContainedType> transformer) {
+ held.transform((containedHolder) -> {
+ return containedHolder.transform((containedValue) -> {
+ if (containedValue == null) {
+ return null;
+ }
+
+ return transformer.apply(containedValue);
+ });
+ });
+
+ return this;
+ }
+
+ @Override
+ public <UnwrappedType> UnwrappedType unwrap(
+ Function<ContainedType, UnwrappedType> unwrapper) {
+ return held.unwrap((containedHolder) -> {
+ return containedHolder.unwrap((containedValue) -> {
+ if (containedValue == null) {
+ return null;
+ }
+
+ return unwrapper.apply(containedValue);
+ });
+ });
+ }
+
+ @Override
+ public <NewType> Function<ContainedType, IHolder<NewType>> lift(
+ Function<ContainedType, NewType> func) {
+ return (val) -> {
+ return new Option<>(func.apply(val));
+ };
+ }
+}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalList.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalList.java
index 91b2ba3..5327dbe 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalList.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalList.java
@@ -246,6 +246,16 @@ public interface IFunctionalList<ContainedType> {
ContainedType randItem(Function<Integer, Integer> rnd);
/**
+ * Select a random item from the list, using a default random number
+ * generator
+ *
+ * @return A random item from the list
+ */
+ default ContainedType randItem() {
+ return randItem((num) -> (int) (Math.random() * num));
+ }
+
+ /**
* Reduce this list to a single value, using a accumulative approach.
*
* @param <StateType>
diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/PushdownMap.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/PushdownMap.java
new file mode 100644
index 0000000..cc31923
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/PushdownMap.java
@@ -0,0 +1,91 @@
+package bjc.utils.funcdata;
+
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+/**
+ * A map where
+ *
+ * @author ben
+ *
+ * @param <KeyType>
+ * @param <ValueType>
+ */
+public class PushdownMap<KeyType, ValueType>
+ implements IFunctionalMap<KeyType, ValueType> {
+
+ @Override
+ public boolean containsKey(KeyType key) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public IFunctionalMap<KeyType, ValueType> extend() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void forEach(BiConsumer<KeyType, ValueType> action) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void forEachKey(Consumer<KeyType> action) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void forEachValue(Consumer<ValueType> action) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public ValueType get(KeyType key) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public int getSize() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public IFunctionalList<KeyType> keyList() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public <V2> IFunctionalMap<KeyType, V2> mapValues(
+ Function<ValueType, V2> transformer) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public ValueType put(KeyType key, ValueType val) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public ValueType remove(KeyType key) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public IFunctionalList<ValueType> valueList() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/theory/Bifunctor.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/theory/Bifunctor.java
new file mode 100644
index 0000000..3bea135
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/theory/Bifunctor.java
@@ -0,0 +1,66 @@
+package bjc.utils.funcdata.theory;
+
+import java.util.function.Function;
+
+/**
+ * A functor over a pair of heterogenous types
+ *
+ * @author ben
+ * @param <LeftType>
+ * The type stored on the 'left' of the pair
+ * @param <RightType>
+ * The type stored on the 'right' of the pair
+ *
+ */
+public interface Bifunctor<LeftType, RightType> {
+ /**
+ * Lift a function to operate over the left part of this pair
+ *
+ * @param <OldLeft>
+ * The old left type of the pair
+ * @param <OldRight>
+ * The old right type of the pair
+ * @param <NewLeft>
+ * The new left type of the pair
+ * @param func
+ * The function to lift to work over the left side of the
+ * pair
+ * @return The function lifted to work over the left side of bifunctors
+ */
+ public <OldLeft, OldRight, NewLeft>
+ Function<Bifunctor<OldLeft, OldRight>, Bifunctor<NewLeft, OldRight>>
+ fmapLeft(Function<OldLeft, NewLeft> func);
+
+ /**
+ * Lift a function to operate over the right part of this pair
+ *
+ * @param <OldLeft>
+ * The old left type of the pair
+ * @param <OldRight>
+ * The old right type of the pair
+ * @param <NewRight>
+ * The new right type of the pair
+ * @param func
+ * The function to lift to work over the right side of the
+ * pair
+ * @return The function lifted to work over the right side of
+ * bifunctors
+ */
+ public <OldLeft, OldRight, NewRight>
+ Function<Bifunctor<OldLeft, OldRight>, Bifunctor<OldLeft, NewRight>>
+ fmapRight(Function<OldRight, NewRight> func);
+
+ /**
+ * Get the value contained on the left of this bifunctor
+ *
+ * @return The value on the left side of this bifunctor
+ */
+ public LeftType getLeft();
+
+ /**
+ * Get the value contained on the right of this bifunctor
+ *
+ * @return The value on the right of this bifunctor
+ */
+ public RightType getRight();
+}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/theory/Functor.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/theory/Functor.java
new file mode 100644
index 0000000..76f48e2
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/theory/Functor.java
@@ -0,0 +1,39 @@
+package bjc.utils.funcdata.theory;
+
+import java.util.function.Function;
+
+/**
+ * Represents a container or context some sort usually, but the precise
+ * definition is that it represents exactly what it is defined as
+ *
+ * @author ben
+ * @param <ContainedType>
+ * The value inside the functor
+ */
+public interface Functor<ContainedType> {
+ /**
+ * Converts a normal function to operate over values in a functor.
+ *
+ * N.B: Even though the type signature implies that you can apply the
+ * resulting function to any type of functor, it is only safe to call
+ * it on instances of the type of functor you called fmap on.
+ *
+ * @param <ArgType>
+ * The argument of the function
+ * @param <ReturnType>
+ * The return type of the function
+ * @param func
+ * The function to convert
+ * @return The passed in function converted to work over a particular
+ * type of functors
+ */
+ public <ArgType, ReturnType> Function<Functor<ArgType>, Functor<ReturnType>> fmap(
+ Function<ArgType, ReturnType> func);
+
+ /**
+ * Retrieve the thing inside this functor
+ *
+ * @return The thing inside this functor
+ */
+ public ContainedType getValue();
+}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/theory/package-info.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/theory/package-info.java
new file mode 100644
index 0000000..33c80d6
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/theory/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * Random functional type things that don't belong elsewhere
+ *
+ * @author ben
+ *
+ */
+package bjc.utils.funcdata.theory; \ No newline at end of file
diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcutils/StringUtils.java b/BJC-Utils2/src/main/java/bjc/utils/funcutils/StringUtils.java
index 2f8aa09..9401b7e 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/funcutils/StringUtils.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/funcutils/StringUtils.java
@@ -74,8 +74,14 @@ public class StringUtils {
}
}
+ /**
+ * Print out a deque with a special case for easily showing a deque is empty
+ * @param <ContainedType> The type in the deque
+ * @param queue The deque to print
+ * @return A string version of the deque, with allowance for an empty deque
+ */
public static <ContainedType> String printDeque(
- Deque<ContainedType> queuedTrees) {
- return queuedTrees.isEmpty() ? "(none)" : queuedTrees.toString();
+ Deque<ContainedType> queue) {
+ return queue.isEmpty() ? "(none)" : queue.toString();
}
}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/gui/HolderOutputPanel.java b/BJC-Utils2/src/main/java/bjc/utils/gui/HolderOutputPanel.java
index 4cbfb61..49c7283 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/gui/HolderOutputPanel.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/gui/HolderOutputPanel.java
@@ -17,25 +17,31 @@ public class HolderOutputPanel extends JPanel {
private static final long serialVersionUID = 166573313903782080L;
private Timer updateTimer;
private JLabel value;
+ private int nDelay;
+ private IHolder<String> val;
/**
* Create a new display panel, backed by a holder
*
* @param lab
* The label to attach to this field
- * @param val
+ * @param valueHolder
* The holder to get the value from
* @param nDelay
* The delay in ms between value updates
*/
- public HolderOutputPanel(String lab, IHolder<String> val, int nDelay) {
+ public HolderOutputPanel(String lab, IHolder<String> valueHolder,
+ int nDelay) {
+ this.val = valueHolder;
+ this.nDelay = nDelay;
+
setLayout(new HLayout(2));
JLabel label = new JLabel(lab);
- value = new JLabel(val.getValue() + " (stopped)");
+ value = new JLabel("(stopped)");
updateTimer = new Timer(nDelay, (event) -> {
- value.setText(val.getValue());
+ value.setText(valueHolder.getValue());
});
add(label);
@@ -57,4 +63,17 @@ public class HolderOutputPanel extends JPanel {
value.setText(value.getText() + " (stopped)");
}
+
+ /**
+ * Set this panel back to its initial state
+ */
+ public void reset() {
+ stopUpdating();
+
+ value.setText("(stopped)");
+
+ updateTimer = new Timer(nDelay, (event) -> {
+ value.setText(val.getValue());
+ });
+ }
}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/StackBasedConfigReader.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/StackBasedConfigReader.java
new file mode 100644
index 0000000..2d15711
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/StackBasedConfigReader.java
@@ -0,0 +1,37 @@
+package bjc.utils.parserutils;
+
+/**
+ * This class parses a config file written in RPN and uses it to construct
+ * data items
+ *
+ * @author ben
+ *
+ * TODO implement me
+ */
+public class StackBasedConfigReader {
+ public static interface IItem {
+ public ItemType getType();
+ }
+
+ /**
+ * Represents the types of item that can be found on stacks
+ *
+ * @author ben
+ *
+ */
+ public static enum ItemType {
+ /**
+ * Represents an integral number
+ */
+ INTEGER,
+ /**
+ * Represents a string of characters
+ */
+ STRING,
+ /**
+ * Represents an arbitrary object
+ */
+ OBJECT
+ }
+
+}