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-2021, 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 Function1Of, 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 dimap(Function1 before, Function1 after) { Function1 compose = compose(before); return compose.andThen(after); } 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.task(() -> 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 cons(Producer cons) { return ignore -> cons.get(); } static Function1 fail(Producer supplier) { return ignore -> { throw supplier.get(); }; } @SuppressWarnings("unchecked") static Function1 of(Function1 reference) { return (Function1) reference; } }