crazy4groovy
7/13/2017 - 1:28 PM

Functional JS utils

Functional JS utils

/**
 * Retrieve the values of an object's properties
 * @module 101/values
 */
'use strict';

module.exports = values;

/**
 * Borrowing from underscorejs
 * https://github.com/jashkenas/underscore
 * @param {Object} obj
 * @return {Array}
 */
function values (obj) {
  var keys = Object.keys(obj);
  var length = keys.length;
  var vals = new Array(length);
  for (var i = 0; i < length; i++) {
    vals[i] = obj[keys[i]];
  }
  return vals;
}
/**
 * @module 101/curry
 */
 
var slice = Array.prototype.slice;

/**
 * Returns a curried function
 * @function module:101/curry
 * @param {function} f - function to be curried
 * @param {integer} [n] - how many arguments to curry
 * @return {function} 
 */
module.exports = curry;

function curry(f, n) {
  var length = n || f.length;
  return _curry(f, length, []);
}

function _curry(f, n, args) {
  return function(/* args */) {
    var curryArgs = args.concat(slice.call(arguments));
    if (curryArgs.length >= n) {
      return f.apply(null, curryArgs.slice(0, n));
    } else {
      return _curry(f, n, curryArgs);
    }
  };
}
/**
 * @module 101/converge
 */

/**
 * Converges an array of functions into one
 * @function module:101/converge
 * @param {function} f
 * @param {Array} array of functions
 * @return {function}
 */
module.exports = converge;

function converge(f, funcs) {
  return function converged(/* args */) {
    var args = Array.prototype.slice.call(arguments);
    return f.apply(null, funcs.map(function(g) {
      return g.apply(null, args);
    }));
  };
}
/**
 * @module 101/compose
 */

/**
 * [compose description]
 * @function module:101/compose
 * @param {function} f
 * @param {function} g
 * @return {function} 
 */
module.exports = compose;
 
function compose(f,g) {
  return function composed(/* args */) { 
    var args = Array.prototype.slice.call(arguments);
    return f(g.apply(null, args));
  } 
}