javaslang.Function5 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.
/* / \____ _ _ ____ ______ / \ ____ __ _ _____
* / / \/ \ / \/ \ / /\__\/ // \/ \ / / _ \ Javaslang
* _/ / /\ \ \/ / /\ \\__\\ \ // /\ \ /\\/ \__/ / Copyright 2014-now Daniel Dietrich
* /___/\_/ \_/\____/\_/ \_/\__\/__/___\_/ \_// \__/_____/ 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 java.util.function.Function;
import javaslang.control.Option;
import javaslang.control.Try;
/**
* Represents a function with 5 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 argument 5 of the function
* @param return type of the function
* @author Daniel Dietrich
* @since 1.1.0
*/
@FunctionalInterface
public interface Function5 extends λ {
/**
* The serial version uid.
*/
long serialVersionUID = 1L;
/**
* Creates a {@code Function5} 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
* @param 5th argument
* @return a {@code Function5}
*/
static Function5 of(Function5 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
* @param 5th 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 Function5> lift(Function5 partialFunction) {
return (t1, t2, t3, t4, t5) -> Try.of(() -> partialFunction.apply(t1, t2, t3, t4, t5)).getOption();
}
/**
* Applies this function to 5 arguments and returns the result.
*
* @param t1 argument 1
* @param t2 argument 2
* @param t3 argument 3
* @param t4 argument 4
* @param t5 argument 5
* @return the result of function application
*
*/
R apply(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5);
/**
* Applies this function partially to one argument.
*
* @param t1 argument 1
* @return a partial application of this function
*
*/
default Function4 apply(T1 t1) {
return (T2 t2, T3 t3, T4 t4, T5 t5) -> apply(t1, t2, t3, t4, t5);
}
/**
* Applies this function partially to two arguments.
*
* @param t1 argument 1
* @param t2 argument 2
* @return a partial application of this function
*
*/
default Function3 apply(T1 t1, T2 t2) {
return (T3 t3, T4 t4, T5 t5) -> apply(t1, t2, t3, t4, t5);
}
/**
* 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
*
*/
default Function2 apply(T1 t1, T2 t2, T3 t3) {
return (T4 t4, T5 t5) -> apply(t1, t2, t3, t4, t5);
}
/**
* Applies this function partially to 4 arguments.
*
* @param t1 argument 1
* @param t2 argument 2
* @param t3 argument 3
* @param t4 argument 4
* @return a partial application of this function
*
*/
default Function1 apply(T1 t1, T2 t2, T3 t3, T4 t4) {
return (T5 t5) -> apply(t1, t2, t3, t4, t5);
}
@Override
default int arity() {
return 5;
}
@Override
default Function1>>>> curried() {
return t1 -> t2 -> t3 -> t4 -> t5 -> apply(t1, t2, t3, t4, t5);
}
@Override
default Function1, R> tupled() {
return t -> apply(t._1, t._2, t._3, t._4, t._5);
}
@Override
default Function5 reversed() {
return (t5, t4, t3, t2, t1) -> apply(t1, t2, t3, t4, t5);
}
@Override
default Function5 memoized() {
if (isMemoized()) {
return this;
} else {
final Object lock = new Object();
final Map, R> cache = new HashMap<>();
final Function1, R> tupled = tupled();
return (Function5 & Memoized) (t1, t2, t3, t4, t5) -> {
final R result;
synchronized (lock) {
result = cache.computeIfAbsent(Tuple.of(t1, t2, t3, t4, t5), tupled::apply);
}
return result;
};
}
}
/**
* Returns a composed function that first applies this Function5 to the given argument and then applies
* {@linkplain Function} {@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 Function5 andThen(Function super R, ? extends V> after) {
Objects.requireNonNull(after, "after is null");
return (t1, t2, t3, t4, t5) -> after.apply(apply(t1, t2, t3, t4, t5));
}
@Override
default Type getType() {
return new Type<>(this);
}
/**
* Represents the type of a {@code Function5} which consists of 5 parameter types
* and a return type.
*
*
* @param the 1st parameter type of the function
* @param the 2nd parameter type of the function
* @param the 3rd parameter type of the function
* @param the 4th parameter type of the function
* @param the 5th parameter type of the function
* @param the return type of the function
* @author Daniel Dietrich
* @since 2.0.0
*/
final class Type extends λ.Type {
private static final long serialVersionUID = 1L;
private Type(Function5 λ) {
super(λ);
}
@SuppressWarnings("unchecked")
public Class parameterType1() {
return (Class) parameterTypes()[0];
}
@SuppressWarnings("unchecked")
public Class parameterType2() {
return (Class) parameterTypes()[1];
}
@SuppressWarnings("unchecked")
public Class parameterType3() {
return (Class) parameterTypes()[2];
}
@SuppressWarnings("unchecked")
public Class parameterType4() {
return (Class) parameterTypes()[3];
}
@SuppressWarnings("unchecked")
public Class parameterType5() {
return (Class) parameterTypes()[4];
}
}
}