|
From the article: length = foldr (+) 0 . map (const 1)
length2d = foldr (+) 0 . map length
-- and the proposed syntax the author calls more readable:
length = foldr((+), 0, $) . map(const(1), $)
length2d = foldr((+), 0, $) . map(length, $)
But I don't understand. Why does the author think it's confusing to partially apply foldr and map but not (+), (.), const, and length? Applied consistently: length = (.)(foldr((+)($, $), 0, $), map(const(1, $), $), $)
length2d = (.)(foldr((+)($, $), 0, $), map(length($), $), $)
And clearly no-one thinks this strawman is clearer. Further, it's impossible to make it 100% consistent: any function you write with polymorphic result could instantiate as a function needing more arguments. I think currying is the better default. |
Neither of these functions is being partially applied in the code you cited. While the placeholder $ can be used to indicate all "free slots" of a function, you would only have to use it in partial applications of that function. (Analogous to how in mathematics the abstract index notation for tensors[0] is only really useful when you start contracting tensors, etc. Otherwise, the plain objects/tensors without indices are much easier to write & read.)
Specifically:
- (+) was already a function of two arguments, so usage of $ is unnecessary since (+)($, $) == (+). Similarly with the length function (a function of 1 argument): length($) == length.
- Function composition was being used as a binary operator between two functions. You just replaced the infix notation with prefix notation.
- I read const(1) as the function that maps everything to 1. I.e. `const` is a function of one argument x, which returns a function that always returns x. Once again, no need to indicate slots there.
[0]: See https://en.wikipedia.org/wiki/Abstract_index_notation and https://math.stackexchange.com/questions/455478/what-is-the-...