Implement sum, a curried adder that accepts numbers one call at a time and returns the running total when invoked with no arguments. This is the same family as classic currying, but with a twist: the chain has no fixed length. The wrapper keeps handing back a new function on every numeric call and only "settles" — produces a number — when you call it with (). The empty call is the terminator: a sentinel that means "no more numbers, give me the total."
Unlike curry(fn), there is no fn.length to drive the stopping decision. The caller decides when the chain ends, and the chain stays open for as long as numbers keep arriving. Your job is to keep the running total in a closure and react to the terminator.
// sum(1)(2)(3)() === 6
function sum(n?: number): number | ((next?: number) => number | Function);
// numeric call: returns another sum-shaped function
// empty call (): returns the running total as a number
// Basic chain — three numeric calls, then the terminator.
sum(1)(2)(3)(); // 6
sum(10)(20)(30)(); // 60
// Terminator returns the running total at the point you call it.
sum(5)(); // 5 — total after one number
sum(1)(2)(); // 3 — total after two numbers
// Immediate terminator. No numbers, no total — return 0.
sum(); // 0
() with zero arguments tells the chain to stop and return the running total. Until that call arrives, every step returns a new function.curry(fn), you do not know how many numbers will arrive. Don't try to count down from fn.length; let the terminator decide.sum() with no first argument returns 0. The terminator can fire on the very first call when there are no numbers to add.typeof sum(1) is 'function', and so is typeof sum(1)(2). Only the empty call produces a number.sum(1)(2) and then sum(1)(2) again must give the same total each time — no state should leak between separate chains.+ accumulator; treat all numeric inputs the same.