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 super T, ? extends R> mapper) {
return executor -> apply(executor).map(mapper);
}
@Override
default Par flatMap(Function1 super T, ? extends Kind> mapper) {
return executor -> apply(executor).flatMap(value -> mapper.andThen(ParOf::narrowK).apply(value).apply(executor));
}
default Par andThen(Par extends R> next) {
return map2(this, next, second());
}
default Par onSuccess(Consumer1 super T> callback) {
return executor -> apply(executor).onSuccess(callback);
}
default Par onFailure(Consumer1 super Throwable> callback) {
return executor -> apply(executor).onFailure(callback);
}
default Par onComplete(Consumer1 super Try extends T>> callback) {
return executor -> apply(executor).onComplete(callback);
}
default Par ap(Par> apply) {
return executor -> apply(executor).ap(apply.apply(executor));
}
default Par filter(Matcher1 super T> matcher) {
return executor -> apply(executor).filter(matcher);
}
default Par filterNot(Matcher1 super T> matcher) {
return executor -> apply(executor).filterNot(matcher);
}
default Par recover(Function1 super Throwable, ? extends T> recover) {
return fold(recover, identity());
}
default Par recoverWith(Class type,
Function1 super X, ? extends T> mapper) {
return executor -> apply(executor).recoverWith(type, mapper);
}
default Par fold(Function1 super Throwable, ? extends R> failureMapper,
Function1 super T, ? extends R> 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 extends T> producer) {
return executor -> Future.task(executor, producer);
}
static Par defer(Producer extends Kind> producer) {
return executor -> {
Producer> andThen = producer.andThen(ParOf::narrowK);
return andThen.get().apply(executor);
};
}
static Par later(Producer extends T> producer) {
return executor -> Future.later(executor, producer::get);
}
static Par delay(Duration delay, Producer extends T> 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 extends A> acquire,
Function1 super A, ? extends Par extends B>> use, Consumer1 super A> release) {
return executor -> Future.bracket(acquire.apply(executor), a -> use.apply(a).apply(executor), release);
}
static Par map2(Par extends A> parA, Par extends B> parB,
Function2 super A, ? super B, ? extends C> mapper) {
return parB.ap(parA.map(mapper.curried()));
}
static Par> tuple(Par extends A> parA, Par extends B> 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