rpominov/fun-task

toPromise method

rpominov opened this issue · 4 comments

I think this method will run the task and give us a promise that represents the result.

Also we need fromPromise probably.

There are more than way how this methods can work actually. Here is the questions we need to answer:

toPromise

  1. Should Task's failure value go into Promise's failure path? There is a difference in semantics of failure path in Task in Promise. Task basically models Async+Either while in Promises failure path is used for uncaught exceptions and it's reasonable to use it only for uncaught exceptions / bugs. So maybe toPromise should return Promise<{success: S} | {failure: F}> (rel. #13 ). This way we also won't loose type info btw (rel. facebook/flow#1232).
  2. Should we run task with {catch} handler when converting to promise? I don't really have preference either way here, also we could add an option for it toPromise({catch: true}). But if we catch we'll have to put errors into Promise's failure path (there no other options) which is another reason to do {success: S} | {failure: F} thing in #1.

Actually just writing this down helped me realize that {success: S} | {failure: F} is a good idea.

fromPromise

  1. Should we provide failure callback to promise? I've figured out answer while was writing this, but still want to document it. So I think the nice solution is to use our {catch} handler for Promise's failure path. If catch provided we provide failure callback to promise and put Promise's error into our catch path.

So we have following correspondence between Task and Promise callbacks:

Task           Promise

success --┬--- success
failure --╯       
catch -------- catch

This is explained in https://github.com/rpominov/fun-task/blob/master/docs/exceptions.md

Given that correspondence it's natural that toPromise returns Promise<{success: S} | {failure: F}> and fromPromise connects success branch from promise with task's success and catch from promise with task's catch.

I'm doing it this way.

There is a problem with Flow though facebook/flow#2354

src/index.js:201
201:   toPromise(): Promise<{success: S} | {failure: F}> {
                                      ^ S. invariant position (expected `S` to occur only covariantly)

src/index.js:201
201:   toPromise(): Promise<{success: S} | {failure: F}> {
                                                     ^ F. invariant position (expected `F` to occur only covariantly)