javaslang.CheckedFunction4 Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of javaslang Show documentation
Show all versions of javaslang Show documentation
Javaslang is a Java standard library extension built for Java 8 and above.
/* / \____ _ _ ____ ______ / \ ____ __ _______
* / / \/ \ / \/ \ / /\__\/ // \/ \ // /\__\ JΛVΛSLΛNG
* _/ / /\ \ \/ / /\ \\__\\ \ // /\ \ /\\/ \ /__\ \ Copyright 2014-2017 Javaslang, http://javaslang.io
* /___/\_/ \_/\____/\_/ \_/\__\/__/\__\_/ \_// \__/\_____/ Licensed under the Apache License, Version 2.0
*/
package javaslang;
/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*\
G E N E R A T O R C R A F T E D
\*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import javaslang.control.Option;
import javaslang.control.Try;
/**
* Represents a function with 4 arguments.
*
* @param argument 1 of the function
* @param argument 2 of the function
* @param argument 3 of the function
* @param argument 4 of the function
* @param return type of the function
* @author Daniel Dietrich
* @since 1.1.0
*/
@FunctionalInterface
public interface CheckedFunction4 extends λ {
/**
* The serial version uid.
*/
long serialVersionUID = 1L;
/**
* Creates a {@code CheckedFunction4} based on
*
*
* Examples (w.l.o.g. referring to Function1):
* // using a lambda expression
* Function1<Integer, Integer> add1 = Function1.of(i -> i + 1);
*
* // using a method reference (, e.g. Integer method(Integer i) { return i + 1; })
* Function1<Integer, Integer> add2 = Function1.of(this::method);
*
* // using a lambda reference
* Function1<Integer, Integer> add3 = Function1.of(add1::apply);
*
*
* Caution: Reflection loses type information of lambda references.
*
// type of a lambda expression
* Type<?, ?> type1 = add1.getType(); // (Integer) -> Integer
*
* // type of a method reference
* Type<?, ?> type2 = add2.getType(); // (Integer) -> Integer
*
* // type of a lambda reference
* Type<?, ?> type3 = add3.getType(); // (Object) -> Object
*
*
* @param methodReference (typically) a method reference, e.g. {@code Type::method}
* @param return type
* @param 1st argument
* @param 2nd argument
* @param 3rd argument
* @param 4th argument
* @return a {@code CheckedFunction4}
*/
static CheckedFunction4 of(CheckedFunction4 methodReference) {
return methodReference;
}
/**
* Lifts the given {@code partialFunction} into a total function that returns an {@code Option} result.
*
* @param partialFunction a function that is not defined for all values of the domain (e.g. by throwing)
* @param return type
* @param 1st argument
* @param 2nd argument
* @param 3rd argument
* @param 4th argument
* @return a function that applies arguments to the given {@code partialFunction} and returns {@code Some(result)}
* if the function is defined for the given arguments, and {@code None} otherwise.
*/
static Function4> lift(CheckedFunction4 partialFunction) {
return (t1, t2, t3, t4) -> Try.of(() -> partialFunction.apply(t1, t2, t3, t4)).getOption();
}
/**
* Applies this function to 4 arguments and returns the result.
*
* @param t1 argument 1
* @param t2 argument 2
* @param t3 argument 3
* @param t4 argument 4
* @return the result of function application
* @throws Throwable if something goes wrong applying this function to the given arguments
*/
R apply(T1 t1, T2 t2, T3 t3, T4 t4) throws Throwable;
/**
* Applies this function partially to one argument.
*
* @param t1 argument 1
* @return a partial application of this function
* @throws Throwable if something goes wrong partially applying this function to the given arguments
*/
default CheckedFunction3 apply(T1 t1) throws Throwable {
return (T2 t2, T3 t3, T4 t4) -> apply(t1, t2, t3, t4);
}
/**
* Applies this function partially to two arguments.
*
* @param t1 argument 1
* @param t2 argument 2
* @return a partial application of this function
* @throws Throwable if something goes wrong partially applying this function to the given arguments
*/
default CheckedFunction2 apply(T1 t1, T2 t2) throws Throwable {
return (T3 t3, T4 t4) -> apply(t1, t2, t3, t4);
}
/**
* Applies this function partially to three arguments.
*
* @param t1 argument 1
* @param t2 argument 2
* @param t3 argument 3
* @return a partial application of this function
* @throws Throwable if something goes wrong partially applying this function to the given arguments
*/
default CheckedFunction1 apply(T1 t1, T2 t2, T3 t3) throws Throwable {
return (T4 t4) -> apply(t1, t2, t3, t4);
}
@Override
default int arity() {
return 4;
}
@Override
default CheckedFunction1>>> curried() {
return t1 -> t2 -> t3 -> t4 -> apply(t1, t2, t3, t4);
}
@Override
default CheckedFunction1, R> tupled() {
return t -> apply(t._1, t._2, t._3, t._4);
}
@Override
default CheckedFunction4 reversed() {
return (t4, t3, t2, t1) -> apply(t1, t2, t3, t4);
}
@Override
default CheckedFunction4 memoized() {
if (isMemoized()) {
return this;
} else {
final Map, R> cache = new HashMap<>();
return (CheckedFunction4 & Memoized) (t1, t2, t3, t4) ->
Memoized.of(cache, Tuple.of(t1, t2, t3, t4), t -> Try.of(() -> apply(t1, t2, t3, t4)).get());
}
}
/**
* Returns a composed function that first applies this CheckedFunction4 to the given argument and then applies
* {@linkplain CheckedFunction1} {@code after} to the result.
*
* @param return type of after
* @param after the function applied after this
* @return a function composed of this and after
* @throws NullPointerException if after is null
*/
default CheckedFunction4 andThen(CheckedFunction1 super R, ? extends V> after) {
Objects.requireNonNull(after, "after is null");
return (t1, t2, t3, t4) -> after.apply(apply(t1, t2, t3, t4));
}
}