Search code examples
javascriptfunctional-programminglodashflowtype

What is the flow type for a zipAll function, such as in lodash/fp?


Even in normal lodash, zip's type is declared using overloads, like:

zip<A, B>(a1: A[], a2: B[]): Array<[A, B]>;
zip<A, B, C>(a1: A[], a2: B[], a3: C[]): Array<[A, B, C]>;
zip<A, B, C, D>(a1: A[], a2: B[], a3: C[], a4: D[]): Array<[A, B, C, D]>;
zip<A, B, C, D, E>(a1: A[], a2: B[], a3: C[], a4: D[], a5: E[]): Array<[A, B, C, D, E]>;

The first line of this satisfies zip from lodash/fp, but what about zipAll? This function is supposed to take a second order array and basically transpose it.

It would look like this for the above limited cases:

zipAll<A, B>([A[], B[]]): Array<[A, B]>;
zipAll<A, B, C>([A[], B[], C[]]): Array<[A, B, C]>;
zipAll<A, B, C, D>([A[], B[], C[], D[]]): Array<[A, B, C, D]>;
zipAll<A, B, C, D, E>([A[], B[], C[], D[], E[]]): Array<[A, B, C, D, E]>;

Is there no way to define it generally?


Solution

  • This isn't much of an answer, but: no there isn't. This would require some sort of meta-programming layer.

    You can see very similar patterns applied in other languages, for example Haskell. Even though Haskell's type system can be considered more sophisticated, it doesn't have overloads, and zip is implemented for different sized tuples using new names: zip, zip3, zip4 etc. In general, Haskell's Prelude stops at 7 arguments when defining these types of thing, since the code generally becomes unreadable by that point anyway.