diff --git a/Makefile b/Makefile index 57d2b042..ca363f95 100644 --- a/Makefile +++ b/Makefile @@ -54,6 +54,10 @@ $(VERSION)/style.css: $(LESS_FILES) mkdir -p '$(@D)' $(LESS) less/ramda.less >'$@' +docs/%: $(VERSION)/docs/% + mkdir -p '$(@D)' + cp '$<' '$@' + .PHONY: index.html index.html: check-version echo '' >'$@' diff --git a/docs/dist/ramda.js b/docs/dist/ramda.js index 89a3edf9..b176f723 100644 --- a/docs/dist/ramda.js +++ b/docs/dist/ramda.js @@ -1,4 +1,4 @@ -// Ramda v0.17.1 +// Ramda v0.18.0 // https://github.com/ramda/ramda // (c) 2013-2015 Scott Sauyet, Michael Hurley, and David Chambers // Ramda may be freely distributed under the MIT license. @@ -25,6 +25,7 @@ * * @constant * @memberOf R + * @since v0.6.0 * @category Function * @example * @@ -86,6 +87,15 @@ } }; + var _arrayFromIterator = function _arrayFromIterator(iter) { + var list = []; + var next; + while (!(next = iter.next()).done) { + list.push(next.value); + } + return list; + }; + var _cloneRegExp = function _cloneRegExp(pattern) { return new RegExp(pattern.source, (pattern.global ? 'g' : '') + (pattern.ignoreCase ? 'i' : '') + (pattern.multiline ? 'm' : '') + (pattern.sticky ? 'y' : '') + (pattern.unicode ? 'u' : '')); }; @@ -139,7 +149,7 @@ }; /** - * Optimized internal two-arity curry function. + * Optimized internal one-arity curry function. * * @private * @category Function @@ -330,6 +340,15 @@ return x; }; + var _isArguments = function () { + var toString = Object.prototype.toString; + return toString.call(arguments) === '[object Arguments]' ? function _isArguments(x) { + return toString.call(x) === '[object Arguments]'; + } : function _isArguments(x) { + return _has('callee', x); + }; + }(); + /** * Tests whether or not an object is an array. * @@ -362,6 +381,14 @@ return Object.prototype.toString.call(x) === '[object Number]'; }; + var _isObject = function _isObject(x) { + return Object.prototype.toString.call(x) === '[object Object]'; + }; + + var _isRegExp = function _isRegExp(x) { + return Object.prototype.toString.call(x) === '[object RegExp]'; + }; + var _isString = function _isString(x) { return Object.prototype.toString.call(x) === '[object String]'; }; @@ -370,15 +397,21 @@ return typeof obj['@@transducer/step'] === 'function'; }; - var _map = function _map(fn, list) { - var idx = 0, len = list.length, result = Array(len); + var _map = function _map(fn, functor) { + var idx = 0; + var len = functor.length; + var result = Array(len); while (idx < len) { - result[idx] = fn(list[idx]); + result[idx] = fn(functor[idx]); idx += 1; } return result; }; + var _of = function _of(x) { + return [x]; + }; + var _pipe = function _pipe(f, g) { return function () { return g.call(this, f.apply(this, arguments)); @@ -394,8 +427,11 @@ }; }; + // \b matches word boundary; [\b] matches backspace var _quote = function _quote(s) { - return '"' + s.replace(/"/g, '\\"') + '"'; + var escaped = s.replace(/\\/g, '\\\\').replace(/[\b]/g, '\\b') // \b matches word boundary; [\b] matches backspace + .replace(/\f/g, '\\f').replace(/\n/g, '\\n').replace(/\r/g, '\\r').replace(/\t/g, '\\t').replace(/\v/g, '\\v').replace(/\0/g, '\\0'); + return '"' + escaped.replace(/"/g, '\\"') + '"'; }; var _reduced = function _reduced(x) { @@ -674,6 +710,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Math * @sig Number -> Number -> Number * @param {Number} a @@ -697,6 +734,7 @@ * * @func * @memberOf R + * @since v0.14.0 * @category List * @sig (a -> a) -> Number -> [a] -> [a] * @param {Function} fn The function to apply. @@ -731,6 +769,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Function * @sig a -> (* -> a) * @param {*} val The value to wrap in a function @@ -747,31 +786,26 @@ }); /** - * Returns a new list, composed of n-tuples of consecutive elements - * If `n` is greater than the length of the list, an empty list is returned. + * Returns `true` if both arguments are `true`; `false` otherwise. * * @func * @memberOf R - * @category List - * @sig Number -> [a] -> [[a]] - * @param {Number} n The size of the tuples to create - * @param {Array} list The list to split into `n`-tuples - * @return {Array} The new list. + * @since v0.1.0 + * @category Logic + * @sig * -> * -> * + * @param {Boolean} a A boolean value + * @param {Boolean} b A boolean value + * @return {Boolean} `true` if both arguments are `true`, `false` otherwise + * @see R.both * @example * - * R.aperture(2, [1, 2, 3, 4, 5]); //=> [[1, 2], [2, 3], [3, 4], [4, 5]] - * R.aperture(3, [1, 2, 3, 4, 5]); //=> [[1, 2, 3], [2, 3, 4], [3, 4, 5]] - * R.aperture(7, [1, 2, 3, 4, 5]); //=> [] + * R.and(true, true); //=> true + * R.and(true, false); //=> false + * R.and(false, true); //=> false + * R.and(false, false); //=> false */ - var aperture = _curry2(function aperture(n, list) { - var idx = 0; - var limit = list.length - (n - 1); - var acc = new Array(limit >= 0 ? limit : 0); - while (idx < limit) { - acc[idx] = _slice(list, idx, idx + n); - idx += 1; - } - return acc; + var and = _curry2(function and(a, b) { + return a && b; }); /** @@ -780,6 +814,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category List * @sig a -> [a] -> [a] * @param {*} el The element to add to the end of the new list. @@ -804,6 +839,7 @@ * * @func * @memberOf R + * @since v0.7.0 * @category Function * @sig (*... -> a) -> [*] -> a * @param {Function} fn @@ -827,6 +863,7 @@ * * @func * @memberOf R + * @since v0.8.0 * @category Object * @sig String -> a -> {k: v} -> {k: v} * @param {String} prop the property name to set @@ -856,6 +893,7 @@ * * @func * @memberOf R + * @since v0.8.0 * @category Object * @sig [String] -> a -> {k: v} -> {k: v} * @param {Array} path the path to set @@ -885,6 +923,7 @@ * * @func * @memberOf R + * @since v0.6.0 * @category Function * @category Object * @see R.partial @@ -899,48 +938,19 @@ }); }); - /** - * A function wrapping calls to the two functions in an `&&` operation, returning the result of the first - * function if it is false-y and the result of the second function otherwise. Note that this is - * short-circuited, meaning that the second function will not be invoked if the first returns a false-y - * value. - * - * @func - * @memberOf R - * @category Logic - * @sig (*... -> Boolean) -> (*... -> Boolean) -> (*... -> Boolean) - * @param {Function} f a predicate - * @param {Function} g another predicate - * @return {Function} a function that applies its arguments to `f` and `g` and `&&`s their outputs together. - * @see R.and - * @example - * - * var gt10 = function(x) { return x > 10; }; - * var even = function(x) { return x % 2 === 0 }; - * var f = R.both(gt10, even); - * f(100); //=> true - * f(101); //=> false - */ - var both = _curry2(function both(f, g) { - return function _both() { - return f.apply(this, arguments) && g.apply(this, arguments); - }; - }); - /** * Makes a comparator function out of a function that reports whether the first element is less than the second. * * @func * @memberOf R + * @since v0.1.0 * @category Function * @sig (a, b -> Boolean) -> (a, b -> Number) * @param {Function} pred A predicate function of arity two. * @return {Function} A Function :: a -> b -> Int that returns `-1` if a < b, `1` if b < a, otherwise `0`. * @example * - * var cmp = R.comparator(function(a, b) { - * return a.age < b.age; - * }); + * var cmp = R.comparator((a, b) => a.age < b.age); * var people = [ * // ... * ]; @@ -952,31 +962,6 @@ }; }); - /** - * Takes a function `f` and returns a function `g` such that: - * - * - applying `g` to zero or more arguments will give __true__ if applying - * the same arguments to `f` gives a logical __false__ value; and - * - * - applying `g` to zero or more arguments will give __false__ if applying - * the same arguments to `f` gives a logical __true__ value. - * - * @func - * @memberOf R - * @category Logic - * @sig (*... -> *) -> (*... -> Boolean) - * @param {Function} f - * @return {Function} - * @see R.not - * @example - * - * var isEven = function(n) { return n % 2 === 0; }; - * var isOdd = R.complement(isEven); - * isOdd(21); //=> true - * isOdd(42); //=> false - */ - var complement = _curry1(_complement); - /** * Returns a function, `fn`, which encapsulates if/else-if/else logic. * `R.cond` takes a list of [predicate, transform] pairs. All of the @@ -987,6 +972,7 @@ * * @func * @memberOf R + * @since v0.6.0 * @category Logic * @sig [[(*... -> Boolean),(*... -> *)]] -> (*... -> *) * @param {Array} pairs @@ -996,7 +982,7 @@ * var fn = R.cond([ * [R.equals(0), R.always('water freezes at 0°C')], * [R.equals(100), R.always('water boils at 100°C')], - * [R.T, function(temp) { return 'nothing special happens at ' + temp + '°C'; }] + * [R.T, temp => 'nothing special happens at ' + temp + '°C'] * ]); * fn(0); //=> 'water freezes at 0°C' * fn(50); //=> 'nothing special happens at 50°C' @@ -1020,17 +1006,21 @@ * * @func * @memberOf R + * @since v0.1.5 * @category List * @sig (a, a -> Boolean) -> a -> [a] -> Boolean * @param {Function} pred A predicate used to test whether two items are equal. * @param {*} x The item to find * @param {Array} list The list to iterate over * @return {Boolean} `true` if `x` is in `list`, else `false`. + * @deprecated since v0.18.0 * @example * - * var xs = [{x: 12}, {x: 11}, {x: 10}]; - * R.containsWith(function(a, b) { return a.x === b.x; }, {x: 10}, xs); //=> true - * R.containsWith(function(a, b) { return a.x === b.x; }, {x: 1}, xs); //=> false + * var absEq = (a, b) => Math.abs(a) === Math.abs(b); + * R.containsWith(absEq, 5, [1, 2, 3]); //=> false + * R.containsWith(absEq, 5, [4, 5, 6]); //=> true + * R.containsWith(absEq, 5, [-1, -2, -3]); //=> false + * R.containsWith(absEq, 5, [-4, -5, -6]); //=> true */ var containsWith = _curry3(_containsWith); @@ -1043,6 +1033,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Relation * @sig (a -> String) -> [a] -> {*} * @param {Function} fn The function used to map values to keys. @@ -1067,30 +1058,6 @@ return counts; }); - /** - * Creates an object containing a single key:value pair. - * - * @func - * @memberOf R - * @category Object - * @sig String -> a -> {String:a} - * @param {String} key - * @param {*} val - * @return {Object} - * @example - * - * var matchPhrases = R.compose( - * R.createMapEntry('must'), - * R.map(R.createMapEntry('match_phrase')) - * ); - * matchPhrases(['foo', 'bar', 'baz']); //=> {must: [{match_phrase: 'foo'}, {match_phrase: 'bar'}, {match_phrase: 'baz'}]} - */ - var createMapEntry = _curry2(function createMapEntry(key, val) { - var obj = {}; - obj[key] = val; - return obj; - }); - /** * Returns a curried equivalent of the provided function, with the * specified arity. The curried function has two unusual capabilities. @@ -1117,6 +1084,7 @@ * * @func * @memberOf R + * @since v0.5.0 * @category Function * @sig Number -> (* -> a) -> (* -> a) * @param {Number} length The arity for the returned function. @@ -1125,11 +1093,9 @@ * @see R.curry * @example * - * var addFourNumbers = function() { - * return R.sum([].slice.call(arguments, 0, 4)); - * }; + * var sumArgs = (...args) => R.sum(args); * - * var curriedAddFourNumbers = R.curryN(4, addFourNumbers); + * var curriedAddFourNumbers = R.curryN(4, sumArgs); * var f = curriedAddFourNumbers(1, 2); * var g = f(3); * g(4); //=> 10 @@ -1146,6 +1112,7 @@ * * @func * @memberOf R + * @since v0.9.0 * @category Math * @sig Number -> Number * @param {Number} n @@ -1158,11 +1125,12 @@ var dec = add(-1); /** - * Returns the second argument if it is not null or undefined. If it is null - * or undefined, the first (default) argument is returned. + * Returns the second argument if it is not `null`, `undefined` or `NaN` + * otherwise the first argument is returned. * * @func * @memberOf R + * @since v0.10.0 * @category Logic * @sig a -> b -> a | b * @param {a} val The default value. @@ -1170,14 +1138,15 @@ * @return {*} The the second value or the default value * @example * - * var defaultTo42 = defaultTo(42); + * var defaultTo42 = R.defaultTo(42); * * defaultTo42(null); //=> 42 * defaultTo42(undefined); //=> 42 * defaultTo42('Ramda'); //=> 'Ramda' + * defaultTo42(parseInt('string')); //=> 42 */ var defaultTo = _curry2(function defaultTo(d, v) { - return v == null ? d : v; + return v == null || v !== v ? d : v; }); /** @@ -1187,6 +1156,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Relation * @sig (a,a -> Boolean) -> [a] -> [a] -> [a] * @param {Function} pred A predicate used to test whether two items are equal. @@ -1196,7 +1166,7 @@ * @return {Array} The elements in `list1` that are not in `list2`. * @example * - * function cmp(x, y) { return x.a === y.a; } + * function cmp(x, y) => x.a === y.a; * var l1 = [{a: 1}, {a: 2}, {a: 3}]; * var l2 = [{a: 3}, {a: 4}]; * R.differenceWith(cmp, l1, l2); //=> [{a: 1}, {a: 2}] @@ -1220,6 +1190,7 @@ * * @func * @memberOf R + * @since v0.10.0 * @category Object * @sig String -> {k: v} -> {k: v} * @param {String} prop the name of the property to dissociate @@ -1248,6 +1219,7 @@ * * @func * @memberOf R + * @since v0.11.0 * @category Object * @sig [String] -> {k: v} -> {k: v} * @param {Array} path the path to set @@ -1276,6 +1248,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Math * @sig Number -> Number -> Number * @param {Number} a The first value. @@ -1304,6 +1277,7 @@ * * @func * @memberOf R + * @since v0.16.0 * @category List * @sig (a -> Boolean) -> [a] -> [a] * @param {Function} fn The function called per iteration. @@ -1312,11 +1286,9 @@ * @see R.takeLastWhile * @example * - * var lteThree = function(x) { - * return x <= 3; - * }; + * var lteThree = x => x <= 3; * - * R.dropLastWhile(lteThree, [1, 2, 3, 4, 3, 2, 1]); //=> [1, 2] + * R.dropLastWhile(lteThree, [1, 2, 3, 4, 3, 2, 1]); //=> [1, 2, 3, 4] */ var dropLastWhile = _curry2(function dropLastWhile(pred, list) { var idx = list.length - 1; @@ -1326,41 +1298,17 @@ return _slice(list, 0, idx + 1); }); - /** - * A function wrapping calls to the two functions in an `||` operation, returning the result of the first - * function if it is truth-y and the result of the second function otherwise. Note that this is - * short-circuited, meaning that the second function will not be invoked if the first returns a truth-y - * value. - * - * @func - * @memberOf R - * @category Logic - * @sig (*... -> Boolean) -> (*... -> Boolean) -> (*... -> Boolean) - * @param {Function} f a predicate - * @param {Function} g another predicate - * @return {Function} a function that applies its arguments to `f` and `g` and `||`s their outputs together. - * @see R.or - * @example - * - * var gt10 = function(x) { return x > 10; }; - * var even = function(x) { return x % 2 === 0 }; - * var f = R.either(gt10, even); - * f(101); //=> true - * f(8); //=> true - */ - var either = _curry2(function either(f, g) { - return function _either() { - return f.apply(this, arguments) || g.apply(this, arguments); - }; - }); - /** * Returns the empty value of its argument's type. Ramda defines the empty - * value of Array (`[]`), Object (`{}`), and String (`''`). Other types are - * supported if they define `.empty` and/or `.prototype.empty`. + * value of Array (`[]`), Object (`{}`), String (`''`), and Arguments. + * Other types are supported if they define `.empty` and/or + * `.prototype.empty`. + * + * Dispatches to the `empty` method of the first argument, if present. * * @func * @memberOf R + * @since v0.3.0 * @category Function * @sig a -> a * @param {*} x @@ -1372,32 +1320,24 @@ * R.empty('unicorns'); //=> '' * R.empty({x: 1, y: 2}); //=> {} */ + // else var empty = _curry1(function empty(x) { - if (x != null && typeof x.empty === 'function') { - return x.empty(); - } else if (x != null && typeof x.constructor != null && typeof x.constructor.empty === 'function') { - return x.constructor.empty(); - } else { - switch (Object.prototype.toString.call(x)) { - case '[object Array]': - return []; - case '[object Object]': - return {}; - case '[object String]': - return ''; - } - } + return x != null && typeof x.empty === 'function' ? x.empty() : x != null && x.constructor != null && typeof x.constructor.empty === 'function' ? x.constructor.empty() : _isArray(x) ? [] : _isString(x) ? '' : _isObject(x) ? {} : _isArguments(x) ? function () { + return arguments; + }() : // else + void 0; }); /** * Creates a new object by recursively evolving a shallow copy of `object`, according to the * `transformation` functions. All non-primitive properties are copied by reference. * - * A `tranformation` function will not be invoked if its corresponding key does not exist in + * A `transformation` function will not be invoked if its corresponding key does not exist in * the evolved object. * * @func * @memberOf R + * @since v0.9.0 * @category Object * @sig {k: (v -> v)} -> {k: v} -> {k: v} * @param {Object} transformations The object specifying transformation functions to apply @@ -1429,11 +1369,12 @@ * * @func * @memberOf R + * @since v0.3.0 * @category List * @sig [[k,v]] -> {k: v} * @param {Array} pairs An array of two-element arrays that will be the keys and values of the output object. * @return {Object} The object made by pairing up `keys` and `values`. - * @see R.toPairs + * @see R.toPairs, R.pair * @example * * R.fromPairs([['a', 1], ['b', 2], ['c', 3]]); //=> {a: 1, b: 2, c: 3} @@ -1455,6 +1396,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Relation * @sig Ord a => a -> a -> Boolean * @param {*} a @@ -1479,6 +1421,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Relation * @sig Ord a => a -> a -> Boolean * @param {Number} a @@ -1503,6 +1446,7 @@ * * @func * @memberOf R + * @since v0.7.0 * @category Object * @sig s -> {s: x} -> Boolean * @param {String} prop The name of the property to check for. @@ -1529,6 +1473,7 @@ * * @func * @memberOf R + * @since v0.7.0 * @category Object * @sig s -> {s: x} -> Boolean * @param {String} prop The name of the property to check for. @@ -1559,6 +1504,7 @@ * * @func * @memberOf R + * @since v0.15.0 * @category Relation * @sig a -> a -> Boolean * @param {*} a @@ -1596,6 +1542,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Function * @sig a -> a * @param {*} x The value to return. @@ -1615,7 +1562,9 @@ * * @func * @memberOf R + * @since v0.8.0 * @category Logic + * @see R.unless, R.when * @sig (*... -> Boolean) -> (*... -> *) -> (*... -> *) -> (*... -> *) * @param {Function} condition A predicate function * @param {Function} onTrue A function to invoke when the `condition` evaluates to a truthy value. @@ -1624,11 +1573,13 @@ * function depending upon the result of the `condition` predicate. * @example * - * // Flatten all arrays in the list but leave other values alone. - * var flattenArrays = R.map(R.ifElse(Array.isArray, R.flatten, R.identity)); - * - * flattenArrays([[0], [[10], [8]], 1234, {}]); //=> [[0], [10, 8], 1234, {}] - * flattenArrays([[[10], 123], [8, [10]], "hello"]); //=> [[10, 123], [8, 10], "hello"] + * var incCount = R.ifElse( + * R.has('count'), + * R.over(R.lensProp('count'), R.inc), + * R.assoc('count', 1) + * ); + * incCount({}); //=> { count: 1 } + * incCount({ count: 1 }); //=> { count: 2 } */ var ifElse = _curry3(function ifElse(condition, onTrue, onFalse) { return curryN(Math.max(condition.length, onTrue.length, onFalse.length), function _ifElse() { @@ -1641,6 +1592,7 @@ * * @func * @memberOf R + * @since v0.9.0 * @category Math * @sig Number -> Number * @param {Number} n @@ -1659,6 +1611,7 @@ * * @func * @memberOf R + * @since v0.2.2 * @category List * @sig Number -> a -> [a] -> [a] * @param {Number} index The position to insert the element @@ -1683,6 +1636,7 @@ * * @func * @memberOf R + * @since v0.9.0 * @category List * @sig Number -> [a] -> [a] -> [a] * @param {Number} index The position to insert the sub-list @@ -1704,6 +1658,7 @@ * * @func * @memberOf R + * @since v0.3.0 * @category Type * @sig (* -> {*}) -> a -> Boolean * @param {Object} ctor A constructor @@ -1729,6 +1684,7 @@ * * @func * @memberOf R + * @since v0.5.0 * @category Type * @category List * @sig * -> Boolean @@ -1767,34 +1723,12 @@ return false; }); - /** - * Reports whether the list has zero elements. - * - * @func - * @memberOf R - * @category Logic - * @sig [a] -> Boolean - * @param {Array} list - * @return {Boolean} - * @example - * - * R.isEmpty([1, 2, 3]); //=> false - * R.isEmpty([]); //=> true - * R.isEmpty(''); //=> true - * R.isEmpty(null); //=> false - * R.isEmpty(R.keys({})); //=> true - * R.isEmpty({}); //=> false ({} does not have a length property) - * R.isEmpty({length: 0}); //=> true - */ - var isEmpty = _curry1(function isEmpty(list) { - return Object(list).length === 0; - }); - /** * Checks if the input value is `null` or `undefined`. * * @func * @memberOf R + * @since v0.9.0 * @category Type * @sig * -> Boolean * @param {*} x The value to test. @@ -1818,6 +1752,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Object * @sig {k: v} -> [k] * @param {Object} obj The object to extract properties from @@ -1883,6 +1818,7 @@ * * @func * @memberOf R + * @since v0.2.0 * @category Object * @sig {k: v} -> [k] * @param {Object} obj The object to extract properties from @@ -1907,6 +1843,7 @@ * * @func * @memberOf R + * @since v0.3.0 * @category List * @sig [a] -> Number * @param {Array} list The array to inspect. @@ -1926,6 +1863,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Relation * @sig Ord a => a -> a -> Boolean * @param {*} a @@ -1950,6 +1888,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Relation * @sig Ord a => a -> a -> Boolean * @param {Number} a @@ -1978,6 +1917,7 @@ * * @func * @memberOf R + * @since v0.10.0 * @category List * @sig (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y]) * @param {Function} fn The function to be called on every element of the input `list`. @@ -1987,9 +1927,7 @@ * @example * * var digits = ['1', '2', '3', '4']; - * var append = function(a, b) { - * return [a + b, a + b]; - * } + * var append = (a, b) => [a + b, a + b]; * * R.mapAccum(append, 0, digits); //=> ['01234', ['01', '012', '0123', '01234']] */ @@ -2019,6 +1957,7 @@ * * @func * @memberOf R + * @since v0.10.0 * @category List * @sig (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y]) * @param {Function} fn The function to be called on every element of the input `list`. @@ -2028,9 +1967,7 @@ * @example * * var digits = ['1', '2', '3', '4']; - * var append = function(a, b) { - * return [a + b, a + b]; - * } + * var append = (a, b) => [a + b, a + b]; * * R.mapAccumRight(append, 0, digits); //=> ['04321', ['04321', '0432', '043', '04']] */ @@ -2055,6 +1992,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @see R.test * @category String * @sig RegExp -> String -> [String | Undefined] @@ -2079,6 +2017,7 @@ * * @func * @memberOf R + * @since v0.3.0 * @category Math * @sig Number -> Number -> Number * @param {Number} m The dividend. @@ -2117,6 +2056,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Relation * @sig Ord a => a -> a -> a * @param {*} a @@ -2138,6 +2078,7 @@ * * @func * @memberOf R + * @since v0.8.0 * @category Relation * @sig Ord b => (a -> b) -> a -> a -> a * @param {Function} f @@ -2147,7 +2088,13 @@ * @see R.max, R.minBy * @example * - * R.maxBy(function(n) { return n * n; }, -3, 2); //=> -3 + * // square :: Number -> Number + * var square = n => n * n; + * + * R.maxBy(square, -3, 2); //=> -3 + * + * R.reduce(R.maxBy(square), 0, [3, -5, 4, 1, -2]); //=> -5 + * R.reduce(R.maxBy(square), 0, []); //=> 0 */ var maxBy = _curry3(function maxBy(f, a, b) { return f(b) > f(a) ? b : a; @@ -2159,6 +2106,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Object * @sig {k: v} -> {k: v} -> {k: v} * @param {Object} a @@ -2194,6 +2142,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Relation * @sig Ord a => a -> a -> a * @param {*} a @@ -2215,6 +2164,7 @@ * * @func * @memberOf R + * @since v0.8.0 * @category Relation * @sig Ord b => (a -> b) -> a -> a -> a * @param {Function} f @@ -2224,7 +2174,13 @@ * @see R.min, R.maxBy * @example * - * R.minBy(function(n) { return n * n; }, -3, 2); //=> 2 + * // square :: Number -> Number + * var square = n => n * n; + * + * R.minBy(square, -3, 2); //=> 2 + * + * R.reduce(R.minBy(square), Infinity, [3, -5, 4, 1, -2]); //=> 1 + * R.reduce(R.minBy(square), Infinity, []); //=> Infinity */ var minBy = _curry3(function minBy(f, a, b) { return f(b) < f(a) ? b : a; @@ -2232,11 +2188,12 @@ /** * Divides the second parameter by the first and returns the remainder. - * Note that this functions preserves the JavaScript-style behavior for - * modulo. For mathematical modulo see `mathMod` + * Note that this function preserves the JavaScript-style behavior for + * modulo. For mathematical modulo see `mathMod`. * * @func * @memberOf R + * @since v0.1.1 * @category Math * @sig Number -> Number -> Number * @param {Number} a The value to the divide. @@ -2263,6 +2220,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Math * @sig Number -> Number -> Number * @param {Number} a The first value. @@ -2287,6 +2245,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Function * @sig Number -> (* -> a) -> (* -> a) * @param {Number} n The desired arity of the new function. @@ -2295,9 +2254,8 @@ * arity `n`. * @example * - * var takesTwoArgs = function(a, b) { - * return [a, b]; - * }; + * var takesTwoArgs = (a, b) => [a, b]; + * * takesTwoArgs.length; //=> 2 * takesTwoArgs(1, 2); //=> [1, 2] * @@ -2362,6 +2320,7 @@ * * @func * @memberOf R + * @since v0.9.0 * @category Math * @sig Number -> Number * @param {Number} n @@ -2380,6 +2339,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Logic * @sig * -> Boolean * @param {*} a any value @@ -2402,6 +2362,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category List * @sig Number -> [a] -> a | Undefined * @sig Number -> String -> String @@ -2428,6 +2389,7 @@ * * @func * @memberOf R + * @since v0.9.0 * @category Function * @sig Number -> *... -> * * @param {Number} n @@ -2444,43 +2406,29 @@ }); /** - * Returns the nth character of the given string. - * - * @func - * @memberOf R - * @category String - * @sig Number -> String -> String - * @param {Number} n - * @param {String} str - * @return {String} - * @deprecated since v0.16.0 - * @example - * - * R.nthChar(2, 'Ramda'); //=> 'm' - * R.nthChar(-2, 'Ramda'); //=> 'd' - */ - var nthChar = _curry2(function nthChar(n, str) { - return str.charAt(n < 0 ? str.length + n : n); - }); - - /** - * Returns the character code of the nth character of the given string. + * Creates an object containing a single key:value pair. * * @func * @memberOf R - * @category String - * @sig Number -> String -> Number - * @param {Number} n - * @param {String} str - * @return {Number} - * @deprecated since v0.16.0 + * @since v0.18.0 + * @category Object + * @sig String -> a -> {String:a} + * @param {String} key + * @param {*} val + * @return {Object} + * @see R.pair * @example * - * R.nthCharCode(2, 'Ramda'); //=> 'm'.charCodeAt(0) - * R.nthCharCode(-2, 'Ramda'); //=> 'd'.charCodeAt(0) + * var matchPhrases = R.compose( + * R.objOf('must'), + * R.map(R.objOf('match_phrase')) + * ); + * matchPhrases(['foo', 'bar', 'baz']); //=> {must: [{match_phrase: 'foo'}, {match_phrase: 'bar'}, {match_phrase: 'baz'}]} */ - var nthCharCode = _curry2(function nthCharCode(n, str) { - return str.charCodeAt(n < 0 ? str.length + n : n); + var objOf = _curry2(function objOf(key, val) { + var obj = {}; + obj[key] = val; + return obj; }); /** @@ -2491,6 +2439,7 @@ * * @func * @memberOf R + * @since v0.3.0 * @category Function * @sig a -> [a] * @param {*} x any value @@ -2500,24 +2449,23 @@ * R.of(null); //=> [null] * R.of([42]); //=> [[42]] */ - var of = _curry1(function of(x) { - return [x]; - }); + var of = _curry1(_of); /** * Accepts a function `fn` and returns a function that guards invocation of `fn` such that * `fn` can only ever be called once, no matter how many times the returned function is - * invoked. + * invoked. The first value calculated is returned in subsequent invocations. * * @func * @memberOf R + * @since v0.1.0 * @category Function * @sig (a... -> b) -> (a... -> b) * @param {Function} fn The function to wrap in a call-only-once wrapper. * @return {Function} The wrapped function. * @example * - * var addOneOnce = R.once(function(x){ return x + 1; }); + * var addOneOnce = R.once(x => x + 1); * addOneOnce(10); //=> 11 * addOneOnce(addOneOnce(50)); //=> 11 */ @@ -2533,12 +2481,38 @@ }; }); + /** + * Returns `true` if one or both of its arguments are `true`. Returns `false` + * if both arguments are `false`. + * + * @func + * @memberOf R + * @since v0.1.0 + * @category Logic + * @sig * -> * -> * + * @param {Boolean} a A boolean value + * @param {Boolean} b A boolean value + * @return {Boolean} `true` if one or both arguments are `true`, `false` otherwise + * @see R.either + * @example + * + * R.or(true, true); //=> true + * R.or(true, false); //=> true + * R.or(false, true); //=> true + * R.or(false, false); //=> false + */ + var or = _curry2(function or(a, b) { + return a || b; + }); + /** * Returns the result of "setting" the portion of the given data structure - * focused by the given lens to the given value. + * focused by the given lens to the result of applying the given function to + * the focused value. * * @func * @memberOf R + * @since v0.16.0 * @category Object * @typedefn Lens s a = Functor f => (a -> f a) -> s -> f s * @sig Lens s a -> (a -> a) -> s -> s @@ -2569,11 +2543,35 @@ }); }(); + /** + * Takes two arguments, `fst` and `snd`, and returns `[fst, snd]`. + * + * @func + * @memberOf R + * @since v0.18.0 + * @category List + * @sig a -> b -> (a,b) + * @param {*} fst + * @param {*} snd + * @return {Array} + * @see R.createMapEntry, R.of + * @example + * + * pair('foo', 'bar'); //=> ['foo', 'bar'] + */ + var pair = _curry2(function pair(fst, snd) { + return [ + fst, + snd + ]; + }); + /** * Retrieve the value at a given path. * * @func * @memberOf R + * @since v0.2.0 * @category Object * @sig [String] -> {k: v} -> v | Undefined * @param {Array} path The path to use. @@ -2588,25 +2586,49 @@ return; } else { var val = obj; - for (var idx = 0, len = paths.length; idx < len && val != null; idx += 1) { + var idx = 0; + while (val != null && idx < paths.length) { val = val[paths[idx]]; + idx += 1; } return val; } }); + /** + * If the given, non-null object has a value at the given path, returns + * the value at that path. Otherwise returns the provided default value. + * + * @func + * @memberOf R + * @since v0.18.0 + * @category Object + * @sig a -> [String] -> Object -> a + * @param {*} d The default value. + * @param {Array} p The path to use. + * @return {*} The data at `path` of the supplied object or the default value. + * @example + * + * R.pathOr('N/A', ['a', 'b'], {a: {b: 2}}); //=> 2 + * R.pathOr('N/A', ['a', 'b'], {c: {b: 2}}); //=> "N/A" + */ + var pathOr = _curry3(function pathOr(d, p, obj) { + return defaultTo(d, path(p, obj)); + }); + /** * Returns a partial copy of an object containing only the keys specified. If the key does not exist, the * property is ignored. * * @func * @memberOf R + * @since v0.1.0 * @category Object * @sig [k] -> {k: v} -> {k: v} * @param {Array} names an array of String property names to copy onto a new object * @param {Object} obj The object to copy from * @return {Object} A new object with only properties from `names` on it. - * @see R.omit + * @see R.omit, R.props * @example * * R.pick(['a', 'd'], {a: 1, b: 2, c: 3, d: 4}); //=> {a: 1, d: 4} @@ -2629,6 +2651,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Object * @sig [k] -> {k: v} -> {k: v} * @param {Array} names an array of String property names to copy onto a new object @@ -2658,6 +2681,7 @@ * * @func * @memberOf R + * @since v0.8.0 * @category Object * @sig (v, k -> Boolean) -> {k: v} -> {k: v} * @param {Function} pred A predicate to determine whether or not a key @@ -2668,7 +2692,7 @@ * @see R.pick * @example * - * var isUpperCase = function(val, key) { return key.toUpperCase() === key; } + * var isUpperCase = (val, key) => key.toUpperCase() === key; * R.pickBy(isUpperCase, {a: 1, b: 2, A: 3, B: 4}); //=> {A: 3, B: 4} */ var pickBy = _curry2(function pickBy(test, obj) { @@ -2687,6 +2711,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category List * @sig a -> [a] -> [a] * @param {*} el The item to add to the head of the output list. @@ -2706,6 +2731,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Object * @sig s -> {s: a} -> a | Undefined * @param {String} p The property name @@ -2727,6 +2753,7 @@ * * @func * @memberOf R + * @since v0.6.0 * @category Object * @sig a -> String -> Object -> a * @param {*} val The default value. @@ -2755,6 +2782,7 @@ * * @func * @memberOf R + * @since v0.16.0 * @category Logic * @sig (a -> Boolean) -> String -> {String: a} -> Boolean * @param {Function} pred @@ -2776,6 +2804,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Object * @sig [k] -> {k: v} -> [v] * @param {Array} ps The property names to fetch @@ -2806,6 +2835,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category List * @sig Number -> Number -> [Number] * @param {Number} from The first number in the list. @@ -2844,6 +2874,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category List * @sig (a,b -> a) -> a -> [b] -> a * @param {Function} fn The iterator function. Receives two values, the accumulator and the @@ -2854,9 +2885,7 @@ * @example * * var pairs = [ ['a', 1], ['b', 2], ['c', 3] ]; - * var flattenPairs = function(acc, pair) { - * return acc.concat(pair); - * }; + * var flattenPairs = (acc, pair) => acc.concat(pair); * * R.reduceRight(flattenPairs, [], pairs); //=> [ 'c', 3, 'b', 2, 'a', 1 ] */ @@ -2881,6 +2910,7 @@ * * @func * @memberOf R + * @since v0.15.0 * @category List * @see R.reduce, R.transduce * @sig a -> * @@ -2889,7 +2919,7 @@ * @example * * R.reduce( - * R.pipe(R.add, R.ifElse(R.lte(10), R.reduced, R.identity)), + * R.pipe(R.add, R.when(R.gte(R.__, 10), R.reduced)), * 0, * [1, 2, 3, 4, 5]) // 10 */ @@ -2903,6 +2933,7 @@ * * @func * @memberOf R + * @since v0.2.2 * @category List * @sig Number -> Number -> [a] -> [a] * @param {Number} start The position to start removing elements @@ -2922,6 +2953,7 @@ * * @func * @memberOf R + * @since v0.7.0 * @category String * @sig RegExp|String -> String -> String -> String * @param {RegExp|String} pattern A regular expression or a substring to match. @@ -2941,24 +2973,31 @@ }); /** - * Returns a new list with the same elements as the original list, just - * in the reverse order. + * Returns a new list or string with the elements or characters in reverse + * order. * * @func * @memberOf R + * @since v0.1.0 * @category List * @sig [a] -> [a] - * @param {Array} list The list to reverse. - * @return {Array} A copy of the list in reverse order. + * @sig String -> String + * @param {Array|String} list + * @return {Array|String} * @example * * R.reverse([1, 2, 3]); //=> [3, 2, 1] * R.reverse([1, 2]); //=> [2, 1] * R.reverse([1]); //=> [1] * R.reverse([]); //=> [] + * + * R.reverse('abc'); //=> 'cba' + * R.reverse('ab'); //=> 'ba' + * R.reverse('a'); //=> 'a' + * R.reverse(''); //=> '' */ var reverse = _curry1(function reverse(list) { - return _slice(list).reverse(); + return _isString(list) ? list.split('').reverse().join('') : _slice(list).reverse(); }); /** @@ -2966,6 +3005,7 @@ * * @func * @memberOf R + * @since v0.10.0 * @category List * @sig (a,b -> a) -> a -> [b] -> [a] * @param {Function} fn The iterator function. Receives two values, the accumulator and the @@ -2994,6 +3034,7 @@ * * @func * @memberOf R + * @since v0.16.0 * @category Object * @typedefn Lens s a = Functor f => (a -> f a) -> s -> f s * @sig Lens s a -> a -> s -> s @@ -3020,6 +3061,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category List * @sig (a,a -> Number) -> [a] -> [a] * @param {Function} comparator A sorting function :: a -> b -> Int @@ -3039,6 +3081,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Relation * @sig Ord b => (a -> b) -> [a] -> [a] * @param {Function} fn @@ -3046,7 +3089,7 @@ * @return {Array} A new list sorted by the keys generated by `fn`. * @example * - * var sortByFirstItem = R.sortBy(prop(0)); + * var sortByFirstItem = R.sortBy(R.prop(0)); * var sortByNameCaseInsensitive = R.sortBy(R.compose(R.toLower, R.prop('name'))); * var pairs = [[-1, 1], [-2, 2], [-3, 3]]; * sortByFirstItem(pairs); //=> [[-3, 3], [-2, 2], [-1, 1]] @@ -3078,6 +3121,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Math * @sig Number -> Number -> Number * @param {Number} a The first value. @@ -3107,6 +3151,7 @@ * * @func * @memberOf R + * @since v0.16.0 * @category List * @sig (a -> Boolean) -> [a] -> [a] * @param {Function} fn The function called per iteration. @@ -3115,9 +3160,7 @@ * @see R.dropLastWhile * @example * - * var isNotOne = function(x) { - * return !(x === 1); - * }; + * var isNotOne = x => x !== 1; * * R.takeLastWhile(isNotOne, [1, 2, 3, 4]); //=> [2, 3, 4] */ @@ -3134,6 +3177,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Function * @sig (a -> *) -> a -> a * @param {Function} fn The function to call with `x`. The return value of `fn` will be thrown away. @@ -3141,7 +3185,7 @@ * @return {*} `x`. * @example * - * var sayX = function(x) { console.log('x is ' + x); }; + * var sayX = x => console.log('x is ' + x); * R.tap(sayX, 100); //=> 100 * //-> 'x is 100' */ @@ -3151,39 +3195,20 @@ }); /** - * Determines whether a given string matches a given regular expression. + * Calls an input function `n` times, returning an array containing the results of those + * function calls. + * + * `fn` is passed one argument: The current value of `n`, which begins at `0` and is + * gradually incremented to `n - 1`. * * @func * @memberOf R - * @see R.match - * @category String - * @sig RegExp -> String -> Boolean - * @param {RegExp} pattern - * @param {String} str - * @return {Boolean} - * @example - * - * R.test(/^x/, 'xyz'); //=> true - * R.test(/^y/, 'xyz'); //=> false - */ - var test = _curry2(function test(pattern, str) { - return _cloneRegExp(pattern).test(str); - }); - - /** - * Calls an input function `n` times, returning an array containing the results of those - * function calls. - * - * `fn` is passed one argument: The current value of `n`, which begins at `0` and is - * gradually incremented to `n - 1`. - * - * @func - * @memberOf R - * @category List - * @sig (i -> a) -> i -> [a] - * @param {Function} fn The function to invoke. Passed one argument, the current value of `n`. - * @param {Number} n A value between `0` and `n - 1`. Increments after each function call. - * @return {Array} An array containing the return values of all calls to `fn`. + * @since v0.2.3 + * @category List + * @sig (i -> a) -> i -> [a] + * @param {Function} fn The function to invoke. Passed one argument, the current value of `n`. + * @param {Number} n A value between `0` and `n - 1`. Increments after each function call. + * @return {Array} An array containing the return values of all calls to `fn`. * @example * * R.times(R.identity, 5); //=> [0, 1, 2, 3, 4] @@ -3207,6 +3232,7 @@ * * @func * @memberOf R + * @since v0.4.0 * @category Object * @sig {String: *} -> [[String,*]] * @param {Object} obj The object to extract from @@ -3237,6 +3263,7 @@ * * @func * @memberOf R + * @since v0.4.0 * @category Object * @sig {String: *} -> [[String,*]] * @param {Object} obj The object to extract from @@ -3265,6 +3292,7 @@ * * @func * @memberOf R + * @since v0.6.0 * @category String * @sig String -> String * @param {String} str The string to trim. @@ -3298,6 +3326,7 @@ * * @func * @memberOf R + * @since v0.8.0 * @category Type * @sig (* -> {*}) -> String * @param {*} val The value to test @@ -3329,6 +3358,7 @@ * * @func * @memberOf R + * @since v0.8.0 * @category Function * @sig ([*...] -> a) -> (*... -> a) * @param {Function} fn @@ -3350,6 +3380,7 @@ * * @func * @memberOf R + * @since v0.2.0 * @category Function * @sig (* -> b) -> (a -> b) * @param {Function} fn The function to wrap. @@ -3377,6 +3408,7 @@ * * @func * @memberOf R + * @since v0.14.0 * @category Function * @sig Number -> (a -> b) -> (a -> c) * @param {Number} length The arity for the returned function. @@ -3385,18 +3417,10 @@ * @see R.curry * @example * - * var addFour = function(a) { - * return function(b) { - * return function(c) { - * return function(d) { - * return a + b + c + d; - * }; - * }; - * }; - * }; + * var addFour = a => b => c => d => a + b + c + d; * * var uncurriedAddFour = R.uncurryN(4, addFour); - * curriedAddFour(1, 2, 3, 4); //=> 10 + * uncurriedAddFour(1, 2, 3, 4); //=> 10 */ var uncurryN = _curry2(function uncurryN(depth, fn) { return curryN(depth, function () { @@ -3423,6 +3447,7 @@ * * @func * @memberOf R + * @since v0.10.0 * @category List * @sig (a -> [b]) -> * -> [b] * @param {Function} fn The iterator function. receives one argument, `seed`, and returns @@ -3433,7 +3458,7 @@ * @return {Array} The final list. * @example * - * var f = function(n) { return n > 50 ? false : [-n, n + 10] }; + * var f = n => n > 50 ? false : [-n, n + 10]; * R.unfold(f, 10); //=> [-10, -20, -30, -40, -50] */ var unfold = _curry2(function unfold(fn, seed) { @@ -3453,6 +3478,7 @@ * * @func * @memberOf R + * @since v0.2.0 * @category List * @sig (a, a -> Boolean) -> [a] -> [a] * @param {Function} pred A predicate used to test whether two items are equal. @@ -3460,7 +3486,7 @@ * @return {Array} The list of unique items. * @example * - * var strEq = function(a, b) { return String(a) === String(b); }; + * var strEq = R.eqBy(String); * R.uniqWith(strEq)([1, '1', 2, 1]); //=> [1, 2] * R.uniqWith(strEq)([{}, {}]); //=> [{}] * R.uniqWith(strEq)([1, '1', 1]); //=> [1] @@ -3479,6 +3505,35 @@ return result; }); + /** + * Tests the final argument by passing it to the given predicate function. + * If the predicate is not satisfied, the function will return the + * result of calling the `whenFalseFn` function with the same argument. If the + * predicate is satisfied, the argument is returned as is. + * + * @func + * @memberOf R + * @since v0.18.0 + * @category Logic + * @see R.ifElse, R.when + * @sig (a -> Boolean) -> (a -> a) -> a -> a + * @param {Function} pred A predicate function + * @param {Function} whenFalseFn A function to invoke when the `pred` evaluates + * to a falsy value. + * @param {*} x An object to test with the `pred` function and + * pass to `whenFalseFn` if necessary. + * @return {*} Either `x` or the result of applying `x` to `whenFalseFn`. + * @example + * + * // coerceArray :: (a|[a]) -> [a] + * var coerceArray = R.unless(R.isArrayLike, R.of); + * coerceArray([1, 2, 3]); //=> [1, 2, 3] + * coerceArray(1); //=> [1] + */ + var unless = _curry3(function unless(pred, whenFalseFn, x) { + return pred(x) ? x : whenFalseFn(x); + }); + /** * Returns a new copy of the array with the element at the * provided index replaced with the given value. @@ -3486,6 +3541,7 @@ * * @func * @memberOf R + * @since v0.14.0 * @category List * @sig Number -> a -> [a] -> [a] * @param {Number} idx The index to update. @@ -3508,6 +3564,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Object * @sig {k: v} -> [v] * @param {Object} obj The object to extract values from @@ -3536,6 +3593,7 @@ * * @func * @memberOf R + * @since v0.2.0 * @category Object * @sig {k: v} -> [v] * @param {Object} obj The object to extract values from @@ -3561,6 +3619,7 @@ * * @func * @memberOf R + * @since v0.16.0 * @category Object * @typedefn Lens s a = Functor f => (a -> f a) -> s -> f s * @sig Lens s a -> s -> a @@ -3589,6 +3648,38 @@ }); }(); + /** + * Tests the final argument by passing it to the given predicate function. + * If the predicate is satisfied, the function will return the result + * of calling the `whenTrueFn` function with the same argument. If the predicate + * is not satisfied, the argument is returned as is. + * + * @func + * @memberOf R + * @since v0.18.0 + * @category Logic + * @see R.ifElse, R.unless + * @sig (a -> Boolean) -> (a -> a) -> a -> a + * @param {Function} pred A predicate function + * @param {Function} whenTrueFn A function to invoke when the `condition` + * evaluates to a truthy value. + * @param {*} x An object to test with the `pred` function and + * pass to `whenTrueFn` if necessary. + * @return {*} Either `x` or the result of applying `x` to `whenTrueFn`. + * @example + * + * // truncate :: String -> String + * var truncate = R.when( + * R.propSatisfies(R.gt(R.__, 10), 'length'), + * R.pipe(R.take(10), R.append('…'), R.join('')) + * ); + * truncate('12345'); //=> '12345' + * truncate('0123456789ABC'); //=> '0123456789…' + */ + var when = _curry3(function when(pred, whenTrueFn, x) { + return pred(x) ? whenTrueFn(x) : x; + }); + /** * Takes a spec object and a test object; returns true if the test satisfies * the spec. Each of the spec's own properties must be a predicate function. @@ -3601,6 +3692,7 @@ * * @func * @memberOf R + * @since v0.1.1 * @category Object * @sig {String: (* -> Boolean)} -> {String: *} -> Boolean * @param {Object} spec @@ -3637,6 +3729,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Function * @sig (a... -> b) -> ((a... -> b) -> a... -> c) -> (a... -> c) * @param {Function} fn The function to wrap. @@ -3644,11 +3737,10 @@ * @return {Function} The wrapped function. * @example * - * var greet = function(name) {return 'Hello ' + name;}; + * var greet = name => 'Hello ' + name; + * + * var shoutedGreet = R.wrap(greet, (gr, name) => gr(name).toUpperCase()); * - * var shoutedGreet = R.wrap(greet, function(gr, name) { - * return gr(name).toUpperCase(); - * }); * shoutedGreet("Kathy"); //=> "HELLO KATHY" * * var shortenedGreet = R.wrap(greet, function(gr, name) { @@ -3668,6 +3760,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category List * @sig [a] -> [b] -> [[a,b]] * @param {Array} as The first list. @@ -3708,6 +3801,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category List * @sig [a] -> [b] -> [[a,b]] * @param {Array} list1 The first array to consider. @@ -3736,6 +3830,7 @@ * * @func * @memberOf R + * @since v0.3.0 * @category List * @sig [String] -> [*] -> {String: *} * @param {Array} keys The array that will be properties on the output object. @@ -3761,6 +3856,7 @@ * * @function * @memberOf R + * @since v0.1.0 * @category List * @sig (a,b -> c) -> [a] -> [b] -> [c] * @param {Function} fn The function used to combine the two elements into one value. @@ -3770,7 +3866,7 @@ * using `fn`. * @example * - * var f = function(x, y) { + * var f = (x, y) => { * // ... * }; * R.zipWith(f, [1, 2, 3], ['a', 'b', 'c']); @@ -3790,9 +3886,11 @@ * * @func * @memberOf R + * @since v0.9.0 * @category Function - * @sig * -> false - * @return {Boolean} false + * @sig * -> Boolean + * @param {*} + * @return {Boolean} * @see R.always, R.T * @example * @@ -3805,9 +3903,11 @@ * * @func * @memberOf R + * @since v0.9.0 * @category Function - * @sig * -> true - * @return {Boolean} `true`. + * @sig * -> Boolean + * @param {*} + * @return {Boolean} * @see R.always, R.F * @example * @@ -3815,6 +3915,17 @@ */ var T = always(true); + var _aperture = function _aperture(n, list) { + var idx = 0; + var limit = list.length - (n - 1); + var acc = new Array(limit >= 0 ? limit : 0); + while (idx < limit) { + acc[idx] = _slice(list, idx, idx + n); + idx += 1; + } + return acc; + }; + /** * Similar to hasMethod, this checks whether a function has a [methodname] * function. If it isn't an array it will execute that function otherwise it will @@ -3877,12 +3988,11 @@ }; var _createPartialApplicator = function _createPartialApplicator(concat) { - return function (fn) { - var args = _slice(arguments, 1); + return _curry2(function (fn, args) { return _arity(Math.max(0, fn.length - args.length), function () { return fn.apply(this, concat(args, arguments)); }); - }; + }); }; /** @@ -3920,75 +4030,88 @@ }; }; - // The algorithm used to handle cyclic structures is - // inspired by underscore's isEqual - // RegExp equality algorithm: http://stackoverflow.com/a/10776635 + // Values of other types are only equal if identical. var _equals = function _equals(a, b, stackA, stackB) { - var typeA = type(a); - if (typeA !== type(b)) { - return false; - } - if (typeA === 'Boolean' || typeA === 'Number' || typeA === 'String') { - return typeof a === 'object' ? typeof b === 'object' && identical(a.valueOf(), b.valueOf()) : identical(a, b); - } if (identical(a, b)) { return true; } - if (typeA === 'RegExp') { - // RegExp equality algorithm: http://stackoverflow.com/a/10776635 - return a.source === b.source && a.global === b.global && a.ignoreCase === b.ignoreCase && a.multiline === b.multiline && a.sticky === b.sticky && a.unicode === b.unicode; + if (type(a) !== type(b)) { + return false; + } + if (a == null || b == null) { + return false; + } + if (typeof a.equals === 'function' || typeof b.equals === 'function') { + return typeof a.equals === 'function' && a.equals(b) && typeof b.equals === 'function' && b.equals(a); } - if (Object(a) === a) { - if (typeA === 'Date' && a.getTime() !== b.getTime()) { + switch (type(a)) { + case 'Arguments': + case 'Array': + case 'Object': + break; + case 'Boolean': + case 'Number': + case 'String': + if (!(typeof a === typeof b && identical(a.valueOf(), b.valueOf()))) { return false; } - var keysA = keys(a); - if (keysA.length !== keys(b).length) { + break; + case 'Date': + if (!identical(a.valueOf(), b.valueOf())) { return false; } - var idx = stackA.length - 1; - while (idx >= 0) { - if (stackA[idx] === a) { - return stackB[idx] === b; - } - idx -= 1; + break; + case 'RegExp': + if (!(a.source === b.source && a.global === b.global && a.ignoreCase === b.ignoreCase && a.multiline === b.multiline && a.sticky === b.sticky && a.unicode === b.unicode)) { + return false; } - stackA[stackA.length] = a; - stackB[stackB.length] = b; - idx = keysA.length - 1; - while (idx >= 0) { - var key = keysA[idx]; - if (!_has(key, b) || !_equals(b[key], a[key], stackA, stackB)) { - return false; - } - idx -= 1; + break; + case 'Map': + case 'Set': + if (!_equals(_arrayFromIterator(a.entries()), _arrayFromIterator(b.entries()), stackA, stackB)) { + return false; } - stackA.pop(); - stackB.pop(); - return true; + break; + case 'Int8Array': + case 'Uint8Array': + case 'Uint8ClampedArray': + case 'Int16Array': + case 'Uint16Array': + case 'Int32Array': + case 'Uint32Array': + case 'Float32Array': + case 'Float64Array': + break; + case 'ArrayBuffer': + break; + default: + // Values of other types are only equal if identical. + return false; } - return false; - }; - - /** - * Private function that determines whether or not a provided object has a given method. - * Does not ignore methods stored on the object's prototype chain. Used for dynamically - * dispatching Ramda methods to non-Array objects. - * - * @private - * @param {String} methodName The name of the method to check for. - * @param {Object} obj The object to test. - * @return {Boolean} `true` has a given method, `false` otherwise. - * @example - * - * var person = { name: 'John' }; - * person.shout = function() { alert(this.name); }; - * - * _hasMethod('shout', person); //=> true - * _hasMethod('foo', person); //=> false - */ - var _hasMethod = function _hasMethod(methodName, obj) { - return obj != null && !_isArray(obj) && typeof obj[methodName] === 'function'; + var keysA = keys(a); + if (keysA.length !== keys(b).length) { + return false; + } + var idx = stackA.length - 1; + while (idx >= 0) { + if (stackA[idx] === a) { + return stackB[idx] === b; + } + idx -= 1; + } + stackA.push(a); + stackB.push(b); + idx = keysA.length - 1; + while (idx >= 0) { + var key = keysA[idx]; + if (!(_has(key, b) && _equals(b[key], a[key], stackA, stackB))) { + return false; + } + idx -= 1; + } + stackA.pop(); + stackB.pop(); + return true; }; /** @@ -4067,45 +4190,6 @@ }; }(); - var _stepCat = function () { - var _stepCatArray = { - '@@transducer/init': Array, - '@@transducer/step': function (xs, x) { - return _concat(xs, [x]); - }, - '@@transducer/result': _identity - }; - var _stepCatString = { - '@@transducer/init': String, - '@@transducer/step': function (a, b) { - return a + b; - }, - '@@transducer/result': _identity - }; - var _stepCatObject = { - '@@transducer/init': Object, - '@@transducer/step': function (result, input) { - return merge(result, isArrayLike(input) ? createMapEntry(input[0], input[1]) : input); - }, - '@@transducer/result': _identity - }; - return function _stepCat(obj) { - if (_isTransformer(obj)) { - return obj; - } - if (isArrayLike(obj)) { - return _stepCatArray; - } - if (typeof obj === 'string') { - return _stepCatString; - } - if (typeof obj === 'object') { - return _stepCatObject; - } - throw new Error('Cannot create transformer for ' + obj); - }; - }(); - var _xall = function () { function XAll(f, xf) { this.xf = xf; @@ -4156,6 +4240,35 @@ }); }(); + var _xaperture = function () { + function XAperture(n, xf) { + this.xf = xf; + this.pos = 0; + this.full = false; + this.acc = new Array(n); + } + XAperture.prototype['@@transducer/init'] = _xfBase.init; + XAperture.prototype['@@transducer/result'] = _xfBase.result; + XAperture.prototype['@@transducer/step'] = function (result, input) { + this.store(input); + return this.full ? this.xf['@@transducer/step'](result, this.getCopy()) : result; + }; + XAperture.prototype.store = function (input) { + this.acc[this.pos] = input; + this.pos += 1; + if (this.pos === this.acc.length) { + this.pos = 0; + this.full = true; + } + }; + XAperture.prototype.getCopy = function () { + return _concat(_slice(this.acc, this.pos), _slice(this.acc, 0, this.pos)); + }; + return _curry2(function _xaperture(n, xf) { + return new XAperture(n, xf); + }); + }(); + var _xdrop = function () { function XDrop(n, xf) { this.xf = xf; @@ -4241,6 +4354,7 @@ * * @func * @memberOf R + * @since v0.15.0 * @category Function * @category List * @sig ((a ... -> b) ... -> [a] -> *) -> (a ..., Int, [a] -> b) ... -> [a] -> *) @@ -4249,7 +4363,7 @@ * @example * * var mapIndexed = R.addIndex(R.map); - * mapIndexed(function(val, idx) {return idx + '-' + val;}, ['f', 'o', 'o', 'b', 'a', 'r']); + * mapIndexed((val, idx) => idx + '-' + val, ['f', 'o', 'o', 'b', 'a', 'r']); * //=> ['0-f', '1-o', '2-o', '3-b', '4-a', '5-r'] */ var addIndex = _curry1(function addIndex(fn) { @@ -4274,11 +4388,14 @@ * Returns `true` if all elements of the list match the predicate, `false` if there are any * that don't. * + * Dispatches to the `all` method of the second argument, if present. + * * Acts as a transducer if a transformer is given in list position. * @see R.transduce * * @func * @memberOf R + * @since v0.1.0 * @category List * @sig (a -> Boolean) -> [a] -> Boolean * @param {Function} fn The predicate function. @@ -4304,40 +4421,18 @@ return true; })); - /** - * A function that returns the first argument if it's falsy otherwise the second - * argument. Note that this is NOT short-circuited, meaning that if expressions - * are passed they are both evaluated. - * - * Dispatches to the `and` method of the first argument if applicable. - * - * @func - * @memberOf R - * @category Logic - * @sig * -> * -> * - * @param {*} a any value - * @param {*} b any other value - * @return {*} the first argument if falsy otherwise the second argument. - * @see R.both - * @example - * - * R.and(false, true); //=> false - * R.and(0, []); //=> 0 - * R.and(null, ''); => null - */ - var and = _curry2(function and(a, b) { - return _hasMethod('and', a) ? a.and(b) : a && b; - }); - /** * Returns `true` if at least one of elements of the list match the predicate, `false` * otherwise. * + * Dispatches to the `any` method of the second argument, if present. + * * Acts as a transducer if a transformer is given in list position. * @see R.transduce * * @func * @memberOf R + * @since v0.1.0 * @category List * @sig (a -> Boolean) -> [a] -> Boolean * @param {Function} fn The predicate function. @@ -4363,12 +4458,38 @@ return false; })); + /** + * Returns a new list, composed of n-tuples of consecutive elements + * If `n` is greater than the length of the list, an empty list is returned. + * + * Dispatches to the `aperture` method of the second argument, if present. + * + * Acts as a transducer if a transformer is given in list position. + * @see R.transduce + * + * @func + * @memberOf R + * @since v0.12.0 + * @category List + * @sig Number -> [a] -> [[a]] + * @param {Number} n The size of the tuples to create + * @param {Array} list The list to split into `n`-tuples + * @return {Array} The new list. + * @example + * + * R.aperture(2, [1, 2, 3, 4, 5]); //=> [[1, 2], [2, 3], [3, 4], [4, 5]] + * R.aperture(3, [1, 2, 3, 4, 5]); //=> [[1, 2, 3], [2, 3, 4], [3, 4, 5]] + * R.aperture(7, [1, 2, 3, 4, 5]); //=> [] + */ + var aperture = _curry2(_dispatchable('aperture', _xaperture, _aperture)); + /** * Wraps a function of any arity (including nullary) in a function that accepts exactly 2 * parameters. Any extraneous parameters will not be passed to the supplied function. * * @func * @memberOf R + * @since v0.2.0 * @category Function * @sig (* -> c) -> (a, b -> c) * @param {Function} fn The function to wrap. @@ -4392,12 +4513,13 @@ }); /** - * Creates a deep copy of the value which may contain (nested) `Array`s and - * `Object`s, `Number`s, `String`s, `Boolean`s and `Date`s. `Function`s are - * not copied, but assigned by their reference. + * Creates a deep copy of the value which may contain (nested) `Array`s and `Object`s, `Number`s, + * `String`s, `Boolean`s and `Date`s. `Function`s are not copied, but assigned by their + * reference. Dispatches to a `clone` method if present. * * @func * @memberOf R + * @since v0.1.0 * @category Object * @sig {*} -> {*} * @param {*} value The object or array to clone @@ -4409,39 +4531,31 @@ * objects[0] === objectsClone[0]; //=> false */ var clone = _curry1(function clone(value) { - return _clone(value, [], []); + return value != null && typeof value.clone === 'function' ? value.clone() : _clone(value, [], []); }); /** - * Returns a new list consisting of the elements of the first list followed by the elements - * of the second. + * Creates an object containing a single key:value pair. * * @func * @memberOf R - * @category List - * @sig [a] -> [a] -> [a] - * @param {Array} list1 The first list to merge. - * @param {Array} list2 The second set to merge. - * @return {Array} A new array consisting of the contents of `list1` followed by the - * contents of `list2`. If, instead of an Array for `list1`, you pass an - * object with a `concat` method on it, `concat` will call `list1.concat` - * and pass it the value of `list2`. - * + * @since v0.7.0 + * @category Object + * @sig String -> a -> {String:a} + * @param {String} key + * @param {*} val + * @return {Object} + * @see R.pair, R.objOf + * @deprecated since v0.18.0 * @example * - * R.concat([], []); //=> [] - * R.concat([4, 5, 6], [1, 2, 3]); //=> [4, 5, 6, 1, 2, 3] - * R.concat('ABC', 'DEF'); // 'ABCDEF' + * var matchPhrases = R.compose( + * R.createMapEntry('must'), + * R.map(R.createMapEntry('match_phrase')) + * ); + * matchPhrases(['foo', 'bar', 'baz']); //=> {must: [{match_phrase: 'foo'}, {match_phrase: 'bar'}, {match_phrase: 'baz'}]} */ - var concat = _curry2(function concat(set1, set2) { - if (_isArray(set2)) { - return _concat(set1, set2); - } else if (_hasMethod('concat', set1)) { - return set1.concat(set2); - } else { - throw new TypeError('can\'t concat ' + typeof set1); - } - }); + var createMapEntry = objOf; /** * Returns a curried equivalent of the provided function. The curried @@ -4469,6 +4583,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Function * @sig (* -> a) -> (* -> a) * @param {Function} fn The function to curry. @@ -4476,9 +4591,7 @@ * @see R.curryN * @example * - * var addFourNumbers = function(a, b, c, d) { - * return a + b + c + d; - * }; + * var addFourNumbers = (a, b, c, d) => a + b + c + d; * * var curriedAddFourNumbers = R.curry(addFourNumbers); * var f = curriedAddFourNumbers(1, 2); @@ -4494,11 +4607,14 @@ * to the supplied predicate function, skipping elements while the predicate function returns * `true`. The predicate function is passed one argument: *(value)*. * + * Dispatches to the `dropWhile` method of the second argument, if present. + * * Acts as a transducer if a transformer is given in list position. * @see R.transduce * * @func * @memberOf R + * @since v0.9.0 * @category List * @sig (a -> Boolean) -> [a] -> [a] * @param {Function} fn The function called per iteration. @@ -4507,9 +4623,7 @@ * @see R.takeWhile * @example * - * var lteTwo = function(x) { - * return x <= 2; - * }; + * var lteTwo = x => x <= 2; * * R.dropWhile(lteTwo, [1, 2, 3, 4, 3, 2, 1]); //=> [3, 4, 3, 2, 1] */ @@ -4526,8 +4640,11 @@ * Dispatches to an `equals` method if present. Handles cyclical data * structures. * + * Dispatches to the `equals` method of both arguments, if present. + * * @func * @memberOf R + * @since v0.15.0 * @category Relation * @sig a -> b -> Boolean * @param {*} a @@ -4544,7 +4661,7 @@ * R.equals(a, b); //=> true */ var equals = _curry2(function equals(a, b) { - return _hasMethod('equals', a) ? a.equals(b) : _hasMethod('equals', b) ? b.equals(a) : _equals(a, b, [], []); + return _equals(a, b, [], []); }); /** @@ -4555,11 +4672,14 @@ * `Array.prototype.filter` method. For more details on this behavior, see: * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter#Description * + * Dispatches to the `filter` method of the second argument, if present. + * * Acts as a transducer if a transformer is given in list position. * @see R.transduce * * @func * @memberOf R + * @since v0.1.0 * @category List * @sig (a -> Boolean) -> [a] -> [a] * @param {Function} fn The function called per iteration. @@ -4568,9 +4688,8 @@ * @see R.reject * @example * - * var isEven = function(n) { - * return n % 2 === 0; - * }; + * var isEven = n => n % 2 === 0; + * * R.filter(isEven, [1, 2, 3, 4]); //=> [2, 4] */ var filter = _curry2(_dispatchable('filter', _xfilter, _filter)); @@ -4579,11 +4698,14 @@ * Returns the first element of the list which matches the predicate, or `undefined` if no * element matches. * + * Dispatches to the `find` method of the second argument, if present. + * * Acts as a transducer if a transformer is given in list position. * @see R.transduce * * @func * @memberOf R + * @since v0.1.0 * @category List * @sig (a -> Boolean) -> [a] -> a | undefined * @param {Function} fn The predicate function used to determine if the element is the @@ -4611,11 +4733,14 @@ * Returns the index of the first element of the list which matches the predicate, or `-1` * if no element matches. * + * Dispatches to the `findIndex` method of the second argument, if present. + * * Acts as a transducer if a transformer is given in list position. * @see R.transduce * * @func * @memberOf R + * @since v0.1.1 * @category List * @sig (a -> Boolean) -> [a] -> Number * @param {Function} fn The predicate function used to determine if the element is the @@ -4644,11 +4769,14 @@ * Returns the last element of the list which matches the predicate, or `undefined` if no * element matches. * + * Dispatches to the `findLast` method of the second argument, if present. + * * Acts as a transducer if a transformer is given in list position. * @see R.transduce * * @func * @memberOf R + * @since v0.1.1 * @category List * @sig (a -> Boolean) -> [a] -> a | undefined * @param {Function} fn The predicate function used to determine if the element is the @@ -4675,11 +4803,14 @@ * Returns the index of the last element of the list which matches the predicate, or * `-1` if no element matches. * + * Dispatches to the `findLastIndex` method of the second argument, if present. + * * Acts as a transducer if a transformer is given in list position. * @see R.transduce * * @func * @memberOf R + * @since v0.1.1 * @category List * @sig (a -> Boolean) -> [a] -> Number * @param {Function} fn The predicate function used to determine if the element is the @@ -4709,6 +4840,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category List * @sig [a] -> [b] * @param {Array} list The array to consider. @@ -4727,15 +4859,14 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Function * @sig (a -> b -> c -> ... -> z) -> (b -> a -> c -> ... -> z) * @param {Function} fn The function to invoke with its first two parameters reversed. * @return {*} The result of invoking `fn` with its first two parameters' order reversed. * @example * - * var mergeThree = function(a, b, c) { - * return ([]).concat(a, b, c); - * }; + * var mergeThree = (a, b, c) => [].concat(a, b, c); * * mergeThree(1, 2, 3); //=> [1, 2, 3] * @@ -4763,8 +4894,11 @@ * Also note that, unlike `Array.prototype.forEach`, Ramda's `forEach` returns the original * array. In some libraries this function is named `each`. * + * Dispatches to the `forEach` method of the second argument, if present. + * * @func * @memberOf R + * @since v0.1.1 * @category List * @sig (a -> *) -> [a] -> [a] * @param {Function} fn The function to invoke. Receives one argument, `value`. @@ -4772,7 +4906,7 @@ * @return {Array} The original list. * @example * - * var printXPlusFive = function(x) { console.log(x + 5); }; + * var printXPlusFive = x => console.log(x + 5); * R.forEach(printXPlusFive, [1, 2, 3]); //=> [1, 2, 3] * //-> 6 * //-> 7 @@ -4793,10 +4927,12 @@ * * @func * @memberOf R + * @since v0.4.0 * @category Object * @sig {*} -> [String] * @param {Object} obj The objects with functions in it * @return {Array} A list of the object's own properties that map to functions. + * @deprecated since v0.18.0 * @example * * R.functions(R); // returns list of ramda's own function names @@ -4813,11 +4949,13 @@ * * @func * @memberOf R + * @since v0.4.0 * @category Object * @sig {*} -> [String] * @param {Object} obj The objects with functions in it * @return {Array} A list of the object's own properties and prototype * properties that map to functions. + * @deprecated since v0.18.0 * @example * * R.functionsIn(R); // returns list of ramda's own and prototype function names @@ -4833,11 +4971,14 @@ * Splits a list into sub-lists stored in an object, based on the result of calling a String-returning function * on each element, and grouping the results according to values returned. * + * Dispatches to the `groupBy` method of the second argument, if present. + * * Acts as a transducer if a transformer is given in list position. * @see R.transduce * * @func * @memberOf R + * @since v0.1.0 * @category List * @sig (a -> String) -> [a] -> {String: [a]} * @param {Function} fn Function :: a -> String @@ -4879,6 +5020,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category List * @see R.tail, R.init, R.last * @sig [a] -> a | Undefined @@ -4903,6 +5045,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Relation * @sig (a,a -> Boolean) -> [a] -> [a] -> [a] * @param {Function} pred A predicate function that determines whether @@ -4927,9 +5070,7 @@ * {id: 177, name: 'Neil Young'} * ]; * - * var sameId = function(o1, o2) {return o1.id === o2.id;}; - * - * R.intersectionWith(sameId, buffaloSpringfield, csny); + * R.intersectionWith(R.eqBy(R.prop('id')), buffaloSpringfield, csny); * //=> [{id: 456, name: 'Stephen Stills'}, {id: 177, name: 'Neil Young'}] */ var intersectionWith = _curry3(function intersectionWith(pred, list1, list2) { @@ -4946,8 +5087,11 @@ /** * Creates a new list with the separator interposed between elements. * + * Dispatches to the `intersperse` method of the second argument, if present. + * * @func * @memberOf R + * @since v0.14.0 * @category List * @sig a -> [a] -> [a] * @param {*} separator The element to add to the list. @@ -4973,50 +5117,13 @@ })); /** - * Transforms the items of the list with the transducer and appends the transformed items to - * the accumulator using an appropriate iterator function based on the accumulator type. - * - * The accumulator can be an array, string, object or a transformer. Iterated items will - * be appended to arrays and concatenated to strings. Objects will be merged directly or 2-item - * arrays will be merged as key, value pairs. - * - * The accumulator can also be a transformer object that provides a 2-arity reducing iterator - * function, step, 0-arity initial value function, init, and 1-arity result extraction function - * result. The step function is used as the iterator function in reduce. The result function is - * used to convert the final accumulator into the return type and in most cases is R.identity. - * The init function is used to provide the initial accumulator. - * - * The iteration is performed with R.reduce after initializing the transducer. - * - * @func - * @memberOf R - * @category List - * @sig a -> (b -> b) -> [c] -> a - * @param {*} acc The initial accumulator value. - * @param {Function} xf The transducer function. Receives a transformer and returns a transformer. - * @param {Array} list The list to iterate over. - * @return {*} The final, accumulated value. - * @example - * - * var numbers = [1, 2, 3, 4]; - * var transducer = R.compose(R.map(R.add(1)), R.take(2)); - * - * R.into([], transducer, numbers); //=> [2, 3] - * - * var intoArray = R.into([]); - * intoArray(transducer, numbers); //=> [2, 3] - */ - var into = _curry3(function into(acc, xf, list) { - return _isTransformer(acc) ? _reduce(xf(acc), acc['@@transducer/init'](), list) : _reduce(xf(_stepCat(acc)), acc, list); - }); - - /** - * Same as R.invertObj, however this accounts for objects - * with duplicate values by putting the values into an - * array. + * Same as R.invertObj, however this accounts for objects + * with duplicate values by putting the values into an + * array. * * @func * @memberOf R + * @since v0.9.0 * @category Object * @sig {s: x} -> {x: [ s, ... ]} * @param {Object} obj The object or array to invert @@ -5049,10 +5156,14 @@ /** * Returns a new object with the keys of the given object - * as values, and the values of the given object as keys. + * as values, and the values of the given object, which are + * coerced to strings, as keys. + * Note that the last key found is preferred when handling + * the same value. * * @func * @memberOf R + * @since v0.9.0 * @category Object * @sig {s: x} -> {x: s} * @param {Object} obj The object or array to invert @@ -5084,11 +5195,37 @@ return out; }); + /** + * Returns `true` if the given value is its type's empty value; `false` + * otherwise. + * + * @func + * @memberOf R + * @since v0.1.0 + * @category Logic + * @sig a -> Boolean + * @param {*} x + * @return {Boolean} + * @see R.empty + * @example + * + * R.isEmpty([1, 2, 3]); //=> false + * R.isEmpty([]); //=> true + * R.isEmpty(''); //=> true + * R.isEmpty(null); //=> false + * R.isEmpty({}); //=> true + * R.isEmpty({length: 0}); //=> false + */ + var isEmpty = _curry1(function isEmpty(x) { + return x != null && equals(x, empty(x)); + }); + /** * Returns the last element of the given list or string. * * @func * @memberOf R + * @since v0.1.4 * @category List * @see R.init, R.head, R.tail * @sig [a] -> a | Undefined @@ -5112,6 +5249,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category List * @sig a -> [a] -> Number * @param {*} target The item to find. @@ -5124,7 +5262,7 @@ * R.lastIndexOf(10, [1,2,3,4]); //=> -1 */ var lastIndexOf = _curry2(function lastIndexOf(target, xs) { - if (_hasMethod('lastIndexOf', xs)) { + if (typeof xs.lastIndexOf === 'function' && !_isArray(xs)) { return xs.lastIndexOf(target); } else { var idx = xs.length - 1; @@ -5146,25 +5284,44 @@ * native `Array.prototype.map` method. For more details on this behavior, see: * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map#Description * + * Dispatches to the `map` method of the second argument, if present. + * * Acts as a transducer if a transformer is given in list position. * @see R.transduce * + * Map treats also treats functions as functors and will compose them together. + * * @func * @memberOf R + * @since v0.1.0 * @category List - * @sig (a -> b) -> [a] -> [b] + * @sig Functor f => (a -> b) -> f a -> f b * @param {Function} fn The function to be called on every element of the input `list`. * @param {Array} list The list to be iterated over. * @return {Array} The new list. * @example * - * var double = function(x) { - * return x * 2; - * }; + * var double = x => x * 2; * * R.map(double, [1, 2, 3]); //=> [2, 4, 6] + * + * R.map(double, {x: 1, y: 2, z: 3}); //=> {x: 2, y: 4, z: 6} */ - var map = _curry2(_dispatchable('map', _xmap, _map)); + var map = _curry2(_dispatchable('map', _xmap, function map(fn, functor) { + switch (Object.prototype.toString.call(functor)) { + case '[object Function]': + return curryN(functor.length, function () { + return fn.call(this, functor.apply(this, arguments)); + }); + case '[object Object]': + return _reduce(function (acc, key) { + acc[key] = fn(functor[key]); + return acc; + }, {}, keys(functor)); + default: + return _map(fn, functor); + } + })); /** * Map, but for objects. Creates an object with the same keys as `obj` and values @@ -5173,6 +5330,7 @@ * * @func * @memberOf R + * @since v0.1.4 * @category Object * @sig (v -> v) -> {k: v} -> {k: v} * @param {Function} fn A function called for each property in `obj`. Its return value will @@ -5180,12 +5338,11 @@ * @param {Object} obj The object to iterate over. * @return {Object} A new object with the same keys as `obj` and values that are the result * of running each property through `fn`. + * @deprecated since v0.18.0 * @example * * var values = { x: 1, y: 2, z: 3 }; - * var double = function(num) { - * return num * 2; - * }; + * var double = num => num * 2; * * R.mapObj(double, values); //=> { x: 2, y: 4, z: 6 } */ @@ -5197,11 +5354,12 @@ }); /** - * Like `mapObj`, but but passes additional arguments to the predicate function. The + * Like `mapObj`, but passes additional arguments to the predicate function. The * predicate function is passed three arguments: *(value, key, obj)*. * * @func * @memberOf R + * @since v0.9.0 * @category Object * @sig (v, k, {k: v} -> v) -> {k: v} -> {k: v} * @param {Function} fn A function called for each property in `obj`. Its return value will @@ -5212,9 +5370,7 @@ * @example * * var values = { x: 1, y: 2, z: 3 }; - * var prependKeyAndDouble = function(num, key, obj) { - * return key + (num * 2); - * }; + * var prependKeyAndDouble = (num, key, obj) => key + (num * 2); * * R.mapObjIndexed(prependKeyAndDouble, values); //=> { x: 'x2', y: 'y4', z: 'z6' } */ @@ -5229,8 +5385,11 @@ * Returns `true` if no elements of the list match the predicate, * `false` otherwise. * + * Dispatches to the `any` method of the second argument, if present. + * * @func * @memberOf R + * @since v0.12.0 * @category List * @sig (a -> Boolean) -> [a] -> Boolean * @param {Function} fn The predicate function. @@ -5245,84 +5404,58 @@ var none = _curry2(_complement(_dispatchable('any', _xany, any))); /** - * A function that returns the first truthy of two arguments otherwise the - * last argument. Note that this is NOT short-circuited, meaning that if - * expressions are passed they are both evaluated. - * - * Dispatches to the `or` method of the first argument if applicable. - * - * @func - * @memberOf R - * @category Logic - * @sig * -> * -> * - * @param {*} a any value - * @param {*} b any other value - * @return {*} the first truthy argument, otherwise the last argument. - * @see R.either - * @example - * - * R.or(false, true); //=> true - * R.or(0, []); //=> [] - * R.or(null, ''); => '' - */ - var or = _curry2(function or(a, b) { - return _hasMethod('or', a) ? a.or(b) : a || b; - }); - - /** - * Accepts as its arguments a function and any number of values and returns a function that, - * when invoked, calls the original function with all of the values prepended to the - * original function's arguments list. In some libraries this function is named `applyLeft`. + * Takes a function `f` and a list of arguments, and returns a function `g`. + * When applied, `g` returns the result of applying `f` to the arguments + * provided initially followed by the arguments provided to `g`. * * @func * @memberOf R + * @since v0.10.0 * @category Function - * @sig (a -> b -> ... -> i -> j -> ... -> m -> n) -> a -> b-> ... -> i -> (j -> ... -> m -> n) - * @param {Function} fn The function to invoke. - * @param {...*} [args] Arguments to prepend to `fn` when the returned function is invoked. - * @return {Function} A new function wrapping `fn`. When invoked, it will call `fn` - * with `args` prepended to `fn`'s arguments list. + * @sig ((a, b, c, ..., n) -> x) -> [a, b, c, ...] -> ((d, e, f, ..., n) -> x) + * @param {Function} f + * @param {Array} args + * @return {Function} + * @see R.partialRight * @example * - * var multiply = function(a, b) { return a * b; }; - * var double = R.partial(multiply, 2); + * var multiply = (a, b) => a * b; + * var double = R.partial(multiply, [2]); * double(2); //=> 4 * - * var greet = function(salutation, title, firstName, lastName) { - * return salutation + ', ' + title + ' ' + firstName + ' ' + lastName + '!'; - * }; - * var sayHello = R.partial(greet, 'Hello'); - * var sayHelloToMs = R.partial(sayHello, 'Ms.'); + * var greet = (salutation, title, firstName, lastName) => + * salutation + ', ' + title + ' ' + firstName + ' ' + lastName + '!'; + * + * var sayHello = R.partial(greet, ['Hello']); + * var sayHelloToMs = R.partial(sayHello, ['Ms.']); * sayHelloToMs('Jane', 'Jones'); //=> 'Hello, Ms. Jane Jones!' */ - var partial = curry(_createPartialApplicator(_concat)); + var partial = _createPartialApplicator(_concat); /** - * Accepts as its arguments a function and any number of values and returns a function that, - * when invoked, calls the original function with all of the values appended to the original - * function's arguments list. - * - * Note that `partialRight` is the opposite of `partial`: `partialRight` fills `fn`'s arguments - * from the right to the left. In some libraries this function is named `applyRight`. + * Takes a function `f` and a list of arguments, and returns a function `g`. + * When applied, `g` returns the result of applying `f` to the arguments + * provided to `g` followed by the arguments provided initially. * * @func * @memberOf R + * @since v0.10.0 * @category Function - * @sig (a -> b-> ... -> i -> j -> ... -> m -> n) -> j -> ... -> m -> n -> (a -> b-> ... -> i) - * @param {Function} fn The function to invoke. - * @param {...*} [args] Arguments to append to `fn` when the returned function is invoked. - * @return {Function} A new function wrapping `fn`. When invoked, it will call `fn` with - * `args` appended to `fn`'s arguments list. + * @sig ((a, b, c, ..., n) -> x) -> [d, e, f, ..., n] -> ((a, b, c, ...) -> x) + * @param {Function} f + * @param {Array} args + * @return {Function} + * @see R.partial * @example * - * var greet = function(salutation, title, firstName, lastName) { - * return salutation + ', ' + title + ' ' + firstName + ' ' + lastName + '!'; - * }; - * var greetMsJaneJones = R.partialRight(greet, 'Ms.', 'Jane', 'Jones'); + * var greet = (salutation, title, firstName, lastName) => + * salutation + ', ' + title + ' ' + firstName + ' ' + lastName + '!'; + * + * var greetMsJaneJones = R.partialRight(greet, ['Ms.', 'Jane', 'Jones']); * * greetMsJaneJones('Hello'); //=> 'Hello, Ms. Jane Jones!' */ - var partialRight = curry(_createPartialApplicator(flip(_concat))); + var partialRight = _createPartialApplicator(flip(_concat)); /** * Takes a predicate and a list and returns the pair of lists of @@ -5330,6 +5463,7 @@ * * @func * @memberOf R + * @since v0.1.4 * @category List * @sig (a -> Boolean) -> [a] -> [[a],[a]] * @param {Function} pred A predicate to determine which array the element belongs to. @@ -5358,6 +5492,7 @@ * * @func * @memberOf R + * @since v0.7.0 * @category Relation * @sig [String] -> * -> {String: *} -> Boolean * @param {Array} path The path of the nested property to use @@ -5383,11 +5518,13 @@ * * @func * @memberOf R + * @since v0.1.0 * @category List * @sig k -> [{k: v}] -> [v] * @param {Number|String} key The key name to pluck off of each object. * @param {Array} list The array to consider. * @return {Array} The list of values for the given key. + * @see R.props * @example * * R.pluck('a')([{a: 1}, {a: 2}]); //=> [1, 2] @@ -5403,6 +5540,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Relation * @sig String -> a -> Object -> Boolean * @param {String} name @@ -5430,6 +5568,7 @@ * * @func * @memberOf R + * @since v0.16.0 * @category Type * @sig Type -> String -> Object -> Boolean * @param {Function} type @@ -5461,8 +5600,11 @@ * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce#Description * @see R.reduced * + * Dispatches to the `reduce` method of the third argument, if present. + * * @func * @memberOf R + * @since v0.1.0 * @category List * @sig (a,b -> a) -> a -> [b] -> a * @param {Function} fn The iterator function. Receives two values, the accumulator and the @@ -5473,9 +5615,7 @@ * @example * * var numbers = [1, 2, 3]; - * var add = function(a, b) { - * return a + b; - * }; + * var add = (a, b) => a + b; * * R.reduce(add, 10, numbers); //=> 16 */ @@ -5490,6 +5630,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category List * @sig (a -> Boolean) -> [a] -> [a] * @param {Function} fn The function called per iteration. @@ -5498,9 +5639,8 @@ * @see R.filter * @example * - * var isOdd = function(n) { - * return n % 2 === 1; - * }; + * var isOdd = (n) => n % 2 === 1; + * * R.reject(isOdd, [1, 2, 3, 4]); //=> [2, 4] */ var reject = _curry2(function reject(fn, list) { @@ -5512,6 +5652,7 @@ * * @func * @memberOf R + * @since v0.1.1 * @category List * @sig a -> n -> [a] * @param {*} value The value to repeat. @@ -5533,8 +5674,11 @@ * Returns the elements of the given list or string (or object with a `slice` * method) from `fromIndex` (inclusive) to `toIndex` (exclusive). * + * Dispatches to the `slice` method of the third argument, if present. + * * @func * @memberOf R + * @since v0.1.4 * @category List * @sig Number -> Number -> [a] -> [a] * @sig Number -> Number -> String -> String @@ -5559,6 +5703,7 @@ * * @func * @memberOf R + * @since v0.16.0 * @category List * @sig Number -> [a] -> [[a]] * @sig Number -> String -> [String] @@ -5587,6 +5732,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Math * @sig [Number] -> Number * @param {Array} list An array of numbers @@ -5602,8 +5748,11 @@ * Returns all but the first element of the given list or string (or object * with a `tail` method). * + * Dispatches to the `slice` method of the first argument, if present. + * * @func * @memberOf R + * @since v0.1.0 * @category List * @see R.head, R.init, R.last * @sig [a] -> [a] @@ -5628,8 +5777,11 @@ * Returns the first `n` elements of the given list, string, or * transducer/transformer (or object with a `take` method). * + * Dispatches to the `take` method of the second argument, if present. + * * @func * @memberOf R + * @since v0.1.0 * @category List * @sig Number -> [a] -> [a] * @sig Number -> String -> String @@ -5670,11 +5822,14 @@ * `false`. Excludes the element that caused the predicate function to fail. The predicate * function is passed one argument: *(value)*. * + * Dispatches to the `takeWhile` method of the second argument, if present. + * * Acts as a transducer if a transformer is given in list position. * @see R.transduce * * @func * @memberOf R + * @since v0.1.0 * @category List * @sig (a -> Boolean) -> [a] -> [a] * @param {Function} fn The function called per iteration. @@ -5683,9 +5838,7 @@ * @see R.dropWhile * @example * - * var isNotFour = function(x) { - * return !(x === 4); - * }; + * var isNotFour = x => x !== 4; * * R.takeWhile(isNotFour, [1, 2, 3, 4]); //=> [1, 2, 3] */ @@ -5721,6 +5874,7 @@ * * @func * @memberOf R + * @since v0.12.0 * @category List * @see R.reduce, R.reduced, R.into * @sig (c -> c) -> (a,b -> a) -> a -> [b] -> a @@ -5748,6 +5902,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Relation * @sig (a,a -> Boolean) -> [a] -> [a] -> [a] * @param {Function} pred A predicate used to test whether two items are equal. @@ -5758,10 +5913,9 @@ * @see R.union * @example * - * function cmp(x, y) { return x.a === y.a; } * var l1 = [{a: 1}, {a: 2}]; * var l2 = [{a: 1}, {a: 4}]; - * R.unionWith(cmp, l1, l2); //=> [{a: 1}, {a: 2}, {a: 4}] + * R.unionWith(R.eqBy(R.prop('a')), l1, l2); //=> [{a: 1}, {a: 2}, {a: 4}] */ var unionWith = _curry3(function unionWith(pred, list1, list2) { return uniqWith(pred, _concat(list1, list2)); @@ -5773,6 +5927,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category List * @sig [a] -> [a] * @param {Array} list The array to consider. @@ -5786,25 +5941,7 @@ var uniq = uniqWith(equals); /** - * Returns a new list by pulling every item at the first level of nesting out, and putting - * them in a new array. - * - * @func - * @memberOf R - * @category List - * @sig [a] -> [b] - * @param {Array} list The array to consider. - * @return {Array} The flattened list. - * @see R.flatten - * @example - * - * R.unnest([1, [2], [[3]]]); //=> [1, 2, [3]] - * R.unnest([[1, 2], [3, 4], [5, 6]]); //=> [1, 2, 3, 4, 5, 6] - */ - var unnest = _curry1(_makeFlat(false)); - - /** - * Accepts a function `fn` and any number of transformer functions and returns a new + * Accepts a function `fn` and a list of transformer functions and returns a new curried * function. When the new function is invoked, it calls the function `fn` with parameters * consisting of the result of calling each supplied handler on successive arguments to the * new function. @@ -5816,50 +5953,27 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Function - * @sig (x1 -> x2 -> ... -> z) -> ((a -> x1), (b -> x2), ...) -> (a -> b -> ... -> z) + * @sig (x1 -> x2 -> ... -> z) -> [(a -> x1), (b -> x2), ...] -> (a -> b -> ... -> z) * @param {Function} fn The function to wrap. - * @param {...Function} transformers A variable number of transformer functions + * @param {Array} transformers A list of transformer functions * @return {Function} The wrapped function. * @example * - * var double = function(y) { return y * 2; }; - * var square = function(x) { return x * x; }; - * var add = function(a, b) { return a + b; }; - * // Adds any number of arguments together - * var addAll = function() { - * return R.reduce(add, 0, arguments); - * }; - * - * // Basic example - * var addDoubleAndSquare = R.useWith(addAll, double, square); - * - * //≅ addAll(double(10), square(5)); - * addDoubleAndSquare(10, 5); //=> 45 - * - * // Example of passing more arguments than transformers - * //≅ addAll(double(10), square(5), 100); - * addDoubleAndSquare(10, 5, 100); //=> 145 - * - * // If there are extra _expected_ arguments that don't need to be transformed, although - * // you can ignore them, it might be best to pass in the identity function so that the new - * // function correctly reports arity. - * var addDoubleAndSquareWithExtraParams = R.useWith(addAll, double, square, R.identity); - * // addDoubleAndSquareWithExtraParams.length //=> 3 - * //≅ addAll(double(10), square(5), R.identity(100)); - * addDoubleAndSquare(10, 5, 100); //=> 145 - */ - /*, transformers */ - var useWith = curry(function useWith(fn) { - var transformers = _slice(arguments, 1); - var tlen = transformers.length; - return curry(_arity(tlen, function () { + * R.useWith(Math.pow, [R.identity, R.identity])(3, 4); //=> 81 + * R.useWith(Math.pow, [R.identity, R.identity])(3)(4); //=> 81 + * R.useWith(Math.pow, [R.dec, R.inc])(3, 4); //=> 32 + * R.useWith(Math.pow, [R.dec, R.inc])(3)(4); //=> 32 + */ + var useWith = _curry2(function useWith(fn, transformers) { + return curry(_arity(transformers.length, function () { var args = [], idx = 0; - while (idx < tlen) { - args[idx] = transformers[idx](arguments[idx]); + while (idx < transformers.length) { + args.push(transformers[idx].call(this, arguments[idx])); idx += 1; } - return fn.apply(this, args.concat(_slice(arguments, tlen))); + return fn.apply(this, args.concat(_slice(arguments, transformers.length))); })); }); @@ -5873,6 +5987,7 @@ * * @func * @memberOf R + * @since v0.14.0 * @category Object * @sig {String: *} -> {String: *} -> Boolean * @param {Object} spec @@ -5931,83 +6046,164 @@ return -1; }; - /** - * Create a predicate wrapper which will call a pick function (all/any) for each predicate - * - * @private - * @see R.all - * @see R.any - */ - // Call function immediately if given arguments - // Return a function which will call the predicates with the provided arguments - var _predicateWrap = function _predicateWrap(predPicker) { - return function (preds) { - var predIterator = function () { - var args = arguments; - return predPicker(function (predicate) { - return predicate.apply(null, args); - }, preds); - }; - return arguments.length > 1 ? // Call function immediately if given arguments - predIterator.apply(null, _slice(arguments, 1)) : // Return a function which will call the predicates with the provided arguments - _arity(Math.max.apply(Math, pluck('length', preds)), predIterator); + var _stepCat = function () { + var _stepCatArray = { + '@@transducer/init': Array, + '@@transducer/step': function (xs, x) { + return _concat(xs, [x]); + }, + '@@transducer/result': _identity }; - }; + var _stepCatString = { + '@@transducer/init': String, + '@@transducer/step': function (a, b) { + return a + b; + }, + '@@transducer/result': _identity + }; + var _stepCatObject = { + '@@transducer/init': Object, + '@@transducer/step': function (result, input) { + return merge(result, isArrayLike(input) ? createMapEntry(input[0], input[1]) : input); + }, + '@@transducer/result': _identity + }; + return function _stepCat(obj) { + if (_isTransformer(obj)) { + return obj; + } + if (isArrayLike(obj)) { + return _stepCatArray; + } + if (typeof obj === 'string') { + return _stepCatString; + } + if (typeof obj === 'object') { + return _stepCatObject; + } + throw new Error('Cannot create transformer for ' + obj); + }; + }(); var _xchain = _curry2(function _xchain(f, xf) { return map(f, _flatCat(xf)); }); /** - * Given a list of predicates, returns a new predicate that will be true exactly when all of them are. + * Takes a list of predicates and returns a predicate that returns true + * for a given list of arguments if every one of the provided predicates + * is satisfied by those arguments. + * + * The function returned is a curried function whose arity matches that of + * the highest-arity predicate. * * @func * @memberOf R + * @since v0.9.0 * @category Logic * @sig [(*... -> Boolean)] -> (*... -> Boolean) - * @param {Array} list An array of predicate functions - * @param {*} optional Any arguments to pass into the predicates - * @return {Function} a function that applies its arguments to each of - * the predicates, returning `true` if all are satisfied. + * @param {Array} preds + * @return {Function} * @see R.anyPass * @example * - * var gt10 = function(x) { return x > 10; }; - * var even = function(x) { return x % 2 === 0}; - * var f = R.allPass([gt10, even]); - * f(11); //=> false - * f(12); //=> true + * var isQueen = R.propEq('rank', 'Q'); + * var isSpade = R.propEq('suit', '♠︎'); + * var isQueenOfSpades = R.allPass([isQueen, isSpade]); + * + * isQueenOfSpades({rank: 'Q', suit: '♣︎'}); //=> false + * isQueenOfSpades({rank: 'Q', suit: '♠︎'}); //=> true */ - var allPass = _curry1(_predicateWrap(all)); + var allPass = _curry1(function allPass(preds) { + return curryN(reduce(max, 0, pluck('length', preds)), function () { + var idx = 0; + var len = preds.length; + while (idx < len) { + if (!preds[idx].apply(this, arguments)) { + return false; + } + idx += 1; + } + return true; + }); + }); /** - * Given a list of predicates returns a new predicate that will be true exactly when any one of them is. + * Returns `true` if all elements are unique, in `R.equals` terms, + * otherwise `false`. * * @func * @memberOf R + * @since v0.18.0 + * @category List + * @sig [a] -> Boolean + * @param {Array} list The array to consider. + * @return {Boolean} `true` if all elements are unique, else `false`. + * @example + * + * R.allUniq(['1', 1]); //=> true + * R.allUniq([1, 1]); //=> false + * R.allUniq([[42], [42]]); //=> false + */ + var allUniq = _curry1(function allUniq(list) { + var len = list.length; + var idx = 0; + while (idx < len) { + if (_indexOf(list, list[idx], idx + 1) >= 0) { + return false; + } + idx += 1; + } + return true; + }); + + /** + * Takes a list of predicates and returns a predicate that returns true for + * a given list of arguments if at least one of the provided predicates is + * satisfied by those arguments. + * + * The function returned is a curried function whose arity matches that of + * the highest-arity predicate. + * + * @func + * @memberOf R + * @since v0.9.0 * @category Logic * @sig [(*... -> Boolean)] -> (*... -> Boolean) - * @param {Array} list An array of predicate functions - * @param {*} optional Any arguments to pass into the predicates - * @return {Function} A function that applies its arguments to each of the predicates, returning - * `true` if all are satisfied. + * @param {Array} preds + * @return {Function} * @see R.allPass * @example * - * var gt10 = function(x) { return x > 10; }; - * var even = function(x) { return x % 2 === 0}; - * var f = R.anyPass([gt10, even]); - * f(11); //=> true - * f(8); //=> true - * f(9); //=> false + * var gte = R.anyPass([R.gt, R.equals]); + * + * gte(3, 2); //=> true + * gte(2, 2); //=> true + * gte(2, 3); //=> false */ - var anyPass = _curry1(_predicateWrap(any)); + var anyPass = _curry1(function anyPass(preds) { + return curryN(reduce(max, 0, pluck('length', preds)), function () { + var idx = 0; + var len = preds.length; + while (idx < len) { + if (preds[idx].apply(this, arguments)) { + return true; + } + idx += 1; + } + return false; + }); + }); /** * ap applies a list of functions to a list of values. * + * Dispatches to the `ap` method of the second argument, if present. Also treats + * functions as applicatives. + * * @func * @memberOf R + * @since v0.3.0 * @category Function * @sig [f] -> [a] -> [f a] * @param {Array} fns An array of functions @@ -6017,10 +6213,14 @@ * * R.ap([R.multiply(2), R.add(3)], [1,2,3]); //=> [2, 4, 6, 4, 5, 6] */ - var ap = _curry2(function ap(fns, vs) { - return _hasMethod('ap', fns) ? fns.ap(vs) : _reduce(function (acc, fn) { - return _concat(acc, map(fn, vs)); - }, [], fns); + // else + var ap = _curry2(function ap(applicative, fn) { + return typeof applicative.ap === 'function' ? applicative.ap(fn) : typeof applicative === 'function' ? curryN(Math.max(applicative.length, fn.length), function () { + return applicative.apply(this, arguments)(fn.apply(this, arguments)); + }) : // else + _reduce(function (acc, f) { + return _concat(acc, map(f, fn)); + }, [], applicative); }); /** @@ -6031,6 +6231,7 @@ * * @func * @memberOf R + * @since v0.9.0 * @category Function * @sig (*... -> a),*... -> a * @param {Function} fn The function to apply to the remaining arguments. @@ -6055,12 +6256,13 @@ /** * `chain` maps a function over a list and concatenates the results. - * This implementation is compatible with the - * Fantasy-land Chain spec, and will work with types that implement that spec. * `chain` is also known as `flatMap` in some libraries * + * Dispatches to the `chain` method of the second argument, if present. + * * @func * @memberOf R + * @since v0.3.0 * @category List * @sig (a -> [b]) -> [a] -> [b] * @param {Function} fn @@ -6068,13 +6270,16 @@ * @return {Array} * @example * - * var duplicate = function(n) { - * return [n, n]; - * }; + * var duplicate = n => [n, n]; * R.chain(duplicate, [1, 2, 3]); //=> [1, 1, 2, 2, 3, 3] */ - var chain = _curry2(_dispatchable('chain', _xchain, function chain(fn, list) { - return unnest(map(fn, list)); + var chain = _curry2(_dispatchable('chain', _xchain, function chain(fn, monad) { + if (typeof monad === 'function') { + return function () { + return monad.call(this, fn.apply(this, arguments)).apply(this, arguments); + }; + } + return _makeFlat(false)(map(fn, monad)); })); /** @@ -6083,26 +6288,34 @@ * * @func * @memberOf R + * @since v0.8.0 * @category List * @see R.commute - * @sig Functor f => (f a -> f b) -> (x -> f x) -> [f a] -> f [b] + * @sig Functor f => (a -> f b) -> (x -> f x) -> [a] -> f [b] * @param {Function} fn The transformation function * @param {Function} of A function that returns the data type to return * @param {Array} list An array of functors of the same type * @return {*} * @example * - * R.commuteMap(R.map(R.add(10)), R.of, [[1], [2, 3]]); //=> [[11, 12], [11, 13]] - * R.commuteMap(R.map(R.add(10)), R.of, [[1, 2], [3]]); //=> [[11, 13], [12, 13]] - * R.commuteMap(R.map(R.add(10)), R.of, [[1], [2], [3]]); //=> [[11, 12, 13]] - * R.commuteMap(R.map(R.add(10)), Maybe.of, [Just(1), Just(2), Just(3)]); //=> Just([11, 12, 13]) - * R.commuteMap(R.map(R.add(10)), Maybe.of, [Just(1), Just(2), Nothing()]); //=> Nothing() + * var add10 = R.map(R.add(10)); + * R.commuteMap(add10, R.of, [[1], [2, 3]]); //=> [[11, 12], [11, 13]] + * R.commuteMap(add10, R.of, [[1, 2], [3]]); //=> [[11, 13], [12, 13]] + * R.commuteMap(add10, R.of, [[1], [2], [3]]); //=> [[11, 12, 13]] + * R.commuteMap(add10, Maybe.of, [Just(1), Just(2), Just(3)]); //=> Just([11, 12, 13]) + * R.commuteMap(add10, Maybe.of, [Just(1), Just(2), Nothing()]); //=> Nothing() + * + * var fetch = url => Future((rej, res) => http.get(url, res).on('error', rej)); + * R.commuteMap(fetch, Future.of, [ + * 'http://ramdajs.com', + * 'http://github.com/ramda' + * ]); //=> Future([IncomingMessage, IncomingMessage]) */ var commuteMap = _curry3(function commuteMap(fn, of, list) { - function consF(acc, ftor) { - return ap(map(append, fn(ftor)), acc); + function consF(acc, x) { + return ap(map(prepend, fn(x)), acc); } - return _reduce(consF, of([]), list); + return reduceRight(consF, of([]), list); }); /** @@ -6112,6 +6325,7 @@ * * @func * @memberOf R + * @since v0.4.0 * @category Function * @sig Number -> (* -> {*}) -> (* -> {*}) * @param {Number} n The arity of the constructor function. @@ -6120,7 +6334,7 @@ * @example * * // Variadic constructor function - * var Widget = function() { + * var Widget = () => { * this.children = Array.prototype.slice.call(arguments); * // ... * }; @@ -6168,33 +6382,33 @@ }); /** - * Accepts at least three functions and returns a new function. When invoked, this new - * function will invoke the first function, `after`, passing as its arguments the - * results of invoking the subsequent functions with whatever arguments are passed to - * the new function. + * Accepts a converging function and a list of branching functions and returns a new function. + * When invoked, this new function is applied to some arguments, each branching + * function is applied to those same arguments. The results of each branching + * function are passed as arguments to the converging function to produce the return value. * * @func * @memberOf R + * @since v0.4.2 * @category Function - * @sig (x1 -> x2 -> ... -> z) -> ((a -> b -> ... -> x1), (a -> b -> ... -> x2), ...) -> (a -> b -> ... -> z) + * @sig (x1 -> x2 -> ... -> z) -> [(a -> b -> ... -> x1), (a -> b -> ... -> x2), ...] -> (a -> b -> ... -> z) * @param {Function} after A function. `after` will be invoked with the return values of * `fn1` and `fn2` as its arguments. - * @param {...Function} functions A variable number of functions. + * @param {Array} functions A list of functions. * @return {Function} A new function. * @example * - * var add = function(a, b) { return a + b; }; - * var multiply = function(a, b) { return a * b; }; - * var subtract = function(a, b) { return a - b; }; + * var add = (a, b) => a + b; + * var multiply = (a, b) => a * b; + * var subtract = (a, b) => a - b; * * //≅ multiply( add(1, 2), subtract(1, 2) ); - * R.converge(multiply, add, subtract)(1, 2); //=> -3 + * R.converge(multiply, [add, subtract])(1, 2); //=> -3 * - * var add3 = function(a, b, c) { return a + b + c; }; - * R.converge(add3, multiply, add, subtract)(1, 2); //=> 4 + * var add3 = (a, b, c) => a + b + c; + * R.converge(add3, [multiply, add, subtract])(1, 2); //=> 4 */ - var converge = curryN(3, function converge(after) { - var fns = _slice(arguments, 1); + var converge = _curry2(function converge(after, fns) { return curryN(Math.max.apply(Math, pluck('length', fns)), function () { var args = arguments; var context = this; @@ -6208,8 +6422,11 @@ * Returns all but the first `n` elements of the given list, string, or * transducer/transformer (or object with a `drop` method). * + * Dispatches to the `drop` method of the second argument, if present. + * * @func * @memberOf R + * @since v0.1.0 * @category List * @see R.transduce * @sig Number -> [a] -> [a] @@ -6235,6 +6452,7 @@ * * @func * @memberOf R + * @since v0.16.0 * @category List * @sig Number -> [a] -> [a] * @sig Number -> String -> String @@ -6259,11 +6477,14 @@ * determined by applying the supplied predicate two consecutive elements. * The first element in a series of equal element is the one being preserved. * + * Dispatches to the `dropRepeatsWith` method of the second argument, if present. + * * Acts as a transducer if a transformer is given in list position. * @see R.transduce * * @func * @memberOf R + * @since v0.14.0 * @category List * @sig (a, a -> Boolean) -> [a] -> [a] * @param {Function} pred A predicate used to test whether two items are equal. @@ -6271,9 +6492,9 @@ * @return {Array} `list` without repeating elements. * @example * - * function lengthEq(x, y) { return Math.abs(x) === Math.abs(y); }; + * var lengthEq = (x, y) => Math.abs(x) === Math.abs(y); * var l = [1, -1, 1, 3, 4, -4, -4, -5, 5, 3, 3]; - * R.dropRepeatsWith(lengthEq, l); //=> [1, 3, 4, -5, 3] + * R.dropRepeatsWith(R.eqBy(Math.abs), l); //=> [1, 3, 4, -5, 3] */ var dropRepeatsWith = _curry2(_dispatchable('dropRepeatsWith', _xdropRepeatsWith, function dropRepeatsWith(pred, list) { var result = []; @@ -6291,12 +6512,34 @@ return result; })); + /** + * Takes a function and two values in its domain and returns `true` if + * the values map to the same value in the codomain; `false` otherwise. + * + * @func + * @memberOf R + * @since v0.18.0 + * @category Relation + * @sig (a -> b) -> a -> a -> Boolean + * @param {Function} f + * @param {*} x + * @param {*} y + * @return {Boolean} + * @example + * + * R.eqBy(Math.abs, 5, -5); //=> true + */ + var eqBy = _curry3(function eqBy(f, x, y) { + return equals(f(x), f(y)); + }); + /** * Reports whether two objects have the same value, in `R.equals` terms, * for the specified property. Useful as a curried predicate. * * @func * @memberOf R + * @since v0.1.0 * @category Object * @sig k -> {k: v} -> {k: v} -> Boolean * @param {String} prop The name of the property to compare @@ -6322,6 +6565,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category List * @sig a -> [a] -> Number * @param {*} target The item to find. @@ -6334,7 +6578,7 @@ * R.indexOf(10, [1,2,3,4]); //=> -1 */ var indexOf = _curry2(function indexOf(target, xs) { - return _hasMethod('indexOf', xs) ? xs.indexOf(target) : _indexOf(xs, target, 0); + return typeof xs.indexOf === 'function' && !_isArray(xs) ? xs.indexOf(target) : _indexOf(xs, target, 0); }); /** @@ -6342,6 +6586,7 @@ * * @func * @memberOf R + * @since v0.9.0 * @category List * @see R.last, R.head, R.tail * @sig [a] -> [a] @@ -6362,33 +6607,65 @@ */ var init = slice(0, -1); + /** + * Transforms the items of the list with the transducer and appends the transformed items to + * the accumulator using an appropriate iterator function based on the accumulator type. + * + * The accumulator can be an array, string, object or a transformer. Iterated items will + * be appended to arrays and concatenated to strings. Objects will be merged directly or 2-item + * arrays will be merged as key, value pairs. + * + * The accumulator can also be a transformer object that provides a 2-arity reducing iterator + * function, step, 0-arity initial value function, init, and 1-arity result extraction function + * result. The step function is used as the iterator function in reduce. The result function is + * used to convert the final accumulator into the return type and in most cases is R.identity. + * The init function is used to provide the initial accumulator. + * + * The iteration is performed with R.reduce after initializing the transducer. + * + * @func + * @memberOf R + * @since v0.12.0 + * @category List + * @sig a -> (b -> b) -> [c] -> a + * @param {*} acc The initial accumulator value. + * @param {Function} xf The transducer function. Receives a transformer and returns a transformer. + * @param {Array} list The list to iterate over. + * @return {*} The final, accumulated value. + * @example + * + * var numbers = [1, 2, 3, 4]; + * var transducer = R.compose(R.map(R.add(1)), R.take(2)); + * + * R.into([], transducer, numbers); //=> [2, 3] + * + * var intoArray = R.into([]); + * intoArray(transducer, numbers); //=> [2, 3] + */ + var into = _curry3(function into(acc, xf, list) { + return _isTransformer(acc) ? _reduce(xf(acc), acc['@@transducer/init'](), list) : _reduce(xf(_stepCat(acc)), acc, list); + }); + /** * Returns `true` if all elements are unique, in `R.equals` terms, * otherwise `false`. * * @func * @memberOf R + * @since v0.1.1 * @category List * @sig [a] -> Boolean * @param {Array} list The array to consider. * @return {Boolean} `true` if all elements are unique, else `false`. + * @see R.allUniq + * @deprecated since v0.18.0 * @example * * R.isSet(['1', 1]); //=> true * R.isSet([1, 1]); //=> false * R.isSet([[42], [42]]); //=> false */ - var isSet = _curry1(function isSet(list) { - var len = list.length; - var idx = 0; - while (idx < len) { - if (_indexOf(list, list[idx], idx + 1) >= 0) { - return false; - } - idx += 1; - } - return true; - }); + var isSet = allUniq; /** * Returns a lens for the given getter and setter functions. The getter "gets" @@ -6397,6 +6674,7 @@ * * @func * @memberOf R + * @since v0.8.0 * @category Object * @typedefn Lens s a = Functor f => (a -> f a) -> s -> f s * @sig (s -> a) -> ((a, s) -> s) -> Lens s a @@ -6427,6 +6705,7 @@ * * @func * @memberOf R + * @since v0.14.0 * @category Object * @typedefn Lens s a = Functor f => (a -> f a) -> s -> f s * @sig Number -> Lens s a @@ -6450,6 +6729,7 @@ * * @func * @memberOf R + * @since v0.14.0 * @category Object * @typedefn Lens s a = Functor f => (a -> f a) -> s -> f s * @sig String -> Lens s a @@ -6474,6 +6754,7 @@ * * @func * @memberOf R + * @since v0.7.0 * @see R.lift * @category Function * @sig Number -> (*... -> *) -> ([*]... -> [*]) @@ -6481,9 +6762,7 @@ * @return {Function} The function `fn` applicable to mappable objects. * @example * - * var madd3 = R.liftN(3, R.curryN(3, function() { - * return R.reduce(R.add, 0, arguments); - * })); + * var madd3 = R.liftN(3, R.curryN(3, () => R.reduce(R.add, 0, arguments))); * madd3([1,2,3], [1,2,3], [1]); //=> [3, 4, 5, 4, 5, 6, 5, 6, 7] */ var liftN = _curry2(function liftN(arity, fn) { @@ -6498,6 +6777,7 @@ * * @func * @memberOf R + * @since v0.14.0 * @category Math * @sig [Number] -> Number * @param {Array} list @@ -6516,6 +6796,7 @@ * * @func * @memberOf R + * @since v0.14.0 * @category Math * @sig [Number] -> Number * @param {Array} list @@ -6543,6 +6824,7 @@ * * @func * @memberOf R + * @since v0.10.0 * @category List * @sig [{k: v}] -> {k: v} * @param {Array} list An array of objects @@ -6565,8 +6847,9 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Function - * @sig (((a, b, ..., n) -> o), (o -> p), ..., (x -> y), (y -> z)) -> (a -> b -> ... -> n -> z) + * @sig (((a, b, ..., n) -> o), (o -> p), ..., (x -> y), (y -> z)) -> ((a, b, ..., n) -> z) * @param {...Function} functions * @return {Function} * @see R.compose @@ -6580,7 +6863,7 @@ if (arguments.length === 0) { throw new Error('pipe requires at least one argument'); } - return curryN(arguments[0].length, reduce(_pipe, arguments[0], tail(arguments))); + return _arity(arguments[0].length, reduce(_pipe, arguments[0], tail(arguments))); }; /** @@ -6590,6 +6873,7 @@ * * @func * @memberOf R + * @since v0.10.0 * @category Function * @sig ((a -> Promise b), (b -> Promise c), ..., (y -> Promise z)) -> (a -> Promise z) * @param {...Function} functions @@ -6604,7 +6888,7 @@ if (arguments.length === 0) { throw new Error('pipeP requires at least one argument'); } - return curryN(arguments[0].length, reduce(_pipeP, arguments[0], tail(arguments))); + return _arity(arguments[0].length, reduce(_pipeP, arguments[0], tail(arguments))); }; /** @@ -6612,6 +6896,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Math * @sig [Number] -> Number * @param {Array} list An array of numbers @@ -6628,6 +6913,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Object * @category Relation * @sig [k] -> [{k: v}] -> [{k: v}] @@ -6642,7 +6928,10 @@ * R.project(['name', 'grade'], kids); //=> [{name: 'Abby', grade: 2}, {name: 'Fred', grade: 7}] */ // passing `identity` gives correct arity - var project = useWith(_map, pickAll, identity); + var project = useWith(_map, [ + pickAll, + identity + ]); /** * Returns a new list containing the last `n` elements of the given list. @@ -6650,6 +6939,7 @@ * * @func * @memberOf R + * @since v0.16.0 * @category List * @sig Number -> [a] -> [a] * @sig Number -> String -> String @@ -6660,7 +6950,7 @@ * @example * * R.takeLast(1, ['foo', 'bar', 'baz']); //=> ['baz'] - * R.takeLast(2, ['foo', 'bar', 'baz']); //=> ['for', 'baz'] + * R.takeLast(2, ['foo', 'bar', 'baz']); //=> ['bar', 'baz'] * R.takeLast(3, ['foo', 'bar', 'baz']); //=> ['foo', 'bar', 'baz'] * R.takeLast(4, ['foo', 'bar', 'baz']); //=> ['foo', 'bar', 'baz'] * R.takeLast(3, 'ramda'); //=> 'mda' @@ -6669,6 +6959,25 @@ return drop(n >= 0 ? xs.length - n : 0, xs); }); + /** + * Shorthand for `R.chain(R.identity)`, which removes one level of nesting + * from any [Chain](https://github.com/fantasyland/fantasy-land#chain). + * + * @func + * @memberOf R + * @since v0.3.0 + * @category List + * @sig Chain c => c (c a) -> c a + * @param {*} list + * @return {*} + * @see R.flatten, R.chain + * @example + * + * R.unnest([1, [2], [[3]]]); //=> [1, 2, [3]] + * R.unnest([[1, 2], [3, 4], [5, 6]]); //=> [1, 2, 3, 4, 5, 6] + */ + var unnest = chain(_identity); + var _contains = function _contains(a, list) { return _indexOf(list, a, 0) >= 0; }; @@ -6690,7 +6999,9 @@ case '[object Arguments]': return '(function() { return arguments; }(' + _map(recur, x).join(', ') + '))'; case '[object Array]': - return '[' + _map(recur, x).concat(mapPairs(x, reject(test(/^\d+$/), keys(x)))).join(', ') + ']'; + return '[' + _map(recur, x).concat(mapPairs(x, reject(function (k) { + return /^\d+$/.test(k); + }, keys(x)))).join(', ') + ']'; case '[object Boolean]': return typeof x === 'object' ? 'new Boolean(' + recur(x.valueOf()) + ')' : x.toString(); case '[object Date]': @@ -6714,6 +7025,7 @@ * * @func * @memberOf R + * @since v0.8.0 * @category List * @see R.commuteMap * @sig Functor f => (x -> f x) -> [f a] -> f [a] @@ -6736,8 +7048,9 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Function - * @sig ((y -> z), (x -> y), ..., (o -> p), ((a, b, ..., n) -> o)) -> (a -> b -> ... -> n -> z) + * @sig ((y -> z), (x -> y), ..., (o -> p), ((a, b, ..., n) -> o)) -> ((a, b, ..., n) -> z) * @param {...Function} functions * @return {Function} * @see R.pipe @@ -6762,6 +7075,7 @@ * * @func * @memberOf R + * @since v0.16.0 * @category Function * @see R.pipeK * @sig Chain m => ((y -> m z), (x -> m y), ..., (a -> m b)) -> (m a -> m z) @@ -6787,7 +7101,7 @@ * //=> Nothing() */ var composeK = function composeK() { - return arguments.length === 0 ? identity : compose.apply(this, map(chain, arguments)); + return compose.apply(this, prepend(identity, map(chain, arguments))); }; /** @@ -6797,6 +7111,7 @@ * * @func * @memberOf R + * @since v0.10.0 * @category Function * @sig ((y -> Promise z), (x -> Promise y), ..., (a -> Promise b)) -> (a -> Promise z) * @param {...Function} functions @@ -6820,6 +7135,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Function * @sig (* -> {*}) -> (* -> {*}) * @param {Function} Fn The constructor function to wrap. @@ -6827,7 +7143,7 @@ * @example * * // Constructor function - * var Widget = function(config) { + * var Widget = config => { * // ... * }; * Widget.prototype = { @@ -6848,12 +7164,13 @@ * * @func * @memberOf R + * @since v0.1.0 * @category List * @sig a -> [a] -> Boolean * @param {Object} a The item to compare against. * @param {Array} list The array to consider. * @return {Boolean} `true` if the item is in the list, `false` otherwise. - * + * @see R.any * @example * * R.contains(3, [1, 2, 3]); //=> true @@ -6867,6 +7184,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Relation * @sig [a] -> [a] -> [a] * @param {Array} list1 The first list. @@ -6895,11 +7213,14 @@ * Returns a new list without any consecutively repeating elements. * `R.equals` is used to determine equality. * + * Dispatches to the `dropRepeats` method of the first argument, if present. + * * Acts as a transducer if a transformer is given in list position. * @see R.transduce * * @func * @memberOf R + * @since v0.14.0 * @category List * @sig [a] -> [a] * @param {Array} list The array to consider. @@ -6915,6 +7236,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Relation * @sig [a] -> [a] -> [a] * @param {Array} list1 The first list. @@ -6935,6 +7257,7 @@ * * @func * @memberOf R + * @since v0.7.0 * @see R.liftN * @category Function * @sig (*... -> *) -> ([*]... -> [*]) @@ -6942,14 +7265,12 @@ * @return {Function} The function `fn` applicable to mappable objects. * @example * - * var madd3 = R.lift(R.curry(function(a, b, c) { - * return a + b + c; - * })); + * var madd3 = R.lift(R.curry((a, b, c) => a + b + c)); + * * madd3([1,2,3], [1,2,3], [1]); //=> [3, 4, 5, 4, 5, 6, 5, 6, 7] * - * var madd5 = R.lift(R.curry(function(a, b, c, d, e) { - * return a + b + c + d + e; - * })); + * var madd5 = R.lift(R.curry((a, b, c, d, e) => a + b + c + d + e)); + * * madd5([1,2], [3], [4, 5], [6], [7, 8]); //=> [21, 22, 22, 23, 22, 23, 23, 24] */ var lift = _curry1(function lift(fn) { @@ -6961,6 +7282,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Object * @sig [String] -> {String: *} -> {String: *} * @param {Array} names an array of String property names to omit from the new object @@ -6989,6 +7311,7 @@ * * @func * @memberOf R + * @since v0.16.0 * @category Function * @see R.composeK * @sig Chain m => ((a -> m b), (b -> m c), ..., (y -> m z)) -> (m a -> m z) @@ -7040,6 +7363,7 @@ * * @func * @memberOf R + * @since v0.14.0 * @category String * @sig * -> String * @param {*} val @@ -7062,6 +7386,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Relation * @sig [a] -> [a] -> [a] * @param {Array} as The first list. @@ -7083,6 +7408,7 @@ * * @func * @memberOf R + * @since v0.16.0 * @category List * @sig (a -> b) -> [a] -> [a] * @param {Function} fn A function used to produce a value to use during comparisons. @@ -7106,6 +7432,84 @@ return result; }); + /** + * A function wrapping calls to the two functions in an `&&` operation, returning the result of the first + * function if it is false-y and the result of the second function otherwise. + * + * `R.both` will work on all other applicatives as well. + * + * @func + * @memberOf R + * @since v0.12.0 + * @category Logic + * @sig (*... -> Boolean) -> (*... -> Boolean) -> (*... -> Boolean) + * @param {Function} f a predicate + * @param {Function} g another predicate + * @return {Function} a function that applies its arguments to `f` and `g` and `&&`s their outputs together. + * @see R.and + * @example + * + * var gt10 = x => x > 10; + * var even = x => x % 2 === 0; + * var f = R.both(gt10, even); + * f(100); //=> true + * f(101); //=> false + */ + var both = lift(and); + + /** + * Takes a function `f` and returns a function `g` such that: + * + * - applying `g` to zero or more arguments will give __true__ if applying + * the same arguments to `f` gives a logical __false__ value; and + * + * - applying `g` to zero or more arguments will give __false__ if applying + * the same arguments to `f` gives a logical __true__ value. + * + * `R.complement` will work on all other functors as well. + * + * @func + * @memberOf R + * @since v0.12.0 + * @category Logic + * @sig (*... -> *) -> (*... -> Boolean) + * @param {Function} f + * @return {Function} + * @see R.not + * @example + * + * var isEven = n => n % 2 === 0; + * var isOdd = R.complement(isEven); + * isOdd(21); //=> true + * isOdd(42); //=> false + */ + var complement = lift(not); + + /** + * A function wrapping calls to the two functions in an `||` operation, returning the result of the first + * function if it is truth-y and the result of the second function otherwise. + * + * `R.either` will work on all other applicatives as well. + * + * @func + * @memberOf R + * @since v0.12.0 + * @category Logic + * @sig (*... -> Boolean) -> (*... -> Boolean) -> (*... -> Boolean) + * @param {Function} f a predicate + * @param {Function} g another predicate + * @return {Function} a function that applies its arguments to `f` and `g` and `||`s their outputs together. + * @see R.or + * @example + * + * var gt10 = x => x > 10; + * var even = x => x % 2 === 0; + * var f = R.either(gt10, even); + * f(101); //=> true + * f(8); //=> true + */ + var either = lift(or); + /** * Turns a named method with a specified arity into a function * that can be called directly supplied with arguments and a target object. @@ -7115,6 +7519,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Function * @sig Number -> String -> (a -> b -> ... -> n -> Object -> *) * @param {Number} arity Number of arguments the returned function should take @@ -7144,6 +7549,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category List * @sig String -> [a] -> String * @param {Number|String} separator The string used to separate the elements. @@ -7166,6 +7572,7 @@ * * @func * @memberOf R + * @since v0.1.0 * @category Function * @sig (*... -> a) -> (*... -> a) * @param {Function} fn The function to memoize. @@ -7173,7 +7580,7 @@ * @example * * var count = 0; - * var factorial = R.memoize(function(n) { + * var factorial = R.memoize(n => { * count += 1; * return R.product(R.range(1, n + 1)); * }); @@ -7199,9 +7606,10 @@ * * @func * @memberOf R + * @since v0.1.0 * @category String - * @sig String -> String -> [String] - * @param {String} sep The separator string. + * @sig (String | RegExp) -> String -> [String] + * @param {String|RegExp} sep The pattern. * @param {String} str The string to separate into an array. * @return {Array} The array of strings from `str` separated by `str`. * @see R.join @@ -7214,11 +7622,36 @@ */ var split = invoker(1, 'split'); + /** + * Determines whether a given string matches a given regular expression. + * + * @func + * @memberOf R + * @since v0.12.0 + * @see R.match + * @category String + * @sig RegExp -> String -> Boolean + * @param {RegExp} pattern + * @param {String} str + * @return {Boolean} + * @example + * + * R.test(/^x/, 'xyz'); //=> true + * R.test(/^y/, 'xyz'); //=> false + */ + var test = _curry2(function test(pattern, str) { + if (!_isRegExp(pattern)) { + throw new TypeError('\u2018test\u2019 requires a value of type RegExp as its first argument; received ' + toString(pattern)); + } + return _cloneRegExp(pattern).test(str); + }); + /** * The lower case version of a string. * * @func * @memberOf R + * @since v0.9.0 * @category String * @sig String -> String * @param {String} str The string to lower case. @@ -7235,6 +7668,7 @@ * * @func * @memberOf R + * @since v0.9.0 * @category String * @sig String -> String * @param {String} str The string to upper case. @@ -7246,6 +7680,29 @@ */ var toUpper = invoker(0, 'toUpperCase'); + /** + * Returns the result of concatenating the given lists or strings. + * + * Dispatches to the `concat` method of the second argument, if present. + * + * @func + * @memberOf R + * @since v0.1.0 + * @category List + * @sig [a] -> [a] -> [a] + * @sig String -> String -> String + * @param {Array|String} a + * @param {Array|String} b + * @return {Array|String} + * + * @example + * + * R.concat([], []); //=> [] + * R.concat([4, 5, 6], [1, 2, 3]); //=> [4, 5, 6, 1, 2, 3] + * R.concat('ABC', 'DEF'); // 'ABCDEF' + */ + var concat = flip(invoker(1, 'concat')); + var R = { F: F, T: T, @@ -7255,6 +7712,7 @@ adjust: adjust, all: all, allPass: allPass, + allUniq: allUniq, always: always, and: and, any: any, @@ -7304,6 +7762,7 @@ dropWhile: dropWhile, either: either, empty: empty, + eqBy: eqBy, eqProps: eqProps, equals: equals, evolve: evolve, @@ -7381,18 +7840,19 @@ not: not, nth: nth, nthArg: nthArg, - nthChar: nthChar, - nthCharCode: nthCharCode, + objOf: objOf, of: of, omit: omit, once: once, or: or, over: over, + pair: pair, partial: partial, partialRight: partialRight, partition: partition, path: path, pathEq: pathEq, + pathOr: pathOr, pick: pick, pickAll: pickAll, pickBy: pickBy, @@ -7452,12 +7912,14 @@ uniq: uniq, uniqBy: uniqBy, uniqWith: uniqWith, + unless: unless, unnest: unnest, update: update, useWith: useWith, values: values, valuesIn: valuesIn, view: view, + when: when, where: where, whereEq: whereEq, wrap: wrap, diff --git a/docs/index.html b/docs/index.html index 37e9485c..bc42539e 100644 --- a/docs/index.html +++ b/docs/index.html @@ -7,18 +7,20 @@ +