From 63528c2ac18054f9ac679ac3f8789d7dbd2a43e2 Mon Sep 17 00:00:00 2001 From: Ben Culkin Date: Sat, 21 Nov 2020 16:52:26 -0500 Subject: Add some function combinators This adds some interesting function combinators --- src/main/java/bjc/functypes/Combinators.java | 133 +++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 src/main/java/bjc/functypes/Combinators.java (limited to 'src/main/java') diff --git a/src/main/java/bjc/functypes/Combinators.java b/src/main/java/bjc/functypes/Combinators.java new file mode 100644 index 0000000..21238c2 --- /dev/null +++ b/src/main/java/bjc/functypes/Combinators.java @@ -0,0 +1,133 @@ +package bjc.functypes; + +import java.util.function.*; + +/** + * A bunch of only slightly related function combinators. + * + * @author Ben Culkin + * + */ +public class Combinators { + /** + * If-then-else combinator. + * + * @param The input type. + * @param The output type. + * + * @param in The predicate to run. + * @param ifTrue The condition to run when it is true. + * @param ifFalse The condition to run when it is false. + * + * @return A function which will invoke one or the other action, based on the predicate. + */ + @SuppressWarnings("unused") + public static Function iftt( + Predicate in, + Function ifTrue, + Function ifFalse) + { + return arg -> in.test(arg) ? ifTrue.apply(arg) : ifFalse.apply(arg); + } + + /** + * Execute an action before calling a function. + * + * @param The input to the function. + * @param The output from the function. + * + * @param action The action to run on the input. + * @param terminal The function to call. + * + * @return A function that runs the provided action before calling the function. + */ + public static Function beforeThis( + Consumer action, Function terminal) + { + return (arg) -> { + action.accept(arg); + return terminal.apply(arg); + }; + } + + /** + * Execute an action after calling a function. + * + * @param The input to the function. + * @param The output to the function. + * + * @param initial The function to call. + * @param action The action to call after doing the function. + * + * @return A function that calls the provided action after the function. + */ + public static Consumer andThen( + Function initial, Consumer action) + { + return (arg) -> action.accept(initial.apply(arg)); + } + + /** + * Standalone function composer. + * + * @param The input type of the initial function. + * @param The shared input/output type. + * @param The output type of the terminal function. + * + * @param initial The first function to call. + * @param terminal The second function to call. + * + * @return A function that composes the provided functions together. + */ + public static Function compose( + Function initial, + Function terminal) + { + return (arg) -> terminal.apply(initial.apply(arg)); + } + + /** + * Execute a function with some internal state. + * + * @param The input type of the function. + * @param The output type of the function. + * @param The type of the internal state. + * + * @param source The function which provides internal state. + * @param action The function to call. + * + * @return A function which hides the production of the internal state. + */ + public static Function introducing( + Supplier source, + BiFunction action) + { + return (input) -> action.apply(source.get(), input); + } + + /** + * Invoke a given function with null to produce its result. + * + * @param The input type of the function. + * @param The output type of the function. + * + * @param action The function to invoke. + * + * @return The result of calling the function with null. + */ + public static Output invoke(Function action) + { + return action.apply(null); + } + + /** + * Execute an action a given number of times. + * + * @param times The number of times to execute the action. + * @param action The action to execute. + */ + public static void times(int times, Consumer action) + { + for (int i = 0; i < times; i++) action.accept(i); + } +} \ No newline at end of file -- cgit v1.2.3