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

com.github.tonivade.purefun.concurrent.Par 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.concurrent;

import static com.github.tonivade.purefun.Function1.identity;
import static com.github.tonivade.purefun.Function2.second;
import static com.github.tonivade.purefun.data.ImmutableList.empty;

import java.time.Duration;
import java.util.concurrent.Executor;

import com.github.tonivade.purefun.CheckedRunnable;
import com.github.tonivade.purefun.Consumer1;
import com.github.tonivade.purefun.Function1;
import com.github.tonivade.purefun.Function2;
import com.github.tonivade.purefun.HigherKind;
import com.github.tonivade.purefun.Kind;
import com.github.tonivade.purefun.Bindable;
import com.github.tonivade.purefun.Matcher1;
import com.github.tonivade.purefun.Producer;
import com.github.tonivade.purefun.Tuple;
import com.github.tonivade.purefun.Tuple2;
import com.github.tonivade.purefun.Unit;
import com.github.tonivade.purefun.data.Sequence;
import com.github.tonivade.purefun.type.Try;

@HigherKind
@FunctionalInterface
public interface Par extends ParOf, Bindable {

  Future apply(Executor executor);

  default Promise run(Executor executor) {
    return apply(executor).toPromise();
  }

  default Promise run() {
    return run(Future.DEFAULT_EXECUTOR);
  }

  @Override
  default  Par map(Function1 mapper) {
    return executor -> apply(executor).map(mapper);
  }

  @Override
  default  Par flatMap(Function1> mapper) {
    return executor -> apply(executor).flatMap(value -> mapper.andThen(ParOf::narrowK).apply(value).apply(executor));
  }

  default  Par andThen(Par next) {
    return map2(this, next, second());
  }

  default Par onSuccess(Consumer1 callback) {
    return executor -> apply(executor).onSuccess(callback);
  }

  default Par onFailure(Consumer1 callback) {
    return executor -> apply(executor).onFailure(callback);
  }

  default Par onComplete(Consumer1> callback) {
    return executor -> apply(executor).onComplete(callback);
  }

  default  Par ap(Par> apply) {
    return executor -> apply(executor).ap(apply.apply(executor));
  }

  default Par filter(Matcher1 matcher) {
    return executor -> apply(executor).filter(matcher);
  }

  default Par filterNot(Matcher1 matcher) {
    return executor -> apply(executor).filterNot(matcher);
  }

  default Par recover(Function1 recover) {
    return fold(recover, identity());
  }

  default  Par recoverWith(Class type, 
      Function1 mapper) {
    return executor -> apply(executor).recoverWith(type, mapper);
  }

  default  Par fold(Function1 failureMapper, 
      Function1 successMapper) {
    return executor -> apply(executor).fold(failureMapper, successMapper);
  }

  static  Par success(T value) {
    return executor -> Future.success(executor, value);
  }

  static  Par failure(Throwable error) {
    return executor -> Future.failure(executor, error);
  }

  static  Par task(Producer producer) {
    return executor -> Future.task(executor, producer);
  }

  static  Par defer(Producer> producer) {
    return executor -> {
      Producer> andThen = producer.andThen(ParOf::narrowK);
      return andThen.get().apply(executor);
    };
  }

  static  Par later(Producer producer) {
    return executor -> Future.later(executor, producer::get);
  }

  static  Par delay(Duration delay, Producer producer) {
    return executor -> Future.delay(executor, delay, producer::get);
  }

  static Par exec(CheckedRunnable runnable) {
    return executor -> Future.exec(executor, runnable);
  }

  static  Par async(Consumer1>> consumer) {
    return executor -> Future.async(executor, consumer);
  }

  static Par sleep(Duration delay) {
    return executor -> Future.sleep(executor, delay);
  }

  static  Par bracket(Par acquire, 
      Function1> use, Consumer1 release) {
    return executor -> Future.bracket(acquire.apply(executor), a -> use.apply(a).apply(executor), release);
  }

  static  Par map2(Par parA, Par parB, 
      Function2 mapper) {
    return parB.ap(parA.map(mapper.curried()));
  }

  static  Par> tuple(Par parA, Par parB) {
    return map2(parA, parB, Tuple::of);
  }

  static  Par> traverse(Sequence> sequence) {
    return sequence.foldLeft(success(empty()),
        (Par> xa, Par a) -> map2(xa, a, Sequence::append));
  }

  static Par sequence(Sequence> sequence) {
    return sequence.fold(unit(), Par::andThen).andThen(unit());
  }

  static Par unit() {
    return success(Unit.unit());
  }
}





© 2015 - 2025 Weber Informatics LLC | Privacy Policy