com.github.tonivade.purefun.Function2 Maven / Gradle / Ivy
/*
* Copyright (c) 2018-2021, Antonio Gabriel Muñoz Conejo
* Distributed under the terms of the MIT License
*/
package com.github.tonivade.purefun;
import com.github.tonivade.purefun.type.Either;
import com.github.tonivade.purefun.type.Option;
import com.github.tonivade.purefun.type.Try;
/**
* This interface represents a function with a two parameters. Similar to {@link java.util.function.BiFunction}.
* The function can throws checked exceptions, but calling {@code apply()} method, the exception is sneaky thrown. So, it
* can be used as a higher order function in {@link java.util.stream.Stream} or {@link java.util.Optional} API.
* @param type of first function parameter
* @param type of second function parameter
* @param type of return value
*/
@FunctionalInterface
public interface Function2 extends Recoverable {
default R apply(A a, B b) {
try {
return run(a, b);
} catch (Throwable t) {
return sneakyThrow(t);
}
}
R run(A a, B b) throws Throwable;
default Function1> curried() {
return a -> b -> apply(a, b);
}
default Function1, R> tupled() {
return tuple -> apply(tuple.get1(), tuple.get2());
}
default Function2 andThen(Function1 super R, ? extends C> after) {
return (a, b) -> after.apply(apply(a, b));
}
default Function1 compose(Function1 super C, ? extends A> beforeT, Function1 super C, ? extends B> beforeV) {
return value -> apply(beforeT.apply(value), beforeV.apply(value));
}
default Function2> liftTry() {
return (a, b) -> Try.of(() -> apply(a, b));
}
default Function2> liftEither() {
return liftTry().andThen(Try::toEither);
}
default Function2> liftOption() {
return liftTry().andThen(Try::toOption);
}
default Function2 memoized() {
return (a, b) -> new MemoizedFunction<>(tupled()).apply(Tuple.of(a, b));
}
@SuppressWarnings("unchecked")
static Function2 of(Function2 super A, ? super B, ? extends R> reference) {
return (Function2) reference;
}
static Function2 uncurried(Function1 super A, ? extends Function1 super B, ? extends R>> function) {
return (a, b) -> function.apply(a).apply(b);
}
static Function2 cons(R value) {
return (a, b) -> value;
}
static Function2 first() {
return (a, b) -> a;
}
static Function2 second() {
return (a, b) -> b;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy