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

com.github.tonivade.purefun.Function1 Maven / Gradle / Ivy

/*
 * Copyright (c) 2018-2020, Antonio Gabriel Muñoz Conejo 
 * Distributed under the terms of the MIT License
 */
package com.github.tonivade.purefun;

import static com.github.tonivade.purefun.data.Sequence.listOf;

import java.util.Optional;
import java.util.stream.Stream;

import com.github.tonivade.purefun.concurrent.Future;
import com.github.tonivade.purefun.data.Sequence;
import com.github.tonivade.purefun.type.Either;
import com.github.tonivade.purefun.type.Id;
import com.github.tonivade.purefun.type.Option;
import com.github.tonivade.purefun.type.Try;

/**
 * 

This interface represents a function with a single parameter. Similar to {@link java.util.function.Function}.

*

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 function parameter * @param type of return value */ @HigherKind @FunctionalInterface public interface Function1 extends Recoverable { default R apply(A value) { try { return run(value); } catch (Throwable t) { return sneakyThrow(t); } } R run(A value) throws Throwable; default Function1 andThen(Function1 after) { return value -> after.apply(apply(value)); } default Function1 compose(Function1 before) { return value -> apply(before.apply(value)); } default Function1 flatMap(Function1> after) { return value -> after.apply(apply(value)).apply(value); } default Function1> liftOptional() { return value -> Optional.ofNullable(apply(value)); } default Function1> liftOption() { return value -> Option.of(() -> apply(value)); } default Function1> liftTry() { return value -> Try.of(() -> apply(value)); } default Function1> liftId() { return value -> Id.of(apply(value)); } default Function1> liftFuture() { return value -> Future.async(() -> apply(value)); } default Function1> liftEither() { return liftTry().andThen(Try::toEither); } default Function1> liftRight() { return value -> Either.right(apply(value)); } default Function1> liftLeft() { return value -> Either.left(apply(value)); } default Function1> sequence() { return value -> listOf(apply(value)); } default Function1> stream() { return value -> Stream.of(apply(value)); } default Function1 memoized() { return new MemoizedFunction<>(this); } default PartialFunction1 partial(Matcher1 isDefined) { return new PartialFunction1() { @Override public boolean isDefinedAt(A value) { return isDefined.match(value); } @Override public R apply(A value) { return Function1.this.apply(value); } }; } static Function1 identity() { return value -> value; } static Function1 cons(T cons) { return ignore -> cons; } static Function1 fail(Producer supplier) { return ignore -> { throw supplier.get(); }; } static Function1 of(Function1 reference) { return reference; } }