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

Add support for Do - bind Result syntax #63

Closed josher8a closed 1 year ago

josher8a commented 1 year ago

Awesome job! I've been using your library for a while and was wondering if you see it possible to add a Do-bind syntax to be able to chain without so much verbosity.

I've sketched my utility for the Results, but this can be extended to Options and Async Result

export const Do = <T, E = Error>(value?: T) => R.makeOk<NonNullable<T> | {}, E>(value ?? {})
export const bind =
    <K extends string ,T, U, E>(key: K, fn: (value: T) => R.Result<U, E>) =>
    (prev: R.Result<T, E>) =>
        R.flatMap(prev, value => R.map(fn(value), result => D.set(value, key, result)))

export const bindTo = <K extends string ,T, E>(key: K) => (prev: R.Result<T, E>)  => R.map<T,E,Record<K, T>>(prev,value => D.fromPairs([[key, value]]))

With this, we can improve readability

const before = pipe(
    resultFn1(x),
    R.flatMap(prev =>
        R.map(resultFn2(y), current => ({
            ['meningFullKey2']: current,
            ['meningFullKey1']: prev,
        })),
    ),
    R.flatMap(prev =>
        R.map(resultFn3(z), current => ({
            ['meningFullKey3']: current,
            ...prev,
        })),
    ),
    R.flatMap(prev =>
        R.map(resultFn3(prev.meningFullKey3, prev.meningFullKey1), current => ({
            ['meningFullKey4']: current,
            ...prev,
        })),
    ),
    // ...
)

const after = pipe(
    R.do(),
    R.bind('meningFullKey1', () => resultFn1(x)),
    R.bind('meningFullKey2', () => resultFn2(y)),
    R.bind('meningFullKey3', () => resultFn3(z)),
    R.bind('meningFullKey4', ({ meningFullKey3, meningFullKey1 }) => resultFn3(meningFullKey3, meningFullKey1)),
    // ...
)
mobily commented 1 year ago

@josher8a I fully understand the idea, and thanks for the suggestion! however, if you can easily compose do/bind using current functions, then there's no reason for adding them to ts-belt at this point, sorry!