It's possible to do the Eff Monad in Haxe

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: