fun-task icon indicating copy to clipboard operation
fun-task copied to clipboard

toEither method

Open rpominov opened this issue 8 years ago • 2 comments

It would turn Task<S, F> into Task<{success: S} | {failure: F}, any>*.

* Would be cool to use empty instead of any here, but Flow doesn't support it yet: https://github.com/facebook/flow/issues/2225

I've already run into two cases where it could be useful:

In Task.do.

Task.do(function* () {
  const {success, failure} = yield doStuff().toEither()
  // ...
})

In combination with toPromise (task.toEither().toPromise()) because Promise's error path isn't really good to use for expected failures, it's better to reserve it only for uncaught exceptions / bugs (update: or we probably should do it automatically in toPromise https://github.com/rpominov/fun-task/issues/4#issuecomment-240075160).

The name

I'm not a fun of toEither name, would appreciate a help here. Other names I've considered so far:

  • join — it's better to reserve this name for monadic join (chain(x => x))
  • reduce — conflicts with Fantasy Land's Foldable

Also both join and reduce not very intuitive i.e., bad names either way.

The idea of toEither is that {success: S} | {failure: F} basically poor man's Either so in other words we transform Task<S, F> into Task<Either<S, F>, empty>. The problems are: 1) this explanation is required to understand the name, 2) strictly speaking the name should be toTaksOfEither.

rpominov avatar Aug 16 '16 11:08 rpominov

Fluture provides fold, leaving the decision of what to fold into to the user. They can choose to use S.Either, or their own poor-mans either-like structure or something else:

const toEither = Future.fold(failure => ({failure}), success => ({success}));
Future.do(function*() {
  const {failure, success} = yield toEither(doStuff());
})

I think providing the toEither function would be treading on user territory. Your making a decision for them about which structure they should use to handle failure. Then again, I do see some sense in having a standard way to convert to Promise without losing type info. Since this type info is not kept in Fluture to begin with (errors are thrown outwards), I haven't run into this problem.

Avaq avatar Aug 16 '16 12:08 Avaq

Yea, I was looking at how it's done in Fluture, and had the exact same thoughts.

I agree that we're treading on user territory. But on the other hand people are free not to use this, and use their own helpers.

And I've also considered to accept callbacks, so people could use arbitrary Either type. But it's more code to write with callbacks. We can also do both: accept callbacks but make them optional.

So yeah, still thinking what is the best way to go here. Also in toPromise I think we should do it automatically, so that leaves only do use-case for this method therefore maybe we don't need toEither after all.

fold is an option for the name, btw! Thanks for reminder.

rpominov avatar Aug 16 '16 13:08 rpominov