What if you want to write a library that works with either blocking calls or asynchronous promises?
The cohttp HTTP library is written that way. For example, the Transfer_io module[1] (supporting both chunking and non-chunking HTTP transfers) takes as an argument another module, IO[2], that provides a read_line function of type "ic -> string option t", where the type t is abstract and higher-kinded (and "ic" = input channel). You can instantiate the module with a blocking IO module (where a "string t" is just the same as a "string" and read_line blocks) or with a non-blocking one (where a "string t" is a promise for a "t" and read_line returns a promise).
[1] https://github.com/mirage/ocaml-cohttp/blob/master/lib/trans...
[2] https://github.com/mirage/ocaml-cohttp/blob/master/lib/s.mli
(also useful if your language has multiple competing promise libraries...)