summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/bjc/data/CollectionUtils.java54
-rw-r--r--src/main/java/bjc/data/Holder.java4
-rw-r--r--src/main/java/bjc/functypes/Combinators.java40
-rw-r--r--src/main/java/bjc/functypes/Const.java19
-rw-r--r--src/main/java/bjc/functypes/Predicates.java (renamed from src/main/java/bjc/functypes/optics/Lens.java)29
-rw-r--r--src/main/java/bjc/functypes/ThrowFunction.java2
-rw-r--r--src/main/java/bjc/optics/Lens.java68
-rw-r--r--src/main/java/bjc/optics/LensX.java (renamed from src/main/java/bjc/functypes/optics/LensX.java)4
-rw-r--r--src/main/java/bjc/optics/Lenses.java (renamed from src/main/java/bjc/functypes/optics/Lenses.java)2
-rw-r--r--src/main/java/bjc/optics/MutableLens.java (renamed from src/main/java/bjc/functypes/optics/MutableLens.java)2
-rw-r--r--src/main/java/bjc/optics/Optic.java (renamed from src/main/java/bjc/functypes/optics/Optic.java)2
-rw-r--r--src/main/java/bjc/optics/PrismX.java (renamed from src/main/java/bjc/functypes/optics/PrismX.java)2
-rw-r--r--src/main/java/bjc/optics/impl/package-info.java (renamed from src/main/java/bjc/functypes/optics/impl/package-info.java)2
-rw-r--r--src/main/java/bjc/optics/package-info.java (renamed from src/main/java/bjc/functypes/optics/package-info.java)2
-rw-r--r--src/main/java/bjc/typeclasses/BiContainer.java (renamed from src/main/java/bjc/functypes/BiContainer.java)2
-rw-r--r--src/main/java/bjc/typeclasses/Container.java (renamed from src/main/java/bjc/functypes/Container.java)2
-rw-r--r--src/main/java/bjc/typeclasses/FunList.java55
-rw-r--r--src/main/java/bjc/typeclasses/FunctionalIsomorphism.java (renamed from src/main/java/bjc/functypes/FunctionalIsomorphism.java)2
-rw-r--r--src/main/java/bjc/typeclasses/Isomorphism.java (renamed from src/main/java/bjc/functypes/Isomorphism.java)2
-rw-r--r--src/main/java/bjc/typeclasses/ListC.java (renamed from src/main/java/bjc/functypes/ListC.java)2
-rw-r--r--src/main/java/bjc/typeclasses/Natural.java (renamed from src/main/java/bjc/functypes/Natural.java)36
-rw-r--r--src/main/java/bjc/typeclasses/PFLens.java18
-rw-r--r--src/main/java/bjc/typeclasses/package-info.java18
-rw-r--r--src/main/java/bjc/typeclasses/todo126
-rw-r--r--src/test/java/bjc/test/functypes/optics/LensesTest.java2
25 files changed, 464 insertions, 33 deletions
diff --git a/src/main/java/bjc/data/CollectionUtils.java b/src/main/java/bjc/data/CollectionUtils.java
new file mode 100644
index 0000000..08ef711
--- /dev/null
+++ b/src/main/java/bjc/data/CollectionUtils.java
@@ -0,0 +1,54 @@
+/*
+ * esodata - data structures of varying utility
+ * Copyright 2022, Ben Culkin
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+package bjc.data;
+
+import java.util.*;
+import java.util.function.Function;
+
+/**
+ * Various utilities for dealing w/ collections
+ * @author bjcul
+ *
+ */
+public class CollectionUtils {
+ /**
+ * Create a function that converts a collection into a map.
+ *
+ * @param <Val> The type of the values in the map
+ * @param <Idx> The type of the keys in the map
+ * @param <Ent> The type of the values in the collection
+ *
+ * @param keyFunc The function that determines keys
+ * @param valFunc The function that determines values
+ *
+ * @return A function which uses the provided function to create a map from a
+ * collection.
+ */
+ public static <Val, Idx, Ent> Function<Collection<Ent>, Map<Idx, Val>> indexBy(Function<Ent, Idx> keyFunc,
+ Function<Ent, Val> valFunc) {
+ return (coll) -> {
+ Map<Idx, Val> mep = new HashMap<>();
+
+ for (Ent ent : coll) {
+ mep.put(keyFunc.apply(ent), valFunc.apply(ent));
+ }
+
+ return mep;
+ };
+ }
+}
diff --git a/src/main/java/bjc/data/Holder.java b/src/main/java/bjc/data/Holder.java
index 4a1de75..57a5d6c 100644
--- a/src/main/java/bjc/data/Holder.java
+++ b/src/main/java/bjc/data/Holder.java
@@ -26,6 +26,7 @@ import bjc.data.internals.WrappedLazy;
import bjc.data.internals.WrappedOption;
import bjc.funcdata.FunctionalList;
import bjc.funcdata.theory.Functor;
+import bjc.typeclasses.Container;
/**
* A holder of a single value.
@@ -35,7 +36,8 @@ import bjc.funcdata.theory.Functor;
* @param <ContainedType>
* The type of value held.
*/
-public interface Holder<ContainedType> extends Functor<ContainedType> {
+public interface Holder<ContainedType> extends Functor<ContainedType>, Container<ContainedType, Holder<ContainedType>> {
+ // note: to really work, this should also take the binding parameter
/**
* Bind a function across the value in this container.
*
diff --git a/src/main/java/bjc/functypes/Combinators.java b/src/main/java/bjc/functypes/Combinators.java
index 0b157bb..14af611 100644
--- a/src/main/java/bjc/functypes/Combinators.java
+++ b/src/main/java/bjc/functypes/Combinators.java
@@ -301,14 +301,50 @@ public class Combinators {
// TODO: write a switch-like combinator that uses a KeyedList to get the desired
// fallthrough semantics
-
+
// TODO: non-shortcircuiting boolean combinators
-
+
+ /**
+ * Convert a function into one that takes a supplier as its parameter
+ *
+ * Note this is not as useful as the reverse, as we need to evaluate the
+ * supplier to call the function.
+ *
+ * @param <Input> The input type
+ * @param <Output> The output type
+ *
+ * @param f The function
+ *
+ * @return The function, taking a supplier as its first function
+ */
public static <Input, Output> Function<Supplier<Input>, Output> lazify(Function<Input, Output> f) {
return (supp) -> f.apply(supp.get());
}
+ /**
+ * Convert a lazy function into an eager one
+ *
+ * @param <Input> The input type
+ * @param <Output> The output type
+ *
+ * @param f A function that takes a supplier as its parameter
+ *
+ * @return A function which just takes a value
+ */
public static <Input, Output> Function<Input, Output> strictify(Function<Supplier<Input>, Output> f) {
return (val) -> f.apply(() -> val);
}
+
+ /**
+ * Convert a pure function into one that mutates a holder.
+ *
+ * @param <Input> The type of the function.
+ *
+ * @param f The function.
+ *
+ * @return A function that mutates a holder using the given function
+ */
+ public static <Input> Consumer<Holder<Input>> mutating(UnaryOperator<Input> f) {
+ return (hld) -> hld.transform(f);
+ }
} \ No newline at end of file
diff --git a/src/main/java/bjc/functypes/Const.java b/src/main/java/bjc/functypes/Const.java
new file mode 100644
index 0000000..2fc1606
--- /dev/null
+++ b/src/main/java/bjc/functypes/Const.java
@@ -0,0 +1,19 @@
+package bjc.functypes;
+
+import bjc.typeclasses.Container;
+
+public class Const<V, A> implements Container<V, Const<V, ?>>{
+ private V payload;
+
+ private Const(V payload) {
+ this.payload = payload;
+ }
+
+ public static <V, A> Const<V, A> of(V val) {
+ return new Const<>(val);
+ }
+
+ V get() {
+ return payload;
+ }
+}
diff --git a/src/main/java/bjc/functypes/optics/Lens.java b/src/main/java/bjc/functypes/Predicates.java
index c56a016..3977294 100644
--- a/src/main/java/bjc/functypes/optics/Lens.java
+++ b/src/main/java/bjc/functypes/Predicates.java
@@ -1,5 +1,6 @@
/*
- * esodata - data structures and other things, of varying utility
+ * esodata - data structures of varying utility
+ *
* Copyright 2022, Ben Culkin
*
* This program is free software: you can redistribute it and/or modify
@@ -15,16 +16,26 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package bjc.functypes.optics;
+package bjc.functypes;
+
+import java.util.function.BiPredicate;
+import java.util.function.Predicate;
/**
- * A type-invariant var Laarhoven lens.
- *
+ * Various utility functions for predicates
* @author bjcul
*
- * @param <Whole> The item this lens can focus on
- * @param <Part> The field this lens focuses on
*/
-public interface Lens<Whole, Part> extends LensX<Whole, Whole, Part, Part> {
- // Alias type
-}
+public class Predicates {
+ /**
+ * A predicate for logical implication (!x || y)
+ *
+ * @param x The LHS
+ * @param y The RHS
+ *
+ * @return Whether the LHS implies the RHS
+ */
+ public static boolean implies(boolean x, boolean y) {
+ return !x || y;
+ }
+} \ No newline at end of file
diff --git a/src/main/java/bjc/functypes/ThrowFunction.java b/src/main/java/bjc/functypes/ThrowFunction.java
index 2ec5bea..5c61161 100644
--- a/src/main/java/bjc/functypes/ThrowFunction.java
+++ b/src/main/java/bjc/functypes/ThrowFunction.java
@@ -20,6 +20,8 @@ package bjc.functypes;
import java.util.*;
import java.util.function.*;
+import bjc.typeclasses.Isomorphism;
+
/**
* An instance of {@link Function} that can throw an exception.
*
diff --git a/src/main/java/bjc/optics/Lens.java b/src/main/java/bjc/optics/Lens.java
new file mode 100644
index 0000000..be10eef
--- /dev/null
+++ b/src/main/java/bjc/optics/Lens.java
@@ -0,0 +1,68 @@
+/*
+ * esodata - data structures and other things, of varying utility
+ * Copyright 2022, Ben Culkin
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+package bjc.optics;
+
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+
+import bjc.typeclasses.BiContainer;
+
+/**
+ * A type-invariant var Laarhoven lens.
+ *
+ * @author bjcul
+ *
+ * @param <Whole> The item this lens can focus on
+ * @param <Part> The field this lens focuses on
+ */
+public interface Lens<Whole, Part> extends LensX<Whole, Whole, Part, Part>, BiContainer<Whole, Part, Lens<Whole, Part>> {
+ /**
+ * Modify a given whole using an operation
+ *
+ * @param source The whole to modify.
+ * @param mod The operation to use for modifying a part
+ *
+ * @return A modified whole
+ */
+ default Whole modify(Whole source, UnaryOperator<Part> mod) {
+ return set(source, mod.apply(get(source)));
+ }
+
+ /**
+ * Create a function which sets the part of a given whole.
+ *
+ * @param part The part to set
+ *
+ * @return A function that sets the given part on a whole.
+ */
+ default Function<Whole, Whole> setting(Part part) {
+ return (whole) -> set(whole, part);
+ }
+
+ /**
+ * Lift a function that modifies parts to one that modifies wholes.
+ *
+ * @param f The function which operates on parts
+ *
+ * @return A corresponding function which applies the given modification to a part.
+ */
+ default Function<Whole, Whole> lift(UnaryOperator<Part> f) {
+ // modify will be more efficient for some lenses
+ return (whole) -> modify(whole, f);
+ }
+}
diff --git a/src/main/java/bjc/functypes/optics/LensX.java b/src/main/java/bjc/optics/LensX.java
index 0c78370..d0f83be 100644
--- a/src/main/java/bjc/functypes/optics/LensX.java
+++ b/src/main/java/bjc/optics/LensX.java
@@ -15,9 +15,9 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package bjc.functypes.optics;
+package bjc.optics;
-import static bjc.functypes.optics.Lenses.immutable;
+import static bjc.optics.Lenses.immutable;
import java.util.function.BiFunction;
import java.util.function.Function;
diff --git a/src/main/java/bjc/functypes/optics/Lenses.java b/src/main/java/bjc/optics/Lenses.java
index 3c4c688..6cebc84 100644
--- a/src/main/java/bjc/functypes/optics/Lenses.java
+++ b/src/main/java/bjc/optics/Lenses.java
@@ -15,7 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package bjc.functypes.optics;
+package bjc.optics;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
diff --git a/src/main/java/bjc/functypes/optics/MutableLens.java b/src/main/java/bjc/optics/MutableLens.java
index 9c2e635..88eca04 100644
--- a/src/main/java/bjc/functypes/optics/MutableLens.java
+++ b/src/main/java/bjc/optics/MutableLens.java
@@ -15,7 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package bjc.functypes.optics;
+package bjc.optics;
/**
* A type-invariant lens for mutating objects.
diff --git a/src/main/java/bjc/functypes/optics/Optic.java b/src/main/java/bjc/optics/Optic.java
index 513e110..389da21 100644
--- a/src/main/java/bjc/functypes/optics/Optic.java
+++ b/src/main/java/bjc/optics/Optic.java
@@ -15,7 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package bjc.functypes.optics;
+package bjc.optics;
/**
* General interface for optics of varying sorts
diff --git a/src/main/java/bjc/functypes/optics/PrismX.java b/src/main/java/bjc/optics/PrismX.java
index b62bce3..b4986cf 100644
--- a/src/main/java/bjc/functypes/optics/PrismX.java
+++ b/src/main/java/bjc/optics/PrismX.java
@@ -15,7 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package bjc.functypes.optics;
+package bjc.optics;
public interface PrismX<W1, W2, P1, P2> extends Optic<W1, W2, P1, P2> {
diff --git a/src/main/java/bjc/functypes/optics/impl/package-info.java b/src/main/java/bjc/optics/impl/package-info.java
index 8ca00cf..b147877 100644
--- a/src/main/java/bjc/functypes/optics/impl/package-info.java
+++ b/src/main/java/bjc/optics/impl/package-info.java
@@ -15,4 +15,4 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package bjc.functypes.optics.impl; \ No newline at end of file
+package bjc.optics.impl; \ No newline at end of file
diff --git a/src/main/java/bjc/functypes/optics/package-info.java b/src/main/java/bjc/optics/package-info.java
index a3f656c..241b565 100644
--- a/src/main/java/bjc/functypes/optics/package-info.java
+++ b/src/main/java/bjc/optics/package-info.java
@@ -18,4 +18,4 @@
/**
*
*/
-package bjc.functypes.optics; \ No newline at end of file
+package bjc.optics; \ No newline at end of file
diff --git a/src/main/java/bjc/functypes/BiContainer.java b/src/main/java/bjc/typeclasses/BiContainer.java
index db822ba..9be00ca 100644
--- a/src/main/java/bjc/functypes/BiContainer.java
+++ b/src/main/java/bjc/typeclasses/BiContainer.java
@@ -15,7 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package bjc.functypes;
+package bjc.typeclasses;
public interface BiContainer<L, R, C extends BiContainer<?, ?, C>> {
// marker
diff --git a/src/main/java/bjc/functypes/Container.java b/src/main/java/bjc/typeclasses/Container.java
index f000705..b1e3e34 100644
--- a/src/main/java/bjc/functypes/Container.java
+++ b/src/main/java/bjc/typeclasses/Container.java
@@ -15,7 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package bjc.functypes;
+package bjc.typeclasses;
public interface Container<T, C extends Container<?, C>> {
// Marker
diff --git a/src/main/java/bjc/typeclasses/FunList.java b/src/main/java/bjc/typeclasses/FunList.java
new file mode 100644
index 0000000..cd16c82
--- /dev/null
+++ b/src/main/java/bjc/typeclasses/FunList.java
@@ -0,0 +1,55 @@
+package bjc.typeclasses;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Function;
+
+public sealed interface FunList<A, B> permits FunList.Done<A, B>, FunList.More<A, B> {
+ public final class Done<A, B> implements FunList<A, B> {
+ private final B val;
+
+ public Done(B val) {
+ this.val = val;
+ }
+
+ @Override
+ public B getB() {
+ return val;
+ }
+
+ @Override
+ public List<A> getAs() {
+ return new ArrayList<>();
+ }
+ }
+
+ public final class More<A, B> implements FunList<A, B> {
+ private A val;
+ private FunList<A, Function<A, B>> rest;
+
+ public More(A val, FunList<A, Function<A, B>> rest) {
+ this.val = val;
+ this.rest = rest;
+ }
+
+ @Override
+ public B getB() {
+ return rest.getB().apply(val);
+ }
+
+ @Override
+ public List<A> getAs() {
+ List<A> as = rest.getAs();
+ // Note: this is kinda inefficient. Should we instead say that it returns the As
+ // in reverse order
+ as.add(0, val);
+ return as;
+ }
+ }
+
+ public B getB();
+
+ public List<A> getAs();
+
+ // https://twanvl.nl/blog/haskell/non-regular1
+}
diff --git a/src/main/java/bjc/functypes/FunctionalIsomorphism.java b/src/main/java/bjc/typeclasses/FunctionalIsomorphism.java
index 43520e3..47d060c 100644
--- a/src/main/java/bjc/functypes/FunctionalIsomorphism.java
+++ b/src/main/java/bjc/typeclasses/FunctionalIsomorphism.java
@@ -15,7 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package bjc.functypes;
+package bjc.typeclasses;
import java.util.function.Function;
diff --git a/src/main/java/bjc/functypes/Isomorphism.java b/src/main/java/bjc/typeclasses/Isomorphism.java
index 3393ed6..dd5a740 100644
--- a/src/main/java/bjc/functypes/Isomorphism.java
+++ b/src/main/java/bjc/typeclasses/Isomorphism.java
@@ -15,7 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package bjc.functypes;
+package bjc.typeclasses;
import java.util.function.*;
diff --git a/src/main/java/bjc/functypes/ListC.java b/src/main/java/bjc/typeclasses/ListC.java
index 78fbb7a..16dca8a 100644
--- a/src/main/java/bjc/functypes/ListC.java
+++ b/src/main/java/bjc/typeclasses/ListC.java
@@ -15,7 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package bjc.functypes;
+package bjc.typeclasses;
import java.util.List;
diff --git a/src/main/java/bjc/functypes/Natural.java b/src/main/java/bjc/typeclasses/Natural.java
index ecf12c4..d487b9a 100644
--- a/src/main/java/bjc/functypes/Natural.java
+++ b/src/main/java/bjc/typeclasses/Natural.java
@@ -15,19 +15,41 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package bjc.functypes;
+package bjc.typeclasses;
+/**
+ * A natural transformation; a mapping between two type-containers which
+ * preserves the contents of the containers.
+ *
+ * @author bjcul
+ *
+ * @param <F> The actual type of the first container
+ * @param <G> The actual type of the second container
+ */
@FunctionalInterface
-public interface Natural<F extends Container<?, F>, G extends Container<?, G>> extends BiContainer<F, G, Natural<?, ?>> {
+public interface Natural<F extends Container<?, F>, G extends Container<?, G>>
+ extends BiContainer<F, G, Natural<?, ?>> {
+ /**
+ * Apply the natural transformation.
+ *
+ * @param <X> The type contained in the container
+ *
+ * @param val The container to be transformed
+ *
+ * @return The value, in the other container type
+ */
<X> Container<X, G> apply(Container<X, F> val);
- public static Natural<ListC<?>, ListC<?>> listID() {
+ /**
+ * The simplest possible natural transform, mapping a type to itself.
+ *
+ * @return The ID natural transform
+ */
+ public static <C extends Container<?, C>> Natural<C, C> ID() {
return new Natural<>() {
@Override
- public <X> ListC<X> apply(Container<X, ListC<?>> val) {
- ListC<X> lst = (ListC<X>) val;
-
- return lst;
+ public <X> Container<X, C> apply(Container<X, C> val) {
+ return val;
}
};
}
diff --git a/src/main/java/bjc/typeclasses/PFLens.java b/src/main/java/bjc/typeclasses/PFLens.java
new file mode 100644
index 0000000..0468efb
--- /dev/null
+++ b/src/main/java/bjc/typeclasses/PFLens.java
@@ -0,0 +1,18 @@
+package bjc.typeclasses;
+
+import java.util.function.Function;
+
+/**
+ * A profunctor lens
+ *
+ * @author bjcul
+ *
+ * @param <Whole1>
+ * @param <Whole2>
+ * @param <Part1>
+ * @param <Part2>
+ */
+public interface PFLens<Whole1, Whole2, Part1, Part2> {
+ // Container should be Functor once gthat is ironed out
+ <A, B, F extends Container<?, F>> Function<Whole1, Container<Whole2, F>> run(Function<Part1, Container<Part2, F>> f);
+}
diff --git a/src/main/java/bjc/typeclasses/package-info.java b/src/main/java/bjc/typeclasses/package-info.java
new file mode 100644
index 0000000..86ea3c1
--- /dev/null
+++ b/src/main/java/bjc/typeclasses/package-info.java
@@ -0,0 +1,18 @@
+/*
+ * esodata - Data structures of varying utility
+ * Copyright 2022, Ben Culkin
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+package bjc.typeclasses; \ No newline at end of file
diff --git a/src/main/java/bjc/typeclasses/todo b/src/main/java/bjc/typeclasses/todo
new file mode 100644
index 0000000..55dd77d
--- /dev/null
+++ b/src/main/java/bjc/typeclasses/todo
@@ -0,0 +1,126 @@
+https://bartoszmilewski.com/2014/01/14/functors-are-containers/
+ Note that I've not quite ironed out the whole deal w/ BiContainer yet, and type classes which take two parameters
+
+For lenses, name the class Iso as Mirror instead, to keep with the theme
+
+A profunctor value of the type p a b could then be considered a container of bs that are keyed by elements of type a.
+
+class (Profunctor p) => TamModule (ten :: * -> * -> *) p where
+ leftAction :: p a b -> p (c `ten` a) (c `ten` b)
+ rightAction :: p a b -> p (a `ten` c) (b `ten` c)
+
+type TamOptic ten s t a b
+ = forall p. TamModule ten p => p a b -> p s t
+data Optic ten s t a b
+ = forall c. Optic (s -> c `ten` a) (c `ten` b -> t)
+
+type TamProd p = TamModule (,) p
+type TamSum p = TamModule Either p
+
+data Pastro p a b where
+ Pastro :: ((y, z) -> b) -> p x y -> (a -> (x, z))
+ -> Pastro p a b
+data Copastro p a b where
+ Copastro :: (Either y z -> b) -> p x y -> (a -> Either x z)
+ -> Copastro p a b
+// https://bartoszmilewski.com/2017/07/07/profunctor-optics-the-categorical-view/
+
+https://r6research.livejournal.com/28338.html?utm_source=3userpost - A new case for the pointed functor class
+https://r6research.livejournal.com/28050.html - Grate: A new kind of Optic
+https://r6research.livejournal.com/27476.html - Profunctor hierarchy for objects
+
+class Functor c => Naperian c where
+ zipFWith :: Functor f => (f a -> b) -> f (c a) -> (c b)
+
+class (Traversable v, Naperian v) => FiniteVector v where
+ naperianTraverse :: (Functor f, Applicative g) => (f a -> g b) -> f (v a) -> g (v b)
+
+-- A simple example to get people started.
+instance FiniteVector Triple where
+ naperianTraverse h fv = Triple <$> h (one <$> fv) <*> h (two <$> fv) <*> h (three <$> fv)
+ where
+ one (Triple x y z) = x
+ two (Triple x y z) = y
+ three (Triple x y z) = z
+vectorSize :: FiniteVector v => Proxy (Constant () (v a)) -> Integer
+vectorSize p = getSum . getConstant $ naperianTraverse (const (Constant (Sum 1)) (Constant () `asProxyTypeOf` p)
+class Profunctor p => Power p where
+ waddle :: FiniteVector v => p a b -> p (v a) (v b)
+type FiniteGrate s t a b = Power p => p a b -> p s t
+
+type Lens' s a = forall f. Functor f => (a -> f a) -> s -> f s
+
+// Create lens for a Hours/Minutes/Seconds time type, which does the right thing
+
+data SLens α γ β = SLens {putR :: (α, γ) → (β , γ), putL :: (β , γ) → (α, γ), missing :: γ }
+
+(;) :: (SLens α σ1 β ) → (SLens β σ2 γ) → (SLens α (σ1,σ2) γ)
+l1 ; l2 = SLens putR putL (l1.missing, l2.missing)
+ where putR (a, (s1, s2)) =
+ let (b, s′1) = putR (a, s1)
+ (c, s′2) = putR (b, s2)
+ in (c, (s′1, s′2))
+ putL (c, (s1, s2)) =
+ let (b, s′2) = putL (c, s2)
+ (a, s′1) = putL (b, s1)
+ in (a, (s′1, s′2))
+idLensS :: SLens X () X
+idLensS = SLens id id ()
+
+type StateT σ τ α = σ → τ (α, σ)
+instance Monad τ ⇒ Monad (StateT σ τ ) where
+ return a = λs. return (a, s)
+ m >>= k = λs. do {(a, s′) ← m s; k a s′
+
+get :: Monad τ ⇒ StateT σ τ σ
+get = λs. return (s, s)
+set :: Monad τ ⇒ σ → StateT σ τ ()
+set s′ = λs. return ((), s′)
+
+lift :: Monad τ ⇒ τ α → StateT σ τ α
+lift m = λs. do {a ← m; return (a, s)}
+
+gets :: Monad τ ⇒ (σ → α) → StateT σ τ α
+gets f = do {s ← get; return (f s)}
+eval :: Monad τ ⇒ StateT σ τ α → σ → τ α
+eval m s = do {(a, s′) ← m s; return a }
+exec :: Monad τ ⇒ StateT σ τ α → σ → τ σ
+exec m s = do {(a, s′) ← m s; return s′ }
+
+data Codec g p x a = Codec { get :: g a, put :: x -> p a }
+instance (Functor g, Functor p) => Profunctor (Codec g p)
+instance (Monad g, Monad p) => Monad (Codec g p x)
+
+http://oleg.fi/gists/posts/2017-03-20-affine-traversal.html
+
+data Kiosk a b s t = Kiosk (s -> Either t a) (s -> b -> t)
+sellKiosk :: Kiosk a b a b
+sellKiosk = Kiosk Right (\_ -> id)
+instance Profunctor (Kiosk u v) where
+ dimap f g (Kiosk getter setter) = Kiosk
+ (\a -> first g $ getter (f a))
+ (\a v -> g (setter (f a) v))
+instance Strong (Kiosk u v) where
+ first' (Kiosk getter setter) = Kiosk
+ (\(a, c) -> first (,c) $ getter a)
+ (\(a, c) v -> (setter a v, c))
+instance Choice (Kiosk u v) where
+ right' (Kiosk getter setter) = Kiosk
+ (\eca -> assoc (second getter eca))
+ (\eca v -> second (`setter` v) eca)
+ where
+ assoc :: Either a (Either b c) -> Either (Either a b) c
+ assoc (Left a) = Left (Left a)
+ assoc (Right (Left b)) = Left (Right b)
+ assoc (Right (Right c)) = Right c
+
+newtype Kiask a b t = Kiask { runKiask :: (Either t a, b -> t) }
+sellKiask :: a -> Kiask a b b
+sellKiask a = Kiask (Right a, id)
+instance Functor (Kiask a b) where
+ fmap f (Kiask (Left t, g)) = Kiask (Left (f t), f . g)
+ fmap f (Kiask (Right a, g)) = Kiask (Right a, f . g)
+instance Pointed (Kiask a b) where
+ point x = Kiask (Left x, const x)
+
+http://oleg.fi/gists/posts/2021-01-08-indexed-optics-dilemma.html \ No newline at end of file
diff --git a/src/test/java/bjc/test/functypes/optics/LensesTest.java b/src/test/java/bjc/test/functypes/optics/LensesTest.java
index ff13a42..c431c2f 100644
--- a/src/test/java/bjc/test/functypes/optics/LensesTest.java
+++ b/src/test/java/bjc/test/functypes/optics/LensesTest.java
@@ -5,7 +5,7 @@ import static org.junit.Assert.*;
import org.junit.Test;
import bjc.data.Holder;
-import bjc.functypes.optics.Lenses;
+import bjc.optics.Lenses;
public class LensesTest {