All Downloads are FREE. Search and download functionalities are using the official Maven repository.

javaslang.Function5 Maven / Gradle / Ivy

There is a newer version: 2.0.0-RC4
Show newest version
/*     / \____  _    _  ____   ______  / \ ____  __    _ _____
 *    /  /    \/ \  / \/    \ /  /\__\/  //    \/  \  / /  _  \   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 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]; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy