class Error {} enum Outcome { Success(data:Data); Failure(failure:Failure); } interface Future { function map(f:T->A):Future; } typedef Surprise = Future>; abstract Promise(Surprise) from Surprise to Surprise { public inline function map(f:Outcome->R):Future return this.map(f); @:from static inline function ofError(e:Error):Promise return throw 1; } abstract Stream(StreamObject) from StreamObject to StreamObject { public var depleted(get, never):Bool; inline function get_depleted() return this.depleted; @:to function dirty():Stream throw 1; @:from static public function flatten(f:Future>):Stream throw 1; @:from static public function promise(f:Promise>):Stream { return flatten(f.map(function(o) return switch o { case Success(s): s.dirty(); case Failure(e): throw 1; })); } } interface StreamObject { var depleted(get, never):Bool; }