I'm reading a functional programming tutorial called Professor Frisby's Mostly Adequate Guide to Functional Programming, the author gives an introduction to Hindley-Milner and several examples about it, one of them being:
// reduce :: (b -> a -> b) -> b -> [a] -> b
var reduce = curry(function(f, x, xs) {
return xs.reduce(f, x);
});
The first argument of reduce is a function, whose type signature is b -> a -> b, and that's the exact part that I don't understand. The above code is written in js, which means f should take two arguments and return one, like this:
function f(b, a) {
return b + a;
}
Thus the type signature of f should be (b, a) -> b instead of b -> a -> b, right? f shouldn't be a first order function(implied by b -> a -> b), at least not in js.
So my question is, is this an error of the tutorial? If so, what's the correct way to represent (b, a) -> b in Hindley-Milner?
Since
xsis annotated as[a], we can expect it to be a regular javascript array.Therefore, the
.reducecall inside thereducefunction can be assumed to beArray.prototype.reduce.This array method does not take a curried reducer function. So I would say: yes, the type annotation is wrong.
To fix it, either
// reduce :: ((b, a) -> b) -> b -> [a] -> b, like you suggested, orArray.prototype.reduce: