Here’s another thing I didn’t know you could do, the Eff monad:
function main(){
final c : Eff<HasOne,Bool> = new Eff(() -> true);
final d : Eff<HasTwo,Float> = new Eff(() -> 99.9);
final e = c.then(
(x) -> {
return d;
}
);
$type(e);
}
typedef HasOne = {
var one : Int;
}
typedef HasTwo = {
var two : String;
}
class Eff<EA:{}, A> {
public final run: () -> A;
public function new(run: () -> A) {
this.run = run;
}
public function map<B>(f: (_: A) -> B): Eff<EA, B> {
return new Eff(() -> f(this.run()));
}
public function then<EB:{}, B,Z : EB & EA >(f: (_: A) -> Eff<EB, B>): Eff<Z, B> {
return Eff.join(this.map(f));
}
static public function join<Z:EA & EB,EA:{},EB:{},B>(x: Eff<EB, Eff<EA, B>>): Eff<Z, B> {
return new Eff(() -> x.run().run());
}
}
yields:
