diff options
| -rw-r--r-- | src/main/java/bjc/data/CollectionUtils.java | 54 | ||||
| -rw-r--r-- | src/main/java/bjc/data/Holder.java | 4 | ||||
| -rw-r--r-- | src/main/java/bjc/functypes/Combinators.java | 40 | ||||
| -rw-r--r-- | src/main/java/bjc/functypes/Const.java | 19 | ||||
| -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.java | 2 | ||||
| -rw-r--r-- | src/main/java/bjc/optics/Lens.java | 68 | ||||
| -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.java | 55 | ||||
| -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.java | 18 | ||||
| -rw-r--r-- | src/main/java/bjc/typeclasses/package-info.java | 18 | ||||
| -rw-r--r-- | src/main/java/bjc/typeclasses/todo | 126 | ||||
| -rw-r--r-- | src/test/java/bjc/test/functypes/optics/LensesTest.java | 2 |
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 { |
