
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 extends Function> 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