diff options
| author | Ben Culkin <scorpress@gmail.com> | 2020-11-21 16:52:26 -0500 |
|---|---|---|
| committer | Ben Culkin <scorpress@gmail.com> | 2020-11-21 16:52:26 -0500 |
| commit | 63528c2ac18054f9ac679ac3f8789d7dbd2a43e2 (patch) | |
| tree | 78fc1e4993f06f046e3ddd234d13080dd450909a /src/main | |
| parent | 023cc940331caffe6710691f16fcca92e6ad5bfa (diff) | |
Add some function combinators
This adds some interesting function combinators
Diffstat (limited to 'src/main')
| -rw-r--r-- | src/main/java/bjc/functypes/Combinators.java | 133 |
1 files changed, 133 insertions, 0 deletions
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 <Input> The input type. + * @param <Output> 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 <Input, Output> Function<Input, Output> iftt( + Predicate<Input> in, + Function<Input, Output> ifTrue, + Function<Input, Output> ifFalse) + { + return arg -> in.test(arg) ? ifTrue.apply(arg) : ifFalse.apply(arg); + } + + /** + * Execute an action before calling a function. + * + * @param <Input> The input to the function. + * @param <Output> 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 <Input, Output> Function<Input, Output> beforeThis( + Consumer<Input> action, Function<Input, Output> terminal) + { + return (arg) -> { + action.accept(arg); + return terminal.apply(arg); + }; + } + + /** + * Execute an action after calling a function. + * + * @param <Input> The input to the function. + * @param <Output> 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 <Input, Output> Consumer<Input> andThen( + Function<Input, Output> initial, Consumer<Output> action) + { + return (arg) -> action.accept(initial.apply(arg)); + } + + /** + * Standalone function composer. + * + * @param <Left> The input type of the initial function. + * @param <Middle> The shared input/output type. + * @param <Right> 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 <Left, Middle, Right> Function<Left, Right> compose( + Function<Left, Middle> initial, + Function<Middle, Right> terminal) + { + return (arg) -> terminal.apply(initial.apply(arg)); + } + + /** + * Execute a function with some internal state. + * + * @param <Input> The input type of the function. + * @param <Output> The output type of the function. + * @param <State> 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 <Input, Output, State> Function<Input, Output> introducing( + Supplier<State> source, + BiFunction<State, Input, Output> action) + { + return (input) -> action.apply(source.get(), input); + } + + /** + * Invoke a given function with null to produce its result. + * + * @param <Input> The input type of the function. + * @param <Output> The output type of the function. + * + * @param action The function to invoke. + * + * @return The result of calling the function with null. + */ + public static <Input, Output> Output invoke(Function<Input, Output> 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<Integer> action) + { + for (int i = 0; i < times; i++) action.accept(i); + } +}
\ No newline at end of file |
