function _curryN(length, received, fn) {
    return function () {
      var combined = [];
      var argsIdx = 0;
      var left = length;
      var combinedIdx = 0;
      var hasPlaceholder = false;
      while (combinedIdx < received.length || argsIdx < arguments.length) {
        var result;
        if (combinedIdx < received.length && (!_isPlaceholder(received[combinedIdx]) || argsIdx >= arguments.length)) {
          result = received[combinedIdx];
        } else {
          result = arguments[argsIdx];
          argsIdx += 1;
        }
        combined[combinedIdx] = result;
        if (!_isPlaceholder(result)) {
          left -= 1;
        } else {
          hasPlaceholder = true;
        }
        combinedIdx += 1;
      }
      return !hasPlaceholder && left <= 0 ? fn.apply(this, combined) : _arity(Math.max(0, left), _curryN(length, combined, fn));
    };
  }
Internal curryN function.

@private
@category Function
@param {Number} length The arity of the curried function.
@param {Array} received An array of arguments received thus far.
@param {Function} fn The function to curry.
@return {Function} The curried function.