Search code examples
typescriptfunctional-programmingnaming-conventionsnaming

What would you call a function that takes T<A>[] as input and outputs T<A[]>?


Some examples

const f = <L, R>(xs: Either<L, R>[]): Either<L, R[]> => { throw new Error('Not Implemented') };
const f = <T>(xs: Promise<T>[]): Promise<T[]> => { throw new Error('Not Implemented') };
const f = <T>(xs: Box<T>[]): Box<T[]> => { throw new Error('Not Implemented') };

These all perform some sort of reducing. However, the semigroup here is just a List.

From a readability point of view, what would be some good names for such functions.

There is obviously some degree of subjectivity here, which is discouraged by SO. However, I feel it is also possible to say that a name is bad or good with some objective criteria/rationale.

maybe alone the line of collect or gather?


Solution

  • TypeScript isn't Haskell, but that's where I usually go to see if there's already a well-known name for the type of thing I'm creating.

    Assuming that Either<L, T>, Promise<T>, and Box<T> are all applicative functors over T, then the function signatures <L,T>(x: Array<Either<L, T>>) => Either<L, Array<T>>, <T>(x: Array<Promise<T>>) => Promise<Array<T>>, and <T>(x: Array<Box<T>>) => Box<Array<T>> would probably be called sequence.

    A sketch of the rules for what makes a type function F<T> applicative functor over T: you need to have some functions that act like this:

    declare function pure<T>(x: T): F<T>;
    declare function lift2<A, B, T>(cb: (a: A, b: B) => T): (fa: F<A>, fb: F<B>) => F<T>;
    

    And then sequence could be implemented like this:

    function sequence<T>(x: Array<F<T>>): F<Array<T>> {
        return x.reduce(lift2<T[], T, T[]>((xs, x) => xs.concat(x)), pure([]))
    }
    

    For Promise<T> that's fairly straightforward:

    function pure<T>(x: T): Promise<T> {
        return Promise.resolve(x);
    }
    function lift2<A, B, T>(cb: (a: A, b: B) => T): (fa: Promise<A>, fb: Promise<B>) => Promise<T> {
        return (fa: Promise<A>, fb: Promise<B>) => fa.then(a => fb.then(b => cb(a, b)))
    }
    

    and you could presumably come up with ones for Either<L, T> and Box<T> too.

    Okay, hope that helps; good luck!

    Link to code