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

io.vavr.Function1 Maven / Gradle / Ivy

There is a newer version: 1.0.0-alpha-4
Show newest version
/*  __    __  __  __    __  ___
 * \  \  /  /    \  \  /  /  __/
 *  \  \/  /  /\  \  \/  /  /
 *   \____/__/  \__\____/__/
 *
 * Copyright 2014-2019 Vavr, http://vavr.io
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.vavr;

/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*\
   G E N E R A T O R   C R A F T E D
\*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/

import io.vavr.control.Option;
import io.vavr.control.Try;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.Predicate;

/**
 * Represents a function with one argument.
 *
 * @param  argument 1 of the function
 * @param  return type of the function
 * @author Daniel Dietrich
 */
@FunctionalInterface
public interface Function1 extends Serializable, Function {

    /**
     * The serial version uid.
     */
    long serialVersionUID = 1L;

    /**
     * Returns a function that always returns the constant
     * value that you give in parameter.
     *
     * @param  generic parameter type 1 of the resulting function
     * @param  the result type
     * @param value the value to be returned
     * @return a function always returning the given value
     */
    static  Function1 constant(R value) {
        return (t1) -> value;
    }

    /**
     * Creates a {@code Function1} 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 * @return a {@code Function1} */ static Function1 of(Function1 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 * @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. */ @SuppressWarnings("RedundantTypeArguments") static Function1> lift(Function partialFunction) { return t1 -> Try.of(() -> partialFunction.apply(t1)).toOption(); } /** * Lifts the given {@code partialFunction} into a total function that returns an {@code Try} 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 * @return a function that applies arguments to the given {@code partialFunction} and returns {@code Success(result)} * if the function is defined for the given arguments, and {@code Failure(throwable)} otherwise. */ static Function1> liftTry(Function partialFunction) { return t1 -> Try.of(() -> partialFunction.apply(t1)); } /** * Narrows the given {@code Function1} to {@code Function1} * * @param f A {@code Function1} * @param return type * @param 1st argument * @return the given {@code f} instance as narrowed type {@code Function1} */ @SuppressWarnings("unchecked") static Function1 narrow(Function1 f) { return (Function1) f; } /** * Returns the identity Function1, i.e. the function that returns its input. * * @param argument type (and return type) of the identity function * @return the identity Function1 */ static Function1 identity() { return t -> t; } /** * Applies this function to one argument and returns the result. * * @param t1 argument 1 * @return the result of function application * */ R apply(T1 t1); /** * Returns the number of function arguments. * @return an int value >= 0 * @see Arity */ default int arity() { return 1; } /** * Returns a curried version of this function. * * @return a curried function equivalent to this. */ default Function1 curried() { return this; } /** * Returns a tupled version of this function. * * @return a tupled function equivalent to this. */ default Function1, R> tupled() { return t -> apply(t._1); } /** * Returns a reversed version of this function. This may be useful in a recursive context. * * @return a reversed function equivalent to this. */ default Function1 reversed() { return this; } /** * Returns a memoizing version of this function, which computes the return value for given arguments only one time. * On subsequent calls given the same arguments the memoized value is returned. *

* Please note that memoizing functions do not permit {@code null} as single argument or return value. * * @return a memoizing function equivalent to this. */ default Function1 memoized() { if (isMemoized()) { return this; } else { final Map cache = new HashMap<>(); return (Function1 & Memoized) (t1) -> { synchronized (cache) { if (cache.containsKey(t1)) { return cache.get(t1); } else { final R value = apply(t1); cache.put(t1, value); return value; } } }; } } /** * Checks if this function is memoizing (= caching) computed values. * * @return true, if this function is memoizing, false otherwise */ default boolean isMemoized() { return this instanceof Memoized; } /** * Converts this {@code Function1} to a {@link PartialFunction} by adding an {@code isDefinedAt} condition. *

* @param isDefinedAt a predicate that states if an element is in the domain of the returned {@code PartialFunction}. * @return a new {@code PartialFunction} that has the same behavior like this function but is defined only for those elements that make it through the given {@code Predicate} * @throws NullPointerException if {@code isDefinedAt} is null */ default PartialFunction partial(Predicate isDefinedAt) { Objects.requireNonNull(isDefinedAt, "isDefinedAt is null"); final Function1 self = this; return new PartialFunction() { private static final long serialVersionUID = 1L; @Override public boolean isDefinedAt(T1 t1) { return isDefinedAt.test(t1); } @Override public R apply(T1 t1) { return self.apply(t1); } }; } /** * Returns a composed function that first applies this Function1 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 Function1 andThen(Function after) { Objects.requireNonNull(after, "after is null"); return (t1) -> after.apply(apply(t1)); } /** * Returns a composed function that first applies the {@linkplain Function} {@code before} the * given argument and then applies this Function1 to the result. * * @param argument type of before * @param before the function applied before this * @return a function composed of before and this * @throws NullPointerException if before is null */ default Function1 compose(Function before) { Objects.requireNonNull(before, "before is null"); return v -> apply(before.apply(v)); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy