DEV Community

Discussion on: Daily Challenge #123 - Curry me Softly

Collapse
 
vonheikemen profile image
Heiker • Edited

I don't know what's going on with those weird curryAdder calls.

curryAdder(1);
curryAdder(1,2,3);
curryAdder(2)(2,5);
var example = curryAdder(); // 16

It doesn't look like normal currying to me. You're not using the returned curried function (if there is one).

Anyway. Here is mine. Don't judge me.

function curry(fn, arity) {
  if (arguments.length === 1) {
    // you won't tell me? Fine, I'll guess.
    arity = fn.length;

    if(arity === 0) {
      // you are a sneaky one.
      // you trying to curry a variadic function?
      // hope you know what you're doing.
      return curry.bind(null, fn, {last: 0});
    }
  }

  // Gather the relevant arguments.
  var rest = Array.prototype.slice.call(arguments, 2);

  var arity_satisfied = arity <= rest.length;

  // for that edge case. If it is the same you didn't add new arguments.
  var called_without arguments = arity.last === rest.length;

  if (arity_satisfied || called_without arguments){
    return fn.apply(fn, rest);
  }

  if(typeof arity.last == 'number') {
    // state. Remember the arguments count.
    arity.last = rest.length;
  }

  // you can blame `bind` for not taken an array.
  var args = [null, fn, arity].concat(rest);

  // call `bind` with `args` and give me a function.
  return curry.bind.apply(curry, args);
}

Oh and the test. The test was fun. Did you know that the assert module on node had a strict mode? I didn't.

// this is done with mocha
// mocha --ui qunit -r esm test/**/*.test.js

import { strict as t } from 'assert';
import { curry } from '../../src/utils';

suite('# curry');

test('variadic function without arguments list', function() {
  function add () {
    return [].slice.call(arguments).reduce(function(a,b){
      return a + b
    },0);
  }

  let curried = curry(add);
  t.equal(typeof curried, 'function', 'curried is a function');

  let curried_1 = curried(1)(1,2,3)(2)(2,5);
  t.equal(typeof curried_1, 'function', 'still currying');

  t.equal(curried_1(), 16, 'stops when no argument is supplied');
});