Infinite Curried Sum
Write sum(n) so it can be called any number of times in a chain, each call adding to a running total.
The total appears when the result is converted to a primitive — by +, by String(), or inside a template literal. Two separate chains must not share a total.
Examples
+sum(1)(2)(3)6Constraints
- Every argument is a number
- Chains can be arbitrarily long
Notes
- Unlike a fixed-arity curry, nothing tells the function when the chain has ended — coercion is the only signal.
- A function is an object, and objects choose how they coerce.
Hints
Infinite Curried Sum (reference solution)
One way to do it. The Editorial tab walks through why it is written this way.
Solution
1function sum(first) {
2 let total = first;
3 const next = (value) => { total += value; return next; };
4 next.valueOf = () => total;
5 next.toString = () => String(total);
6 return next;
7}Editorial: Infinite Curried Sum
Currying with no arity to stop at
A normal curry knows when to stop: it compares collected arguments against fn.length. An infinite chain has no such signal. Nothing in sum(1)(2)(3) says the chain has ended.
Approach
The answer is that the chain never ends — it just gets asked for a value. Each call returns the same function with a larger total, and coercion is what finally reads it.
Implementation
function sum(first) { let total = first; const next = (value) => { total += value; return next; }; next.valueOf = () => total; next.toString = () => String(total); return next; }
Worth knowing
valueOf handles numeric contexts (+sum(1)(2), arithmetic) and toString handles string ones (template literals, String()). Define only one and the other falls back to "[object Object]", which is exactly the bug the reported candidate hit.
Keeping total inside the outer sum call rather than in module scope is what stops two chains sharing a total — a shared accumulator means the second sum(...) continues the first.