class Main { static function main() { getAnswer().next(v -> switch v { case 42: 'Perfect!'; case 40, 41, 43, 44: 'Close enough!'; default: new NotError(); }).handle(o -> trace(Std.string(o))); } static function getAnswer():Promise return 3 + 39; } class NotError { public function new() {} } abstract Promise((handler:(result:Outcome) -> Void) -> Void) { inline function new(f) this = f; public function next(transform:Next):Promise return new Promise(handler -> this(o -> switch o { case Success(v): transform(v).handle(handler); case Failure(e): handler(Failure(e)); })); @:from static function ofOutcome(o:Outcome):Promise return new Promise(h -> h(o)); @:from static function ofValue(v:T):Promise return ofOutcome(Success(v)); @:from static function ofError(e:NotError):Promise return ofOutcome(Failure(e)); public function handle(cb) this(cb); } @:callable abstract Next(In->Promise) from In->Promise { @:from(ignoredByInference) static function ofSync(f:In->Out):Next return v -> (f(v) : Promise); } enum Outcome { Success(data:T); Failure(error:E); }