Skip to the code
cf.

Infinite curry sum

MediumFunctions

Write sum(...numbers). Called with one or more numbers, it returns a function that takes more numbers the same way. Called with no arguments, it returns the total of every number passed so far in the chain, and the chain ends.

A call can pass several numbers at once, so sum(1, 2)(3)() is also 6. sum() on its own returns 0.

A chain stopped partway can be reused: after const add5 = sum(5), add5(1)() and add5(10)() both work, and neither affects the other. Every new chain starts from 0.

sum(1)(2)(3)();    // 6
sum(1, 2)(3, 4)(); // 10
sum();             // 0
 
const add5 = sum(5);
add5(1)();         // 6
add5(10)();        // 15, not 16: add5 still adds to 5
add5();            // 5

What the tests check

  1. returns the total when called with no arguments
    expect(sum(1)(2)(3)()).toBe(6);
    expect(sum(5)()).toBe(5);
    
  2. returns a function while numbers keep coming
    expect(typeof sum(1)).toBe("function");
    expect(typeof sum(1)(2)).toBe("function");
    expect(typeof sum(1, 2)(3, 4)).toBe("function");
    
  3. adds every number passed in a call
    expect(sum(1, 2)(3, 4)()).toBe(10);
    expect(sum(1, 2, 3)()).toBe(6);
    expect(sum(1)(2, 3, 4)()).toBe(10);
    
  4. sum() on its own returns 0
    expect(sum()).toBe(0);
    
  5. zero and negative numbers don't end the chain
    expect(sum(0)(5)()).toBe(5);
    expect(sum(2)(-2)(3)()).toBe(3);
    expect(sum(-2)(2)(0)()).toBe(0);
    
  6. a partial chain can be reused
    const add5 = sum(5);
    expect(add5(1)()).toBe(6);
    expect(add5(10)()).toBe(15);
    expect(add5()).toBe(5);
    
  7. branches of one chain don't affect each other
    const three = sum(1)(2);
    const six = three(3);
    const thirteen = three(10);
    expect(six()).toBe(6);
    expect(thirteen()).toBe(13);
    expect(three()).toBe(3);
    expect(six(1)()).toBe(7);
    expect(six()).toBe(6);
    
  8. each new chain starts from 0
    expect(sum(1)(2)()).toBe(3);
    expect(sum(4)()).toBe(4);
    expect(sum(10)(20)()).toBe(30);
    

Learn more

solution.jsSaved in this browser

Run tests runs every test on your code, here in your browser. The problem is solved when they all pass.

Ctrl + Enter runs the tests (⌘ + Enter on a Mac).