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

com.github.tonivade.purefun.instances.FutureInstances Maven / Gradle / Ivy

/*
 * Copyright (c) 2018-2019, 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 static java.util.Objects.requireNonNull;

import java.util.concurrent.Executor;

import com.github.tonivade.purefun.Consumer1;
import com.github.tonivade.purefun.Function1;
import com.github.tonivade.purefun.Higher1;
import com.github.tonivade.purefun.Instance;
import com.github.tonivade.purefun.Producer;
import com.github.tonivade.purefun.concurrent.Future;
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.MonadError;

public interface FutureInstances {

  static Functor functor() {
    return new FutureFunctor() {};
  }

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

  static Applicative applicative(Executor executor) {
    requireNonNull(executor);
    return new FutureApplicative() {

      @Override
      public Executor executor() {
        return executor;
      }
    };
  }

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

  static Monad monad(Executor executor) {
    requireNonNull(executor);
    return new FutureMonad() {

      @Override
      public Executor executor() {
        return executor;
      }
    };
  }

  static MonadError monadError() {
    return monadError(Future.DEFAULT_EXECUTOR);
  }

  static MonadError monadError(Executor executor) {
    requireNonNull(executor);
    return new FutureMonadError() {

      @Override
      public Executor executor() {
        return executor;
      }
    };
  }

  static MonadDefer monadDefer() {
    return monadDefer(Future.DEFAULT_EXECUTOR);
  }

  static MonadDefer monadDefer(Executor executor) {
    requireNonNull(executor);
    return new FutureMonadDefer() {

      @Override
      public Executor executor() {
        return executor;
      }
    };
  }
}

@Instance
interface FutureFunctor extends Functor {

  @Override
  default  Future map(Higher1 value, Function1 mapper) {
    return Future.narrowK(value).map(mapper);
  }
}

@Instance
interface FuturePure extends Applicative {

  Executor executor();

  @Override
  default  Future pure(T value) {
    return Future.success(executor(), value);
  }
}

@Instance
interface FutureApplicative extends FuturePure {

  @Override
  default  Future ap(Higher1 value, Higher1> apply) {
    return Future.narrowK(value).flatMap(t -> Future.narrowK(apply).map(f -> f.apply(t)));
  }
}

@Instance
interface FutureMonad extends FuturePure, Monad {

  @Override
  default  Future flatMap(Higher1 value,
      Function1> map) {
    return Future.narrowK(value).flatMap(map.andThen(Future::narrowK));
  }
}

@Instance
interface FutureMonadError extends FutureMonad, MonadError {

  @Override
  Executor executor();

  @Override
  default  Future raiseError(Throwable error) {
    return Future.failure(executor(), error);
  }

  @Override
  default  Future handleErrorWith(Higher1 value,
      Function1> handler) {
    return Future.narrowK(value).fold(handler.andThen(Future::narrowK),
                                      success -> Future.success(executor(), success)).flatMap(identity());
  }
}

@Instance
interface FutureDefer extends Defer {

  Executor executor();

  @Override
  default  Future defer(Producer> defer) {
    return Future.defer(executor(), defer.andThen(Future::narrowK)::get);
  }
}

@Instance
interface FutureBracket extends Bracket {

  @Override
  default  Future bracket(Higher1 acquire, Function1> use, Consumer1 release) {
    return Future.narrowK(acquire)
      .flatMap(resource -> use.andThen(Future::narrowK).apply(resource)
          .onComplete(result -> release.accept(resource)));
  }
}

@Instance
interface FutureMonadDefer extends MonadDefer, FutureMonadError, FutureDefer, FutureBracket { }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy