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

org.smallibs.concurrent.promise.PromiseHelper Maven / Gradle / Ivy

There is a newer version: 0.11.0
Show newest version
/*
 * HPAS
 * https://github.com/d-plaindoux/hpas
 *
 * Copyright (c) 2016-2017 Didier Plaindoux
 * Licensed under the LGPL2 license.
 */

package org.smallibs.concurrent.promise;

import org.smallibs.concurrent.promise.impl.PromisesSet;
import org.smallibs.concurrent.promise.impl.SolvedPromise;
import org.smallibs.control.Applicative;
import org.smallibs.control.Functor;
import org.smallibs.control.Monad;
import org.smallibs.data.Try;
import org.smallibs.type.HK;
import org.smallibs.util.FunctionsHelper;

import java.util.List;
import java.util.function.Function;

public enum PromiseHelper {
    ;

    public static  Functor> functor(Promise promise) {
        return (Functor4Promise) () -> promise;
    }

    public static  Applicative> applicative(Promise promise) {
        return (Applicative4Promise) () -> promise;
    }

    public static  Monad> monad(Promise promise) {
        return (Monad4Promise) () -> promise;
    }

    public static  Promise success(T t) {
        return new SolvedPromise<>(Try.success(t));
    }

    public static  Promise failure(Throwable t) {
        return new SolvedPromise<>(Try.failure(t));
    }

    @SafeVarargs
    public static  Promise> join(Promise... promises) {
        return new PromisesSet<>(PromisesSet.Strategy.NO_STOP, promises);
    }

    @SafeVarargs
    public static  Promise> forall(Promise... promises) {
        return new PromisesSet<>(PromisesSet.Strategy.STOP_ON_ERROR, promises);
    }

    @SafeVarargs
    public static  Promise> exists(Promise... promises) {
        return new PromisesSet<>(PromisesSet.Strategy.STOP_ON_SUCCESS, promises);
    }

    @SuppressWarnings("unchecked")
    private static > HK> specialize(HK app) {
        return (HK>) app;
    }

    @SuppressWarnings("unchecked")
    private static > HK generalize(HK> app) {
        return (HK) app;
    }

    //
    // Internal classes
    //

    @FunctionalInterface
    private interface Functor4Promise extends Functor> {

        @Override
        default > HK map(Function function) {
            return generalize((Functor4Promise) () -> self().map(FunctionsHelper.fromFunction(function)));
        }

        @Override
        default  T1 accept(Function>, T1> f) {
            return self().accept(f);
        }

    }

    @FunctionalInterface
    private interface Applicative4Promise extends Functor4Promise, Applicative> {

        @Override
        default > HK apply(Functor, ?> functor) {
            return generalize((Applicative4Promise) () -> self().flatmap(a -> {
                final HK map = functor.map(bFunction -> bFunction.apply(a));
                return specialize(map).self();
            }));
        }
    }

    /**
     * @param 
     */
    private interface Monad4Promise extends Applicative4Promise, Monad> {

        @Override
        default > HK flatmap(Function> function) {
            final Function> tPromiseFunction = t -> {
                final HK apply = function.apply(t);
                return specialize(apply).self();
            };

            return generalize((Monad4Promise) () -> self().flatmap(tPromiseFunction));
        }
    }
}