// Path: src/main/java/co/unruly/control/pair/Triple.java
// @FunctionalInterface
// public interface TriFunction<A, B, C, R> {
//     R apply(A a, B b, C c);
// }


import co.unruly.control.pair.Triple.TriFunction;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
package co.unruly.control;



/**
 * A collection of functions to partially apply arguments to functions, to simplify usage
 * in streams, optionals etc.
 */
public interface PartialApplication {

    /**
     * Binds the provided argument to the function, and returns a Supplier with that argument applied.
     *
     * bind(f, a) is equivalent to () -> f.apply(a)
     */
    static <I, O> Supplier<O> bind(Function<I, O> f, I input) {
        return () -> f.apply(input);
    }

    /**
     * Binds the provided argument to the function, and returns a new Function with that argument already applied.
     *
     * bind(f, a) is equivalent to b -> f.apply(a, b)
     */
    static <A, B, R> Function<B, R> bind(BiFunction<A, B, R> f, A firstParam) {
        return secondParam -> f.apply(firstParam, secondParam);
    }

    /**
     * Binds the provided arguments to the function, and returns a new Supplier with those arguments already applied.
     *
     * bind(f, a, b) is equivalent to () -> f.apply(a, b)
     */
    static <A, B, R> Supplier<R> bind(BiFunction<A, B, R> f, A firstParam, B secondParam) {
        return () -> f.apply(firstParam, secondParam);
    }

    /**
     * Binds the provided argument to the function, and returns a new BiFunction with that argument already applied.
     *
     * bind(f, a) is equivalent to (b, c) -> f.apply(a, b, c)
     */
// Path: src/main/java/co/unruly/control/pair/Triple.java
// @FunctionalInterface
// public interface TriFunction<A, B, C, R> {
//     R apply(A a, B b, C c);
// }


// Path: src/main/java/co/unruly/control/PartialApplication.java
import co.unruly.control.pair.Triple.TriFunction;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;

package co.unruly.control;



/**
 * A collection of functions to partially apply arguments to functions, to simplify usage
 * in streams, optionals etc.
 */
public interface PartialApplication {

    /**
     * Binds the provided argument to the function, and returns a Supplier with that argument applied.
     *
     * bind(f, a) is equivalent to () -> f.apply(a)
     */
    static <I, O> Supplier<O> bind(Function<I, O> f, I input) {
        return () -> f.apply(input);
    }

    /**
     * Binds the provided argument to the function, and returns a new Function with that argument already applied.
     *
     * bind(f, a) is equivalent to b -> f.apply(a, b)
     */
    static <A, B, R> Function<B, R> bind(BiFunction<A, B, R> f, A firstParam) {
        return secondParam -> f.apply(firstParam, secondParam);
    }

    /**
     * Binds the provided arguments to the function, and returns a new Supplier with those arguments already applied.
     *
     * bind(f, a, b) is equivalent to () -> f.apply(a, b)
     */
    static <A, B, R> Supplier<R> bind(BiFunction<A, B, R> f, A firstParam, B secondParam) {
        return () -> f.apply(firstParam, secondParam);
    }

    /**
     * Binds the provided argument to the function, and returns a new BiFunction with that argument already applied.
     *
     * bind(f, a) is equivalent to (b, c) -> f.apply(a, b, c)
     */
    static <A, B, C, R> BiFunction<B, C, R> bind(TriFunction<A, B, C, R> f, A firstParam) {