monads icon indicating copy to clipboard operation
monads copied to clipboard

handling async results

Open paduc opened this issue 4 years ago • 5 comments

Hi,

A lot of my methods return a Promise<Result<T,K>> because they handle async behaviour (writing to the database for instance).

I would love to be able to chain these methods with and_then but the latter only accepts methods that return a Result<T,K>.

Example:

const user = makeUser({ name, email }).and_then(userDB.insert);

// where userDB.insert = (user) => Promise<Result<User, Error>>

Is this possible currently or does this require additional work ? I'm willing to help if I can.

Cheers

paduc avatar Mar 24 '20 18:03 paduc

It requires work but let me look into it!

slavovojacek avatar Apr 24 '20 01:04 slavovojacek

It is also actual for my case. It will be better to have the possibility to handle the async methods with chained construction. Thanks

dmitrykologrivko avatar Jun 18 '20 11:06 dmitrykologrivko

You can see how superthrow implements it in their ResultAsync type.

paduc avatar Jun 18 '20 12:06 paduc

It's an interesting one, because in a way you could also just use Promise as if it was a Result. The only thing you're losing is the error type (e.g. Promise<T> vs Result<T, E>), but in the context of Promises the errors would ideally always be instanceof Error.

What I am trying to say is that you could simply do...

const validateParams = async (params): Promise<UserAttributes> => {
  ...
}

const insertUser = async (attrs: UserAttributes): Promise<User> => {
  const { id, firstName, lastName, insertedAt } = await db.insert(attrs)
  return { id, firstName, lastName, insertedAt }
}

const user = validateParams(params).then(insertUser)

...which would be conceptually equivalent to Result<T, E>.andThen(...).

However, if there is a use-case where Result<T, E> is absolutely necessary, please let me know! :)

slavovojacek avatar Jun 18 '20 12:06 slavovojacek

@slavovojacek From my point of view, the only advantage of Result is that errors are typed. If you don't care about the error type, you can do everything with plain vars and promises.

Also, with a ResultAsync type, you can guarantee your caller that your method will never throw...

paduc avatar Jun 18 '20 13:06 paduc