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

net.cassite.f.F Maven / Gradle / Ivy

package net.cassite.f;

import io.vertx.core.AsyncResult;
import io.vertx.core.Future;
import io.vertx.core.Handler;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;

public class F {
    private F() {
    }

    // ------- start Monad initializer -------

    public static  Monad unit(T value) {
        return Monad.unit(value);
    }

    public static  Monad unit() {
        return Monad.unit();
    }

    public static  Monad tbd() {
        return new Monad<>(Future.future());
    }

    public static  Monad fail(String msg) {
        return new Monad<>(Future.failedFuture(msg));
    }

    public static  Monad fail(Throwable t) {
        return new Monad<>(Future.failedFuture(t));
    }

    // ------- end Monad initializer -------

    // ------- start Monad transformer -------

    public static  Applicative app(Monad> monad) {
        return new Applicative<>(monad);
    }

    public static  Monad> flip(List> monadList) {
        Monad> m = tbd();
        boolean[] thrown = {false};
        Map map = new HashMap<>(monadList.size());

        //noinspection UnnecessaryLocalVariable
        Object lock = map; // randomly picked object as the lock

        for (int i = 0; i < monadList.size(); i++) {
            int x = i;
            Future fu = monadList.get(i);
            fu.setHandler(r -> {
                if (r.failed()) {
                    boolean doFail = false;
                    synchronized (lock) {
                        if (!thrown[0]) {
                            thrown[0] = true;
                            doFail = true;
                        }
                    }
                    if (doFail) {
                        m.fail(r.cause());
                    }
                    return;
                }

                boolean doComplete = false;

                synchronized (lock) {
                    if (thrown[0])
                        return;

                    map.put(x, r.result());
                    if (map.size() == monadList.size()) {
                        doComplete = true;
                    }
                }
                if (doComplete) {
                    MList ls = MList.modifiable();
                    for (int j = 0; j < monadList.size(); ++j) {
                        ls.add(map.get(j));
                    }
                    m.complete(ls.immutable());
                }
            });
        }
        return m;
    }

    // ------- end Monad transformer -------

    // ------- start flow control -------

    // break loop
    public static  Monad brk() {
        throw new Break();
    }

    // break loop with value
    public static  Monad brk(T result) {
        throw new Break(result);
    }

    // ------- end flow control -------

    // ------- start util -------

    // a common helper function
    public static  T value(T result, Runnable p) {
        p.run();
        return result;
    }

    public static  Monad runcb(Consumer>> func) {
        Monad m = tbd();
        Handler> cb = r -> {
            if (r.failed()) {
                m.fail(r.cause());
            } else {
                m.complete(r.result());
            }
        };
        func.accept(cb);
        return m;
    }

    // ------- end util -------
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy