f(x,y) = ... // arity 2
f = \x -> \y -> ... // sequence of two unary functions
f x y = ... // more compact representation of the above
Regarding partial application, your JS (?) example is basically what happens under the hood with Haskell, but without the ceremony: f x y = ...
fByThree = f 3
fByThree y = f 3 y
Those last two are equivalent, but you don't have to include the y parameter explicitly, because f 3 returns a function that expects another parameter (like the function you wrote out explicitly).And the Haskell version is more general, since it doesn't require a unique function to be written for each possible partial application. Of course, you can do this in languages with closures:
function fByX(x) {
return y => f(x,y);
}
fByThree = fByX(3);
But in Haskell that extra function isn't needed, it's just already there and called f. Regarding your last statement, there are also combinators in Haskell that allow you to do things like this: fXbyThree = flip f 3
// equivalent to:
fXByThree x = f x 3
// JS
function fXByThree(x) { return f(x,3); }
// or
function fXByFixedY(y) { return x => f(x,y); }
fXByThree = fXByFixedY(3);
So I'm not sure it's strictly superior, it is more explicit though.