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

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 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> 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> handler) {
    return ParOf.narrowK(value).fold(handler.andThen(ParOf::narrowK), Par::success).flatMap(identity());
  }
}

interface ParDefer extends Defer {

  @Override
  default  Par defer(Producer> defer) {
    return Par.defer(defer.map(ParOf::narrowK)::get);
  }
}

interface ParBracket extends Bracket {

  @Override
  default  Par bracket(
      Kind acquire, 
      Function1> use, 
      Function1> 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