com.github.tonivade.purefun.instances.ParInstances Maven / Gradle / Ivy
/*
* Copyright (c) 2018-2022, Antonio Gabriel Muñoz Conejo
* Distributed under the terms of the MIT License
*/
package com.github.tonivade.purefun.instances;
import static com.github.tonivade.purefun.Function1.identity;
import java.time.Duration;
import com.github.tonivade.purefun.Consumer1;
import com.github.tonivade.purefun.Function1;
import com.github.tonivade.purefun.Kind;
import com.github.tonivade.purefun.Producer;
import com.github.tonivade.purefun.Unit;
import com.github.tonivade.purefun.concurrent.Par;
import com.github.tonivade.purefun.concurrent.ParOf;
import com.github.tonivade.purefun.concurrent.Par_;
import com.github.tonivade.purefun.typeclasses.Applicative;
import com.github.tonivade.purefun.typeclasses.Bracket;
import com.github.tonivade.purefun.typeclasses.Defer;
import com.github.tonivade.purefun.typeclasses.Functor;
import com.github.tonivade.purefun.typeclasses.Monad;
import com.github.tonivade.purefun.typeclasses.MonadDefer;
import com.github.tonivade.purefun.typeclasses.MonadThrow;
import com.github.tonivade.purefun.typeclasses.Reference;
import com.github.tonivade.purefun.typeclasses.Resource;
public interface ParInstances {
static Functor functor() {
return ParFunctor.INSTANCE;
}
static Applicative applicative() {
return PureApplicative.INSTANCE;
}
static Monad monad() {
return ParMonad.INSTANCE;
}
static MonadDefer monadDefer() {
return ParMonadDefer.INSTANCE;
}
static Reference reference(A value) {
return Reference.of(monadDefer(), value);
}
static Resource resource(Par acquire) {
return resource(acquire, AutoCloseable::close);
}
static Resource resource(Par acquire, Consumer1 release) {
return Resource.from(monadDefer(), acquire, release);
}
}
interface ParFunctor extends Functor {
ParFunctor INSTANCE = new ParFunctor() {};
@Override
default Par map(Kind value, Function1 super T, ? extends R> mapper) {
return value.fix(ParOf::narrowK).map(mapper);
}
}
interface ParPure extends Applicative {
@Override
default Par pure(T value) {
return Par.success(value);
}
}
interface PureApplicative extends ParPure {
PureApplicative INSTANCE = new PureApplicative() {};
@Override
default Par ap(Kind value,
Kind> apply) {
return value.fix(ParOf::narrowK).ap(apply.fix(ParOf::narrowK));
}
}
interface ParMonad extends ParPure, Monad {
ParMonad INSTANCE = new ParMonad() {};
@Override
default Par flatMap(Kind value, Function1 super T, ? extends Kind> map) {
return value.fix(ParOf::narrowK).flatMap(x -> map.apply(x).fix(ParOf::narrowK));
}
/**
* XXX In order to create real parallel computations, we need to override ap to use the
* applicative version of the ap method
*/
@Override
default Par ap(Kind value,
Kind> apply) {
return ParInstances.applicative().ap(value, apply).fix(ParOf::narrowK);
}
}
interface ParMonadThrow extends ParMonad, MonadThrow {
ParMonadThrow INSTANCE = new ParMonadThrow() {};
@Override
default Par raiseError(Throwable error) {
return Par.failure(error);
}
@Override
default Par handleErrorWith(Kind value,
Function1 super Throwable, ? extends Kind> handler) {
return ParOf.narrowK(value).fold(handler.andThen(ParOf::narrowK), Par::success).flatMap(identity());
}
}
interface ParDefer extends Defer {
@Override
default Par defer(Producer extends Kind> defer) {
return Par.defer(defer.map(ParOf::narrowK)::get);
}
}
interface ParBracket extends Bracket {
@Override
default Par bracket(
Kind acquire,
Function1 super A, ? extends Kind> use,
Function1 super A, ? extends Kind> release) {
return Par.bracket(ParOf.narrowK(acquire), use.andThen(ParOf::narrowK), release::apply);
}
}
interface ParMonadDefer extends ParMonadThrow, ParDefer, ParBracket, MonadDefer {
ParMonadDefer INSTANCE = new ParMonadDefer() {};
@Override
default Par sleep(Duration duration) {
return Par.sleep(duration);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy