Skip to content

Commit

Permalink
Implement applySpec
Browse files Browse the repository at this point in the history
Closes #1591
  • Loading branch information
asaf-romano committed Jan 14, 2016
1 parent 46bb0fb commit 7f49330
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 0 deletions.
40 changes: 40 additions & 0 deletions src/applySpec.js
@@ -0,0 +1,40 @@
var _curry1 = require('./internal/_curry1');
var curryN = require('./curryN');
var map = require('./map');
var max = require('./max');
var pluck = require('./pluck');
var reduce = require('./reduce');
var values = require('./values');


/**
* Given a spec object recursively mapping properties to functions, creates a
* function producing an object of the same structure, by mapping each property
* to the result of calling its associated function with the supplied arguments.
*
* @func
* @memberOf R
* @category Function
* @sig {k: ((a, b, ..., m) -> v)} -> ((a, b, ..., m) -> {k: v})
* @param {Object} spec an object recursively mapping properties to functions for
* producing the values for these properties.
* @return {Function} A function that returns an object of the same structure
* as `spec', with each property set to the value returned by calling its
* associated function with the supplied arguments.
* @example
*
* var getMetrics = R.applySpec({
* sum: R.add,
* nested: { mul: R.multiply }
* });
* getMetrics(2, 4); // => { sum: 6, nested: { mul: 8 } }
*/
module.exports = _curry1(function applySpec(spec) {
spec = map(function(v) { return typeof v == 'function' ? v : applySpec(v) },
spec);
return curryN(reduce(max, 0, pluck('length', values(spec))),
function() {
var args = arguments;
return map(function(f) { return f.apply(null, args); }, spec);
});
});
33 changes: 33 additions & 0 deletions test/applySpec.js
@@ -0,0 +1,33 @@
var R = require('..');
var eq = require('./shared/eq');


describe('applySpec', function() {

it('works with empty spec', function() {
eq(R.applySpec({})(), {});
});

it('works with unary functions', function() {
eq(R.applySpec({ v: R.inc, u: R.dec })(1), { v: 2, u: 0 });
});

it('works with binary functions', function() {
eq(R.applySpec({ sum: R.add })(1, 2), { sum: 3 });
});

it('works with nested specs', function() {
eq(R.applySpec({ unnested: R.always(0), nested: { sum: R.add } })(1, 2),
{ unnested: 0, nested: { sum: 3 } });
});

it('retains the highest arity', function() {
var f = R.applySpec({ f1: R.nAry(2, R.T), f2: R.nAry(5, R.T) });
eq(f.length, 5);
});

it('returns a curried function', function() {
eq(R.applySpec({ sum: R.add })(1)(2), { sum: 3 });
});

});

0 comments on commit 7f49330

Please sign in to comment.