fp-ts
                                
                                 fp-ts copied to clipboard
                                
                                    fp-ts copied to clipboard
                            
                            
                            
                        Change zipWith signature
The order of the arguments of zipWith is wrong if you want to compose new functions. for example if i want to compose a 2d array zipper: const zip2d = (xs, ys) => zipWith(xs, ys, zip)
If the function for is first, then it could look like: const zip2d = zipWith(zip)
Also more in line with haskell: https://hackage.haskell.org/package/base-4.17.0.0/docs/Prelude.html#v:zipWith
Current Behavior
Current signature: export declare const zipWith: <A, B, C>(fa: A[], fb: B[], f: (a: A, b: B) => C) => C[]
Desired Behavior
Desired signatute: export declare const zipWith: <A, B, C>( f: (a: A, b: B) => C) => (fa: A[], fb: B[]) => C[]
A pipeable signature is:
export declare const zipWith: <A, B, C>(fb: B[], f: (a: A, b: B) => C) => (fa: A[]) => C[]
that will be in V3
@mikearnaldi Could we flip and curry fb and f there, matching Haskell? I don't think there's ever a case where non-unary functions are advantageous.
@mikearnaldi Could we flip and curry
fbandfthere, matching Haskell? I don't think there's ever a case where non-unary functions are advantageous.
Inference would be seriously compromised, TypeScript is very different from Haskell and in TS non-unary functions are extremely useful. Flipping fb won't allow inference of B.
In fp-ts the pipe function is not function composition, it is a simulation of methods, the above will work as:
pipe([0, 1, 2], zipWith([3, 4, 5], (a, b) => a + b))
and can be piped with any other function of the module.
Inference would be seriously compromised, TypeScript is very different from Haskell and in TS non-unary functions are extremely useful. Flipping
fbwon't allow inference ofB.
Ah. So I find in practice that anonymous functions are rarely used. Simple stuff like that already exists in userland as a readable function (fp-ts-std add in that case), and anything much more complex should be extracted outside of the pipeline. And you can always fall back to explicit annotations.
On the other hand I often want to partially apply these types of functions, which currying enables:
import { add } from 'fp-ts-std/Number'
declare const zipWith: <A, B, C>(f: (a: A) => (b: B) => C) => (fa: A[]) => (fb: B[]) => C[]
pipe([0, 1, 2], zipWith(add)([3, 4, 5]))
const zipAdd = zipWith(add)
pipe([0, 1, 2], zipAdd([3, 4, 5]))
Inference would be seriously compromised, TypeScript is very different from Haskell and in TS non-unary functions are extremely useful. Flipping
fbwon't allow inference ofB.Ah. So I find in practice that anonymous functions are rarely used. Simple stuff like that already exists in userland as a readable function (fp-ts-std
addin that case), and anything much more complex should be extracted outside of the pipeline. And you can always fall back to explicit annotations.On the other hand I often want to partially apply these types of functions, which currying enables:
import { add } from 'fp-ts-std/Number' declare const zipWith: <A, B, C>(f: (a: A) => (b: B) => C) => (fa: A[]) => (fb: B[]) => C[] pipe([0, 1, 2], zipWith(add)([3, 4, 5])) const zipAdd = zipWith(add) pipe([0, 1, 2], zipAdd([3, 4, 5]))
We must look at very different codebases, I find that in practice 99% of usage is directly with anonymous functions.