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-2019, 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.concurrent.Executor;
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;

@FunctionalInterface
public interface Function1 {

  R apply(A value);

  default  Function1 andThen(Function1 after) {
    return value -> after.apply(apply(value));
  }

  default  Function1 compose(Function1 before) {
    return value -> apply(before.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.run(() -> apply(value));
  }

  default Function1> liftFuture(Executor executor) {
    return value -> Future.run(executor, () -> 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 CheckedFunction1 checked() {
    return this::apply;
  }

  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() {
    return ignore -> {
      throw new UnsupportedOperationException();
    };
  }

  static  Function1 of(Function1 reference) {
    return reference;
  }
}