mobily / ts-belt

🔧 Fast, modern, and practical utility library for FP in TypeScript.
https://mobily.github.io/ts-belt
MIT License
1.1k stars 30 forks source link

Try/catch utility? (feature request) #26

Closed Darkle closed 2 years ago

Darkle commented 2 years ago

Hi, previous to ts-belt I had been using the pratica library which had this really neat try/catch utility called encase that was particularly handy for JSON parsing. It'd be cool if ts-belt had something like that too. 😎

mobily commented 2 years ago

@Darkle this is an excellent idea! but here's the thing, I'm wondering what type the tryCatch function should return? I see two options:

  1. the first option is straightforward, we add tryCatch to the F namespace (so it is F.tryCatch), and it always returns the Result data type
export declare function tryCatch<A, B>(
  value: A,
  fn: (value: A) => B,
): Result<B, string>

usage:

type Obj = {
  readonly hello: string,
}

const x = pipe(
  '{"hello": "world"}',
  F.tryCatch<string, Obj>(JSON.parse), // → Ok({ hello: 'world' })
  R.map(obj => obj.hello),
  R.getWithDefault(''),
) // → 'world'

const y = pipe(
  '<>',
  F.tryCatch<string, Obj>(JSON.parse), // → Error('Unexpected token < in JSON at position 0')
  R.map(obj => obj.hello),
  R.getWithDefault('oops'), 
) // → 'oops'

the upside of this option is that having a single tryCatch function might be less confusing for users, and the F namespace is a perfect place for that kind of function, the downside tho might be mapping to the Option data type with R.toOption if someone needs Option instead of Result ¯_(ツ)_/¯

  1. alternatively, we could add tryCatch to both namespaces: Option and Result, so we had O.tryCatch and R.tryCatch eventually
// R namespace
export declare function tryCatch<A, B>(
  value: A,
  fn: (value: A) => B,
): Result<B, string>

// O namespace
export declare function tryCatch<A, B>(
  value: A,
  fn: (value: A) => B,
): Option<B>

what are your thoughts on this topic?

Darkle commented 2 years ago

I think 1 is the better choice. But it would probably be good to remind people in the docs for tryCatch that they can convert the Result to an Option with R.toOption.

mobily commented 2 years ago

sounds reasonable! I already have an initial implementation, so it will be published in v3.10.0 this week 🚀

mobily commented 2 years ago

@Darkle published in v3.10.0

thelinuxlich commented 2 years ago

This won't handle promises/async right?