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

com.github.tonivade.purefun.instances.PromiseInstances 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.Precondition.checkNonNull;
import static com.github.tonivade.purefun.concurrent.PromiseOf.toPromise;

import java.util.concurrent.Executor;

import com.github.tonivade.purefun.Function1;
import com.github.tonivade.purefun.Kind;
import com.github.tonivade.purefun.concurrent.Future;
import com.github.tonivade.purefun.concurrent.Promise;
import com.github.tonivade.purefun.concurrent.PromiseOf;
import com.github.tonivade.purefun.concurrent.Promise_;
import com.github.tonivade.purefun.typeclasses.Applicative;
import com.github.tonivade.purefun.typeclasses.Functor;
import com.github.tonivade.purefun.typeclasses.Monad;

public interface PromiseInstances {

  static Functor functor() {
    return PromiseFunctor.INSTANCE;
  }

  static Applicative applicative() {
    return applicative(Future.DEFAULT_EXECUTOR);
  }

  static Applicative applicative(Executor executor) {
    return PromiseApplicative.instance(checkNonNull(executor));
  }

  static Monad monad() {
    return monad(Future.DEFAULT_EXECUTOR);
  }

  static Monad monad(Executor executor) {
    return PromiseMonad.instance(checkNonNull(executor));
  }
}

interface PromiseFunctor extends Functor {

  PromiseFunctor INSTANCE = new PromiseFunctor() {};

  @Override
  default  Kind map(Kind value, Function1 mapper) {
    return value.fix(toPromise()).map(mapper);
  }
}

interface PromiseExecutorHolder {
  Executor executor();
}

interface PromisePure extends Applicative, PromiseExecutorHolder {

  @Override
  default  Kind pure(T value) {
    return Promise.make(executor()).succeeded(value);
  }
}

interface PromiseApplicative extends PromisePure {

  static PromiseApplicative instance(Executor executor) {
    return () -> executor;
  }

  @Override
  default  Kind ap(Kind value, 
      Kind> apply) {
    return value.fix(PromiseOf::narrowK).ap(apply.fix(PromiseOf::narrowK));
  }
}

interface PromiseMonad extends PromisePure, Monad {

  static PromiseMonad instance(Executor executor) {
    return () -> executor;
  }

  @Override
  default  Kind flatMap(Kind value,
      Function1> map) {
    return value.fix(toPromise()).flatMap(map.andThen(PromiseOf::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  Kind ap(Kind value, 
      Kind> apply) {
    return PromiseInstances.applicative(executor()).ap(value, apply);
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy