Created
August 3, 2015 11:38
-
-
Save alexeygolev/2497f76b8799facb9066 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function webpackUniversalModuleDefinition(root, factory) { | |
if(typeof exports === 'object' && typeof module === 'object') | |
module.exports = factory(); | |
else if(typeof define === 'function' && define.amd) | |
define(factory); | |
else if(typeof exports === 'object') | |
exports["fantasy"] = factory(); | |
else | |
root["fantasy"] = factory(); | |
})(this, function() { | |
return /******/ (function(modules) { // webpackBootstrap | |
/******/ // The module cache | |
/******/ var installedModules = {}; | |
/******/ // The require function | |
/******/ function __webpack_require__(moduleId) { | |
/******/ // Check if module is in cache | |
/******/ if(installedModules[moduleId]) | |
/******/ return installedModules[moduleId].exports; | |
/******/ // Create a new module (and put it into the cache) | |
/******/ var module = installedModules[moduleId] = { | |
/******/ exports: {}, | |
/******/ id: moduleId, | |
/******/ loaded: false | |
/******/ }; | |
/******/ // Execute the module function | |
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); | |
/******/ // Flag the module as loaded | |
/******/ module.loaded = true; | |
/******/ // Return the exports of the module | |
/******/ return module.exports; | |
/******/ } | |
/******/ // expose the modules object (__webpack_modules__) | |
/******/ __webpack_require__.m = modules; | |
/******/ // expose the module cache | |
/******/ __webpack_require__.c = installedModules; | |
/******/ // __webpack_public_path__ | |
/******/ __webpack_require__.p = ""; | |
/******/ // Load entry module and return exports | |
/******/ return __webpack_require__(0); | |
/******/ }) | |
/************************************************************************/ | |
/******/ ([ | |
/* 0 */ | |
/***/ function(module, exports, __webpack_require__) { | |
module.exports = { | |
Either: __webpack_require__(3), | |
Future: __webpack_require__(4), | |
Identity: __webpack_require__(6), | |
IO: __webpack_require__(5), | |
lift2: __webpack_require__(10), | |
lift3: __webpack_require__(11), | |
Maybe: __webpack_require__(7), | |
Tuple: __webpack_require__(9), | |
Reader: __webpack_require__(8) | |
}; | |
/***/ }, | |
/* 1 */ | |
/***/ function(module, exports, __webpack_require__) { | |
// Ramda v0.15.1 | |
// https://github.com/ramda/ramda | |
// (c) 2013-2015 Scott Sauyet, Michael Hurley, and David Chambers | |
// Ramda may be freely distributed under the MIT license. | |
;(function() { | |
'use strict'; | |
/** | |
* A special placeholder value used to specify "gaps" within curried functions, | |
* allowing partial application of any combination of arguments, | |
* regardless of their positions. | |
* | |
* If `g` is a curried ternary function and `_` is `R.__`, the following are equivalent: | |
* | |
* - `g(1, 2, 3)` | |
* - `g(_, 2, 3)(1)` | |
* - `g(_, _, 3)(1)(2)` | |
* - `g(_, _, 3)(1, 2)` | |
* - `g(_, 2, _)(1, 3)` | |
* - `g(_, 2)(1)(3)` | |
* - `g(_, 2)(1, 3)` | |
* - `g(_, 2)(_, 3)(1)` | |
* | |
* @constant | |
* @memberOf R | |
* @category Function | |
* @example | |
* | |
* var greet = R.replace('{name}', R.__, 'Hello, {name}!'); | |
* greet('Alice'); //=> 'Hello, Alice!' | |
*/ | |
var __ = { '@@functional/placeholder': true }; | |
var _add = function _add(a, b) { | |
return a + b; | |
}; | |
var _all = function _all(fn, list) { | |
var idx = 0; | |
while (idx < list.length) { | |
if (!fn(list[idx])) { | |
return false; | |
} | |
idx += 1; | |
} | |
return true; | |
}; | |
var _any = function _any(fn, list) { | |
var idx = 0; | |
while (idx < list.length) { | |
if (fn(list[idx])) { | |
return true; | |
} | |
idx += 1; | |
} | |
return false; | |
}; | |
var _assoc = function _assoc(prop, val, obj) { | |
var result = {}; | |
for (var p in obj) { | |
result[p] = obj[p]; | |
} | |
result[prop] = val; | |
return result; | |
}; | |
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' : '')); | |
}; | |
var _complement = function _complement(f) { | |
return function () { | |
return !f.apply(this, arguments); | |
}; | |
}; | |
/** | |
* Basic, right-associative composition function. Accepts two functions and returns the | |
* composite function; this composite function represents the operation `var h = f(g(x))`, | |
* where `f` is the first argument, `g` is the second argument, and `x` is whatever | |
* argument(s) are passed to `h`. | |
* | |
* This function's main use is to build the more general `compose` function, which accepts | |
* any number of functions. | |
* | |
* @private | |
* @category Function | |
* @param {Function} f A function. | |
* @param {Function} g A function. | |
* @return {Function} A new function that is the equivalent of `f(g(x))`. | |
* @example | |
* | |
* var double = function(x) { return x * 2; }; | |
* var square = function(x) { return x * x; }; | |
* var squareThenDouble = _compose(double, square); | |
* | |
* squareThenDouble(5); //≅ double(square(5)) => 50 | |
*/ | |
var _compose = function _compose(f, g) { | |
return function () { | |
return f.call(this, g.apply(this, arguments)); | |
}; | |
}; | |
/** | |
* Private `concat` function to merge two array-like objects. | |
* | |
* @private | |
* @param {Array|Arguments} [set1=[]] An array-like object. | |
* @param {Array|Arguments} [set2=[]] An array-like object. | |
* @return {Array} A new, merged array. | |
* @example | |
* | |
* _concat([4, 5, 6], [1, 2, 3]); //=> [4, 5, 6, 1, 2, 3] | |
*/ | |
var _concat = function _concat(set1, set2) { | |
set1 = set1 || []; | |
set2 = set2 || []; | |
var idx; | |
var len1 = set1.length; | |
var len2 = set2.length; | |
var result = []; | |
idx = 0; | |
while (idx < len1) { | |
result[result.length] = set1[idx]; | |
idx += 1; | |
} | |
idx = 0; | |
while (idx < len2) { | |
result[result.length] = set2[idx]; | |
idx += 1; | |
} | |
return result; | |
}; | |
var _containsWith = function _containsWith(pred, x, list) { | |
var idx = 0, len = list.length; | |
while (idx < len) { | |
if (pred(x, list[idx])) { | |
return true; | |
} | |
idx += 1; | |
} | |
return false; | |
}; | |
var _createMapEntry = function _createMapEntry(key, val) { | |
var obj = {}; | |
obj[key] = val; | |
return obj; | |
}; | |
/** | |
* Create a function which takes a comparator function and a list | |
* and determines the winning value by a compatator. Used internally | |
* by `R.maxBy` and `R.minBy` | |
* | |
* @private | |
* @param {Function} compatator a function to compare two items | |
* @category Math | |
* @return {Function} | |
*/ | |
var _createMaxMinBy = function _createMaxMinBy(comparator) { | |
return function (valueComputer, list) { | |
if (!(list && list.length > 0)) { | |
return; | |
} | |
var idx = 1; | |
var winner = list[idx]; | |
var computedWinner = valueComputer(winner); | |
var computedCurrent; | |
while (idx < list.length) { | |
computedCurrent = valueComputer(list[idx]); | |
if (comparator(computedCurrent, computedWinner)) { | |
computedWinner = computedCurrent; | |
winner = list[idx]; | |
} | |
idx += 1; | |
} | |
return winner; | |
}; | |
}; | |
/** | |
* Optimized internal two-arity curry function. | |
* | |
* @private | |
* @category Function | |
* @param {Function} fn The function to curry. | |
* @return {Function} The curried function. | |
*/ | |
var _curry1 = function _curry1(fn) { | |
return function f1(a) { | |
if (arguments.length === 0) { | |
return f1; | |
} else if (a != null && a['@@functional/placeholder'] === true) { | |
return f1; | |
} else { | |
return fn(a); | |
} | |
}; | |
}; | |
/** | |
* Optimized internal two-arity curry function. | |
* | |
* @private | |
* @category Function | |
* @param {Function} fn The function to curry. | |
* @return {Function} The curried function. | |
*/ | |
var _curry2 = function _curry2(fn) { | |
return function f2(a, b) { | |
var n = arguments.length; | |
if (n === 0) { | |
return f2; | |
} else if (n === 1 && a != null && a['@@functional/placeholder'] === true) { | |
return f2; | |
} else if (n === 1) { | |
return _curry1(function (b) { | |
return fn(a, b); | |
}); | |
} else if (n === 2 && a != null && a['@@functional/placeholder'] === true && b != null && b['@@functional/placeholder'] === true) { | |
return f2; | |
} else if (n === 2 && a != null && a['@@functional/placeholder'] === true) { | |
return _curry1(function (a) { | |
return fn(a, b); | |
}); | |
} else if (n === 2 && b != null && b['@@functional/placeholder'] === true) { | |
return _curry1(function (b) { | |
return fn(a, b); | |
}); | |
} else { | |
return fn(a, b); | |
} | |
}; | |
}; | |
/** | |
* Optimized internal three-arity curry function. | |
* | |
* @private | |
* @category Function | |
* @param {Function} fn The function to curry. | |
* @return {Function} The curried function. | |
*/ | |
var _curry3 = function _curry3(fn) { | |
return function f3(a, b, c) { | |
var n = arguments.length; | |
if (n === 0) { | |
return f3; | |
} else if (n === 1 && a != null && a['@@functional/placeholder'] === true) { | |
return f3; | |
} else if (n === 1) { | |
return _curry2(function (b, c) { | |
return fn(a, b, c); | |
}); | |
} else if (n === 2 && a != null && a['@@functional/placeholder'] === true && b != null && b['@@functional/placeholder'] === true) { | |
return f3; | |
} else if (n === 2 && a != null && a['@@functional/placeholder'] === true) { | |
return _curry2(function (a, c) { | |
return fn(a, b, c); | |
}); | |
} else if (n === 2 && b != null && b['@@functional/placeholder'] === true) { | |
return _curry2(function (b, c) { | |
return fn(a, b, c); | |
}); | |
} else if (n === 2) { | |
return _curry1(function (c) { | |
return fn(a, b, c); | |
}); | |
} else if (n === 3 && a != null && a['@@functional/placeholder'] === true && b != null && b['@@functional/placeholder'] === true && c != null && c['@@functional/placeholder'] === true) { | |
return f3; | |
} else if (n === 3 && a != null && a['@@functional/placeholder'] === true && b != null && b['@@functional/placeholder'] === true) { | |
return _curry2(function (a, b) { | |
return fn(a, b, c); | |
}); | |
} else if (n === 3 && a != null && a['@@functional/placeholder'] === true && c != null && c['@@functional/placeholder'] === true) { | |
return _curry2(function (a, c) { | |
return fn(a, b, c); | |
}); | |
} else if (n === 3 && b != null && b['@@functional/placeholder'] === true && c != null && c['@@functional/placeholder'] === true) { | |
return _curry2(function (b, c) { | |
return fn(a, b, c); | |
}); | |
} else if (n === 3 && a != null && a['@@functional/placeholder'] === true) { | |
return _curry1(function (a) { | |
return fn(a, b, c); | |
}); | |
} else if (n === 3 && b != null && b['@@functional/placeholder'] === true) { | |
return _curry1(function (b) { | |
return fn(a, b, c); | |
}); | |
} else if (n === 3 && c != null && c['@@functional/placeholder'] === true) { | |
return _curry1(function (c) { | |
return fn(a, b, c); | |
}); | |
} else { | |
return fn(a, b, c); | |
} | |
}; | |
}; | |
var _dissoc = function _dissoc(prop, obj) { | |
var result = {}; | |
for (var p in obj) { | |
if (p !== prop) { | |
result[p] = obj[p]; | |
} | |
} | |
return result; | |
}; | |
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is#Polyfill | |
// SameValue algorithm | |
// Steps 1-5, 7-10 | |
// Steps 6.b-6.e: +0 != -0 | |
// Step 6.a: NaN == NaN | |
var _eq = function _eq(x, y) { | |
// SameValue algorithm | |
if (x === y) { | |
// Steps 1-5, 7-10 | |
// Steps 6.b-6.e: +0 != -0 | |
return x !== 0 || 1 / x === 1 / y; | |
} else { | |
// Step 6.a: NaN == NaN | |
return x !== x && y !== y; | |
} | |
}; | |
var _filter = function _filter(fn, list) { | |
var idx = 0, len = list.length, result = []; | |
while (idx < len) { | |
if (fn(list[idx])) { | |
result[result.length] = list[idx]; | |
} | |
idx += 1; | |
} | |
return result; | |
}; | |
var _filterIndexed = function _filterIndexed(fn, list) { | |
var idx = 0, len = list.length, result = []; | |
while (idx < len) { | |
if (fn(list[idx], idx, list)) { | |
result[result.length] = list[idx]; | |
} | |
idx += 1; | |
} | |
return result; | |
}; | |
// i can't bear not to return *something* | |
var _forEach = function _forEach(fn, list) { | |
var idx = 0, len = list.length; | |
while (idx < len) { | |
fn(list[idx]); | |
idx += 1; | |
} | |
// i can't bear not to return *something* | |
return list; | |
}; | |
var _forceReduced = function _forceReduced(x) { | |
return { | |
'@@transducer/value': x, | |
'@@transducer/reduced': true | |
}; | |
}; | |
/** | |
* @private | |
* @param {Function} fn The strategy for extracting function names from an object | |
* @return {Function} A function that takes an object and returns an array of function names. | |
*/ | |
var _functionsWith = function _functionsWith(fn) { | |
return function (obj) { | |
return _filter(function (key) { | |
return typeof obj[key] === 'function'; | |
}, fn(obj)); | |
}; | |
}; | |
var _gt = function _gt(a, b) { | |
return a > b; | |
}; | |
var _has = function _has(prop, obj) { | |
return Object.prototype.hasOwnProperty.call(obj, prop); | |
}; | |
var _identity = function _identity(x) { | |
return x; | |
}; | |
/** | |
* Tests whether or not an object is an array. | |
* | |
* @private | |
* @param {*} val The object to test. | |
* @return {Boolean} `true` if `val` is an array, `false` otherwise. | |
* @example | |
* | |
* _isArray([]); //=> true | |
* _isArray(null); //=> false | |
* _isArray({}); //=> false | |
*/ | |
var _isArray = Array.isArray || function _isArray(val) { | |
return val != null && val.length >= 0 && Object.prototype.toString.call(val) === '[object Array]'; | |
}; | |
/** | |
* Determine if the passed argument is an integer. | |
* | |
* @private | |
* @param {*} n | |
* @category Type | |
* @return {Boolean} | |
*/ | |
var _isInteger = Number.isInteger || function _isInteger(n) { | |
return n << 0 === n; | |
}; | |
/** | |
* Tests if a value is a thenable (promise). | |
*/ | |
var _isThenable = function _isThenable(value) { | |
return value != null && value === Object(value) && typeof value.then === 'function'; | |
}; | |
var _isTransformer = function _isTransformer(obj) { | |
return typeof obj['@@transducer/step'] === 'function'; | |
}; | |
var _lt = function _lt(a, b) { | |
return a < b; | |
}; | |
var _map = function _map(fn, list) { | |
var idx = 0, len = list.length, result = []; | |
while (idx < len) { | |
result[idx] = fn(list[idx]); | |
idx += 1; | |
} | |
return result; | |
}; | |
var _multiply = function _multiply(a, b) { | |
return a * b; | |
}; | |
var _nth = function _nth(n, list) { | |
return n < 0 ? list[list.length + n] : list[n]; | |
}; | |
/** | |
* internal path function | |
* Takes an array, paths, indicating the deep set of keys | |
* to find. | |
* | |
* @private | |
* @memberOf R | |
* @category Object | |
* @param {Array} paths An array of strings to map to object properties | |
* @param {Object} obj The object to find the path in | |
* @return {Array} The value at the end of the path or `undefined`. | |
* @example | |
* | |
* _path(['a', 'b'], {a: {b: 2}}); //=> 2 | |
*/ | |
var _path = function _path(paths, obj) { | |
if (obj == null) { | |
return; | |
} else { | |
var val = obj; | |
for (var idx = 0, len = paths.length; idx < len && val != null; idx += 1) { | |
val = val[paths[idx]]; | |
} | |
return val; | |
} | |
}; | |
var _prepend = function _prepend(el, list) { | |
return _concat([el], list); | |
}; | |
var _quote = function _quote(s) { | |
return '"' + s.replace(/"/g, '\\"') + '"'; | |
}; | |
var _reduced = function _reduced(x) { | |
return x && x['@@transducer/reduced'] ? x : { | |
'@@transducer/value': x, | |
'@@transducer/reduced': true | |
}; | |
}; | |
/** | |
* An optimized, private array `slice` implementation. | |
* | |
* @private | |
* @param {Arguments|Array} args The array or arguments object to consider. | |
* @param {Number} [from=0] The array index to slice from, inclusive. | |
* @param {Number} [to=args.length] The array index to slice to, exclusive. | |
* @return {Array} A new, sliced array. | |
* @example | |
* | |
* _slice([1, 2, 3, 4, 5], 1, 3); //=> [2, 3] | |
* | |
* var firstThreeArgs = function(a, b, c, d) { | |
* return _slice(arguments, 0, 3); | |
* }; | |
* firstThreeArgs(1, 2, 3, 4); //=> [1, 2, 3] | |
*/ | |
var _slice = function _slice(args, from, to) { | |
switch (arguments.length) { | |
case 1: | |
return _slice(args, 0, args.length); | |
case 2: | |
return _slice(args, from, args.length); | |
default: | |
var list = []; | |
var idx = 0; | |
var len = Math.max(0, Math.min(args.length, to) - from); | |
while (idx < len) { | |
list[idx] = args[from + idx]; | |
idx += 1; | |
} | |
return list; | |
} | |
}; | |
/** | |
* Polyfill from <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString>. | |
*/ | |
var _toISOString = function () { | |
var pad = function pad(n) { | |
return (n < 10 ? '0' : '') + n; | |
}; | |
return typeof Date.prototype.toISOString === 'function' ? function _toISOString(d) { | |
return d.toISOString(); | |
} : function _toISOString(d) { | |
return d.getUTCFullYear() + '-' + pad(d.getUTCMonth() + 1) + '-' + pad(d.getUTCDate()) + 'T' + pad(d.getUTCHours()) + ':' + pad(d.getUTCMinutes()) + ':' + pad(d.getUTCSeconds()) + '.' + (d.getUTCMilliseconds() / 1000).toFixed(3).slice(2, 5) + 'Z'; | |
}; | |
}(); | |
var _xdropRepeatsWith = function () { | |
function XDropRepeatsWith(pred, xf) { | |
this.xf = xf; | |
this.pred = pred; | |
this.lastValue = undefined; | |
this.seenFirstValue = false; | |
} | |
XDropRepeatsWith.prototype['@@transducer/init'] = function () { | |
return this.xf['@@transducer/init'](); | |
}; | |
XDropRepeatsWith.prototype['@@transducer/result'] = function (result) { | |
return this.xf['@@transducer/result'](result); | |
}; | |
XDropRepeatsWith.prototype['@@transducer/step'] = function (result, input) { | |
var sameAsLast = false; | |
if (!this.seenFirstValue) { | |
this.seenFirstValue = true; | |
} else if (this.pred(this.lastValue, input)) { | |
sameAsLast = true; | |
} | |
this.lastValue = input; | |
return sameAsLast ? result : this.xf['@@transducer/step'](result, input); | |
}; | |
return _curry2(function _xdropRepeatsWith(pred, xf) { | |
return new XDropRepeatsWith(pred, xf); | |
}); | |
}(); | |
var _xfBase = { | |
init: function () { | |
return this.xf['@@transducer/init'](); | |
}, | |
result: function (result) { | |
return this.xf['@@transducer/result'](result); | |
} | |
}; | |
var _xfilter = function () { | |
function XFilter(f, xf) { | |
this.xf = xf; | |
this.f = f; | |
} | |
XFilter.prototype['@@transducer/init'] = _xfBase.init; | |
XFilter.prototype['@@transducer/result'] = _xfBase.result; | |
XFilter.prototype['@@transducer/step'] = function (result, input) { | |
return this.f(input) ? this.xf['@@transducer/step'](result, input) : result; | |
}; | |
return _curry2(function _xfilter(f, xf) { | |
return new XFilter(f, xf); | |
}); | |
}(); | |
var _xfind = function () { | |
function XFind(f, xf) { | |
this.xf = xf; | |
this.f = f; | |
this.found = false; | |
} | |
XFind.prototype['@@transducer/init'] = _xfBase.init; | |
XFind.prototype['@@transducer/result'] = function (result) { | |
if (!this.found) { | |
result = this.xf['@@transducer/step'](result, void 0); | |
} | |
return this.xf['@@transducer/result'](result); | |
}; | |
XFind.prototype['@@transducer/step'] = function (result, input) { | |
if (this.f(input)) { | |
this.found = true; | |
result = _reduced(this.xf['@@transducer/step'](result, input)); | |
} | |
return result; | |
}; | |
return _curry2(function _xfind(f, xf) { | |
return new XFind(f, xf); | |
}); | |
}(); | |
var _xfindIndex = function () { | |
function XFindIndex(f, xf) { | |
this.xf = xf; | |
this.f = f; | |
this.idx = -1; | |
this.found = false; | |
} | |
XFindIndex.prototype['@@transducer/init'] = _xfBase.init; | |
XFindIndex.prototype['@@transducer/result'] = function (result) { | |
if (!this.found) { | |
result = this.xf['@@transducer/step'](result, -1); | |
} | |
return this.xf['@@transducer/result'](result); | |
}; | |
XFindIndex.prototype['@@transducer/step'] = function (result, input) { | |
this.idx += 1; | |
if (this.f(input)) { | |
this.found = true; | |
result = _reduced(this.xf['@@transducer/step'](result, this.idx)); | |
} | |
return result; | |
}; | |
return _curry2(function _xfindIndex(f, xf) { | |
return new XFindIndex(f, xf); | |
}); | |
}(); | |
var _xfindLast = function () { | |
function XFindLast(f, xf) { | |
this.xf = xf; | |
this.f = f; | |
} | |
XFindLast.prototype['@@transducer/init'] = _xfBase.init; | |
XFindLast.prototype['@@transducer/result'] = function (result) { | |
return this.xf['@@transducer/result'](this.xf['@@transducer/step'](result, this.last)); | |
}; | |
XFindLast.prototype['@@transducer/step'] = function (result, input) { | |
if (this.f(input)) { | |
this.last = input; | |
} | |
return result; | |
}; | |
return _curry2(function _xfindLast(f, xf) { | |
return new XFindLast(f, xf); | |
}); | |
}(); | |
var _xfindLastIndex = function () { | |
function XFindLastIndex(f, xf) { | |
this.xf = xf; | |
this.f = f; | |
this.idx = -1; | |
this.lastIdx = -1; | |
} | |
XFindLastIndex.prototype['@@transducer/init'] = _xfBase.init; | |
XFindLastIndex.prototype['@@transducer/result'] = function (result) { | |
return this.xf['@@transducer/result'](this.xf['@@transducer/step'](result, this.lastIdx)); | |
}; | |
XFindLastIndex.prototype['@@transducer/step'] = function (result, input) { | |
this.idx += 1; | |
if (this.f(input)) { | |
this.lastIdx = this.idx; | |
} | |
return result; | |
}; | |
return _curry2(function _xfindLastIndex(f, xf) { | |
return new XFindLastIndex(f, xf); | |
}); | |
}(); | |
var _xmap = function () { | |
function XMap(f, xf) { | |
this.xf = xf; | |
this.f = f; | |
} | |
XMap.prototype['@@transducer/init'] = _xfBase.init; | |
XMap.prototype['@@transducer/result'] = _xfBase.result; | |
XMap.prototype['@@transducer/step'] = function (result, input) { | |
return this.xf['@@transducer/step'](result, this.f(input)); | |
}; | |
return _curry2(function _xmap(f, xf) { | |
return new XMap(f, xf); | |
}); | |
}(); | |
var _xtake = function () { | |
function XTake(n, xf) { | |
this.xf = xf; | |
this.n = n; | |
} | |
XTake.prototype['@@transducer/init'] = _xfBase.init; | |
XTake.prototype['@@transducer/result'] = _xfBase.result; | |
XTake.prototype['@@transducer/step'] = function (result, input) { | |
this.n -= 1; | |
return this.n === 0 ? _reduced(this.xf['@@transducer/step'](result, input)) : this.xf['@@transducer/step'](result, input); | |
}; | |
return _curry2(function _xtake(n, xf) { | |
return new XTake(n, xf); | |
}); | |
}(); | |
var _xtakeWhile = function () { | |
function XTakeWhile(f, xf) { | |
this.xf = xf; | |
this.f = f; | |
} | |
XTakeWhile.prototype['@@transducer/init'] = _xfBase.init; | |
XTakeWhile.prototype['@@transducer/result'] = _xfBase.result; | |
XTakeWhile.prototype['@@transducer/step'] = function (result, input) { | |
return this.f(input) ? this.xf['@@transducer/step'](result, input) : _reduced(result); | |
}; | |
return _curry2(function _xtakeWhile(f, xf) { | |
return new XTakeWhile(f, xf); | |
}); | |
}(); | |
var _xwrap = function () { | |
function XWrap(fn) { | |
this.f = fn; | |
} | |
XWrap.prototype['@@transducer/init'] = function () { | |
throw new Error('init not implemented on XWrap'); | |
}; | |
XWrap.prototype['@@transducer/result'] = function (acc) { | |
return acc; | |
}; | |
XWrap.prototype['@@transducer/step'] = function (acc, x) { | |
return this.f(acc, x); | |
}; | |
return function _xwrap(fn) { | |
return new XWrap(fn); | |
}; | |
}(); | |
/** | |
* Adds two numbers (or strings). Equivalent to `a + b` but curried. | |
* | |
* @func | |
* @memberOf R | |
* @category Math | |
* @sig Number -> Number -> Number | |
* @sig String -> String -> String | |
* @param {Number|String} a The first value. | |
* @param {Number|String} b The second value. | |
* @return {Number|String} The result of `a + b`. | |
* @example | |
* | |
* R.add(2, 3); //=> 5 | |
* R.add(7)(10); //=> 17 | |
*/ | |
var add = _curry2(_add); | |
/** | |
* Applies a function to the value at the given index of an array, | |
* returning a new copy of the array with the element at the given | |
* index replaced with the result of the function application. | |
* @see R.update | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig (a -> a) -> Number -> [a] -> [a] | |
* @param {Function} fn The function to apply. | |
* @param {Number} idx The index. | |
* @param {Array|Arguments} list An array-like object whose value | |
* at the supplied index will be replaced. | |
* @return {Array} A copy of the supplied array-like object with | |
* the element at index `idx` replaced with the value | |
* returned by applying `fn` to the existing element. | |
* @example | |
* | |
* R.adjust(R.add(10), 1, [0, 1, 2]); //=> [0, 11, 2] | |
* R.adjust(R.add(10))(1)([0, 1, 2]); //=> [0, 11, 2] | |
*/ | |
var adjust = _curry3(function (fn, idx, list) { | |
if (idx >= list.length || idx < -list.length) { | |
return list; | |
} | |
var start = idx < 0 ? list.length : 0; | |
var _idx = start + idx; | |
var _list = _concat(list); | |
_list[_idx] = fn(list[_idx]); | |
return _list; | |
}); | |
/** | |
* Returns a function that always returns the given value. Note that for non-primitives the value | |
* returned is a reference to the original value. | |
* | |
* @func | |
* @memberOf R | |
* @category Function | |
* @sig a -> (* -> a) | |
* @param {*} val The value to wrap in a function | |
* @return {Function} A Function :: * -> val. | |
* @example | |
* | |
* var t = R.always('Tee'); | |
* t(); //=> 'Tee' | |
*/ | |
var always = _curry1(function always(val) { | |
return function () { | |
return val; | |
}; | |
}); | |
/** | |
* 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. | |
* | |
* @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. | |
* @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(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; | |
}); | |
/** | |
* Applies function `fn` to the argument list `args`. This is useful for | |
* creating a fixed-arity function from a variadic function. `fn` should | |
* be a bound function if context is significant. | |
* | |
* @func | |
* @memberOf R | |
* @category Function | |
* @sig (*... -> a) -> [*] -> a | |
* @param {Function} fn | |
* @param {Array} args | |
* @return {*} | |
* @example | |
* | |
* var nums = [1, 2, 3, -99, 42, 6, 7]; | |
* R.apply(Math.max, nums); //=> 42 | |
*/ | |
var apply = _curry2(function apply(fn, args) { | |
return fn.apply(this, args); | |
}); | |
/** | |
* Wraps a function of any arity (including nullary) in a function that accepts exactly `n` | |
* parameters. Unlike `nAry`, which passes only `n` arguments to the wrapped function, | |
* functions produced by `arity` will pass all provided arguments to the wrapped function. | |
* | |
* @func | |
* @memberOf R | |
* @sig (Number, (* -> *)) -> (* -> *) | |
* @category Function | |
* @param {Number} n The desired arity of the returned function. | |
* @param {Function} fn The function to wrap. | |
* @return {Function} A new function wrapping `fn`. The new function is | |
* guaranteed to be of arity `n`. | |
* @deprecated since v0.15.0 | |
* @example | |
* | |
* var takesTwoArgs = function(a, b) { | |
* return [a, b]; | |
* }; | |
* takesTwoArgs.length; //=> 2 | |
* takesTwoArgs(1, 2); //=> [1, 2] | |
* | |
* var takesOneArg = R.arity(1, takesTwoArgs); | |
* takesOneArg.length; //=> 1 | |
* // All arguments are passed through to the wrapped function | |
* takesOneArg(1, 2); //=> [1, 2] | |
*/ | |
// jshint unused:vars | |
var arity = _curry2(function (n, fn) { | |
// jshint unused:vars | |
switch (n) { | |
case 0: | |
return function () { | |
return fn.apply(this, arguments); | |
}; | |
case 1: | |
return function (a0) { | |
return fn.apply(this, arguments); | |
}; | |
case 2: | |
return function (a0, a1) { | |
return fn.apply(this, arguments); | |
}; | |
case 3: | |
return function (a0, a1, a2) { | |
return fn.apply(this, arguments); | |
}; | |
case 4: | |
return function (a0, a1, a2, a3) { | |
return fn.apply(this, arguments); | |
}; | |
case 5: | |
return function (a0, a1, a2, a3, a4) { | |
return fn.apply(this, arguments); | |
}; | |
case 6: | |
return function (a0, a1, a2, a3, a4, a5) { | |
return fn.apply(this, arguments); | |
}; | |
case 7: | |
return function (a0, a1, a2, a3, a4, a5, a6) { | |
return fn.apply(this, arguments); | |
}; | |
case 8: | |
return function (a0, a1, a2, a3, a4, a5, a6, a7) { | |
return fn.apply(this, arguments); | |
}; | |
case 9: | |
return function (a0, a1, a2, a3, a4, a5, a6, a7, a8) { | |
return fn.apply(this, arguments); | |
}; | |
case 10: | |
return function (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) { | |
return fn.apply(this, arguments); | |
}; | |
default: | |
throw new Error('First argument to arity must be a non-negative integer no greater than ten'); | |
} | |
}); | |
/** | |
* Makes a shallow clone of an object, setting or overriding the specified | |
* property with the given value. Note that this copies and flattens | |
* prototype properties onto the new object as well. All non-primitive | |
* properties are copied by reference. | |
* | |
* @func | |
* @memberOf R | |
* @category Object | |
* @sig String -> a -> {k: v} -> {k: v} | |
* @param {String} prop the property name to set | |
* @param {*} val the new value | |
* @param {Object} obj the object to clone | |
* @return {Object} a new object similar to the original except for the specified property. | |
* @example | |
* | |
* R.assoc('c', 3, {a: 1, b: 2}); //=> {a: 1, b: 2, c: 3} | |
*/ | |
var assoc = _curry3(_assoc); | |
/** | |
* Creates a function that is bound to a context. | |
* Note: `R.bind` does not provide the additional argument-binding capabilities of | |
* [Function.prototype.bind](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind). | |
* | |
* @func | |
* @memberOf R | |
* @category Function | |
* @category Object | |
* @see R.partial | |
* @sig (* -> *) -> {*} -> (* -> *) | |
* @param {Function} fn The function to bind to context | |
* @param {Object} thisObj The context to bind `fn` to | |
* @return {Function} A function that will execute in the context of `thisObj`. | |
*/ | |
var bind = _curry2(function bind(fn, thisObj) { | |
return arity(fn.length, function () { | |
return fn.apply(thisObj, arguments); | |
}); | |
}); | |
/** | |
* 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. | |
* @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 | |
* @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 people = [ | |
* // ... | |
* ]; | |
* R.sort(cmp, people); | |
*/ | |
var comparator = _curry1(function comparator(pred) { | |
return function (a, b) { | |
return pred(a, b) ? -1 : pred(b, a) ? 1 : 0; | |
}; | |
}); | |
/** | |
* 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} | |
* @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. | |
* Each argument to `R.cond` is a [predicate, transform] pair. All of | |
* the arguments to `fn` are applied to each of the predicates in turn | |
* until one returns a "truthy" value, at which point `fn` returns the | |
* result of applying its arguments to the corresponding transformer. | |
* If none of the predicates matches, `fn` returns undefined. | |
* | |
* @func | |
* @memberOf R | |
* @category Logic | |
* @sig [(*... -> Boolean),(*... -> *)]... -> (*... -> *) | |
* @param {...Function} functions | |
* @return {Function} | |
* @example | |
* | |
* 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'; }] | |
* ); | |
* fn(0); //=> 'water freezes at 0°C' | |
* fn(50); //=> 'nothing special happens at 50°C' | |
* fn(100); //=> 'water boils at 100°C' | |
*/ | |
var cond = function cond() { | |
var pairs = arguments; | |
return function () { | |
var idx = 0; | |
while (idx < pairs.length) { | |
if (pairs[idx][0].apply(this, arguments)) { | |
return pairs[idx][1].apply(this, arguments); | |
} | |
idx += 1; | |
} | |
}; | |
}; | |
/** | |
* Returns `true` if the `x` is found in the `list`, using `pred` as an | |
* equality predicate for `x`. | |
* | |
* @func | |
* @memberOf R | |
* @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`. | |
* @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 containsWith = _curry3(_containsWith); | |
/** | |
* Counts the elements of a list according to how many match each value | |
* of a key generated by the supplied function. Returns an object | |
* mapping the keys produced by `fn` to the number of occurrences in | |
* the list. Note that all keys are coerced to strings because of how | |
* JavaScript objects work. | |
* | |
* @func | |
* @memberOf R | |
* @category Relation | |
* @sig (a -> String) -> [a] -> {*} | |
* @param {Function} fn The function used to map values to keys. | |
* @param {Array} list The list to count elements from. | |
* @return {Object} An object mapping keys to number of occurrences in the list. | |
* @example | |
* | |
* var numbers = [1.0, 1.1, 1.2, 2.0, 3.0, 2.2]; | |
* var letters = R.split('', 'abcABCaaaBBc'); | |
* R.countBy(Math.floor)(numbers); //=> {'1': 3, '2': 2, '3': 1} | |
* R.countBy(R.toLower)(letters); //=> {'a': 5, 'b': 4, 'c': 3} | |
*/ | |
var countBy = _curry2(function countBy(fn, list) { | |
var counts = {}; | |
var len = list.length; | |
var idx = 0; | |
while (idx < len) { | |
var key = fn(list[idx]); | |
counts[key] = (_has(key, counts) ? counts[key] : 0) + 1; | |
idx += 1; | |
} | |
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(_createMapEntry); | |
/** | |
* Decrements its argument. | |
* | |
* @func | |
* @memberOf R | |
* @category Math | |
* @sig Number -> Number | |
* @param {Number} n | |
* @return {Number} | |
* @example | |
* | |
* R.dec(42); //=> 41 | |
*/ | |
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. | |
* | |
* @func | |
* @memberOf R | |
* @category Logic | |
* @sig a -> b -> a | b | |
* @param {a} val The default value. | |
* @param {b} val The value to return if it is not null or undefined | |
* @return {*} The the second value or the default value | |
* @example | |
* | |
* var defaultTo42 = defaultTo(42); | |
* | |
* defaultTo42(null); //=> 42 | |
* defaultTo42(undefined); //=> 42 | |
* defaultTo42('Ramda'); //=> 'Ramda' | |
*/ | |
var defaultTo = _curry2(function defaultTo(d, v) { | |
return v == null ? d : v; | |
}); | |
/** | |
* Finds the set (i.e. no duplicates) of all elements in the first list not contained in the second list. | |
* Duplication is determined according to the value returned by applying the supplied predicate to two list | |
* elements. | |
* | |
* @func | |
* @memberOf R | |
* @category Relation | |
* @sig (a,a -> Boolean) -> [a] -> [a] -> [a] | |
* @param {Function} pred A predicate used to test whether two items are equal. | |
* @param {Array} list1 The first list. | |
* @param {Array} list2 The second list. | |
* @see R.difference | |
* @return {Array} The elements in `list1` that are not in `list2`. | |
* @example | |
* | |
* function cmp(x, y) { return 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}] | |
*/ | |
var differenceWith = _curry3(function differenceWith(pred, first, second) { | |
var out = []; | |
var idx = 0; | |
var firstLen = first.length; | |
var containsPred = containsWith(pred); | |
while (idx < firstLen) { | |
if (!containsPred(first[idx], second) && !containsPred(first[idx], out)) { | |
out[out.length] = first[idx]; | |
} | |
idx += 1; | |
} | |
return out; | |
}); | |
/** | |
* Returns a new object that does not contain a `prop` property. | |
* | |
* @func | |
* @memberOf R | |
* @category Object | |
* @sig String -> {k: v} -> {k: v} | |
* @param {String} prop the name of the property to dissociate | |
* @param {Object} obj the object to clone | |
* @return {Object} a new object similar to the original but without the specified property | |
* @example | |
* | |
* R.dissoc('b', {a: 1, b: 2, c: 3}); //=> {a: 1, c: 3} | |
*/ | |
var dissoc = _curry2(_dissoc); | |
/** | |
* Divides two numbers. Equivalent to `a / b`. | |
* | |
* @func | |
* @memberOf R | |
* @category Math | |
* @sig Number -> Number -> Number | |
* @param {Number} a The first value. | |
* @param {Number} b The second value. | |
* @return {Number} The result of `a / b`. | |
* @example | |
* | |
* R.divide(71, 100); //=> 0.71 | |
* | |
* var half = R.divide(R.__, 2); | |
* half(42); //=> 21 | |
* | |
* var reciprocal = R.divide(1); | |
* reciprocal(4); //=> 0.25 | |
*/ | |
var divide = _curry2(function divide(a, b) { | |
return a / b; | |
}); | |
/** | |
* 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. | |
* @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); | |
}; | |
}); | |
/** | |
* Tests if two items are equal. Equality is strict here, meaning reference equality for objects and | |
* non-coercing equality for primitives. | |
* | |
* Has `Object.is` semantics: `NaN` is considered equal to `NaN`; `0` and `-0` | |
* are not considered equal. | |
* @see R.identical | |
* | |
* @func | |
* @memberOf R | |
* @category Relation | |
* @sig a -> a -> Boolean | |
* @param {*} a | |
* @param {*} b | |
* @return {Boolean} | |
* @deprecated since v0.15.0 | |
* @example | |
* | |
* var o = {}; | |
* R.eq(o, o); //=> true | |
* R.eq(o, {}); //=> false | |
* R.eq(1, 1); //=> true | |
* R.eq(1, '1'); //=> false | |
* R.eq(0, -0); //=> false | |
* R.eq(NaN, NaN); //=> true | |
*/ | |
var eq = _curry2(_eq); | |
/** | |
* 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 | |
* the evolved object. | |
* | |
* @func | |
* @memberOf R | |
* @category Object | |
* @sig {k: (v -> v)} -> {k: v} -> {k: v} | |
* @param {Object} transformations The object specifying transformation functions to apply | |
* to the object. | |
* @param {Object} object The object to be transformed. | |
* @return {Object} The transformed object. | |
* @example | |
* | |
* var tomato = {firstName: ' Tomato ', elapsed: 100, remaining: 1400}; | |
* var transformations = { | |
* firstName: R.trim, | |
* lastName: R.trim, // Will not get invoked. | |
* data: {elapsed: R.add(1), remaining: R.add(-1)} | |
* }; | |
* R.evolve(transformations, tomato); //=> {firstName: 'Tomato', data: {elapsed: 101, remaining: 1399}} | |
*/ | |
var evolve = _curry2(function evolve(transformations, object) { | |
var transformation, key, type, result = {}; | |
for (key in object) { | |
transformation = transformations[key]; | |
type = typeof transformation; | |
result[key] = type === 'function' ? transformation(object[key]) : type === 'object' ? evolve(transformations[key], object[key]) : object[key]; | |
} | |
return result; | |
}); | |
/** | |
* Like `filter`, but passes additional parameters to the predicate function. The predicate | |
* function is passed three arguments: *(value, index, list)*. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig (a, i, [a] -> Boolean) -> [a] -> [a] | |
* @param {Function} fn The function called per iteration. | |
* @param {Array} list The collection to iterate over. | |
* @return {Array} The new filtered array. | |
* @deprecated since v0.15.0 | |
* @see R.addIndex | |
* @example | |
* | |
* var lastTwo = function(val, idx, list) { | |
* return list.length - idx <= 2; | |
* }; | |
* R.filterIndexed(lastTwo, [8, 6, 7, 5, 3, 0, 9]); //=> [0, 9] | |
*/ | |
var filterIndexed = _curry2(_filterIndexed); | |
/** | |
* Like `forEach`, but but passes additional parameters to the predicate function. | |
* | |
* `fn` receives three arguments: *(value, index, list)*. | |
* | |
* Note: `R.forEachIndexed` does not skip deleted or unassigned indices (sparse arrays), | |
* unlike the native `Array.prototype.forEach` method. For more details on this behavior, | |
* see: | |
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach#Description | |
* | |
* Also note that, unlike `Array.prototype.forEach`, Ramda's `forEach` returns the original | |
* array. In some libraries this function is named `each`. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig (a, i, [a] -> ) -> [a] -> [a] | |
* @param {Function} fn The function to invoke. Receives three arguments: | |
* (`value`, `index`, `list`). | |
* @param {Array} list The list to iterate over. | |
* @return {Array} The original list. | |
* @deprecated since v0.15.0 | |
* @see R.addIndex | |
* @example | |
* | |
* // Note that having access to the original `list` allows for | |
* // mutation. While you *can* do this, it's very un-functional behavior: | |
* var plusFive = function(num, idx, list) { list[idx] = num + 5 }; | |
* R.forEachIndexed(plusFive, [1, 2, 3]); //=> [6, 7, 8] | |
*/ | |
// i can't bear not to return *something* | |
var forEachIndexed = _curry2(function forEachIndexed(fn, list) { | |
var idx = 0, len = list.length; | |
while (idx < len) { | |
fn(list[idx], idx, list); | |
idx += 1; | |
} | |
// i can't bear not to return *something* | |
return list; | |
}); | |
/** | |
* Creates a new object out of a list key-value pairs. | |
* | |
* @func | |
* @memberOf R | |
* @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`. | |
* @example | |
* | |
* R.fromPairs([['a', 1], ['b', 2], ['c', 3]]); //=> {a: 1, b: 2, c: 3} | |
*/ | |
var fromPairs = _curry1(function fromPairs(pairs) { | |
var idx = 0, len = pairs.length, out = {}; | |
while (idx < len) { | |
if (_isArray(pairs[idx]) && pairs[idx].length) { | |
out[pairs[idx][0]] = pairs[idx][1]; | |
} | |
idx += 1; | |
} | |
return out; | |
}); | |
/** | |
* Returns true if the first parameter is greater than the second. | |
* | |
* @func | |
* @memberOf R | |
* @category Math | |
* @sig Number -> Number -> Boolean | |
* @param {Number} a | |
* @param {Number} b | |
* @return {Boolean} a > b | |
* @example | |
* | |
* R.gt(2, 6); //=> false | |
* R.gt(2, 0); //=> true | |
* R.gt(2, 2); //=> false | |
* R.gt(R.__, 2)(10); //=> true | |
* R.gt(2)(10); //=> false | |
*/ | |
var gt = _curry2(_gt); | |
/** | |
* Returns true if the first parameter is greater than or equal to the second. | |
* | |
* @func | |
* @memberOf R | |
* @category Math | |
* @sig Number -> Number -> Boolean | |
* @param {Number} a | |
* @param {Number} b | |
* @return {Boolean} a >= b | |
* @example | |
* | |
* R.gte(2, 6); //=> false | |
* R.gte(2, 0); //=> true | |
* R.gte(2, 2); //=> true | |
* R.gte(R.__, 6)(2); //=> false | |
* R.gte(2)(0); //=> true | |
*/ | |
var gte = _curry2(function gte(a, b) { | |
return a >= b; | |
}); | |
/** | |
* Returns whether or not an object has an own property with | |
* the specified name | |
* | |
* @func | |
* @memberOf R | |
* @category Object | |
* @sig s -> {s: x} -> Boolean | |
* @param {String} prop The name of the property to check for. | |
* @param {Object} obj The object to query. | |
* @return {Boolean} Whether the property exists. | |
* @example | |
* | |
* var hasName = R.has('name'); | |
* hasName({name: 'alice'}); //=> true | |
* hasName({name: 'bob'}); //=> true | |
* hasName({}); //=> false | |
* | |
* var point = {x: 0, y: 0}; | |
* var pointHas = R.has(R.__, point); | |
* pointHas('x'); //=> true | |
* pointHas('y'); //=> true | |
* pointHas('z'); //=> false | |
*/ | |
var has = _curry2(_has); | |
/** | |
* Returns whether or not an object or its prototype chain has | |
* a property with the specified name | |
* | |
* @func | |
* @memberOf R | |
* @category Object | |
* @sig s -> {s: x} -> Boolean | |
* @param {String} prop The name of the property to check for. | |
* @param {Object} obj The object to query. | |
* @return {Boolean} Whether the property exists. | |
* @example | |
* | |
* function Rectangle(width, height) { | |
* this.width = width; | |
* this.height = height; | |
* } | |
* Rectangle.prototype.area = function() { | |
* return this.width * this.height; | |
* }; | |
* | |
* var square = new Rectangle(2, 2); | |
* R.hasIn('width', square); //=> true | |
* R.hasIn('area', square); //=> true | |
*/ | |
var hasIn = _curry2(function (prop, obj) { | |
return prop in obj; | |
}); | |
/** | |
* Returns true if its arguments are identical, false otherwise. Values are | |
* identical if they reference the same memory. `NaN` is identical to `NaN`; | |
* `0` and `-0` are not identical. | |
* | |
* @func | |
* @memberOf R | |
* @category Relation | |
* @sig a -> a -> Boolean | |
* @param {*} a | |
* @param {*} b | |
* @return {Boolean} | |
* @example | |
* | |
* var o = {}; | |
* R.identical(o, o); //=> true | |
* R.identical(1, 1); //=> true | |
* R.identical(1, '1'); //=> false | |
* R.identical([], []); //=> false | |
* R.identical(0, -0); //=> false | |
* R.identical(NaN, NaN); //=> true | |
*/ | |
// SameValue algorithm | |
// Steps 1-5, 7-10 | |
// Steps 6.b-6.e: +0 != -0 | |
// Step 6.a: NaN == NaN | |
var identical = _curry2(function identical(a, b) { | |
// SameValue algorithm | |
if (a === b) { | |
// Steps 1-5, 7-10 | |
// Steps 6.b-6.e: +0 != -0 | |
return a !== 0 || 1 / a === 1 / b; | |
} else { | |
// Step 6.a: NaN == NaN | |
return a !== a && b !== b; | |
} | |
}); | |
/** | |
* A function that does nothing but return the parameter supplied to it. Good as a default | |
* or placeholder function. | |
* | |
* @func | |
* @memberOf R | |
* @category Function | |
* @sig a -> a | |
* @param {*} x The value to return. | |
* @return {*} The input value, `x`. | |
* @example | |
* | |
* R.identity(1); //=> 1 | |
* | |
* var obj = {}; | |
* R.identity(obj) === obj; //=> true | |
*/ | |
var identity = _curry1(_identity); | |
/** | |
* Increments its argument. | |
* | |
* @func | |
* @memberOf R | |
* @category Math | |
* @sig Number -> Number | |
* @param {Number} n | |
* @return {Number} | |
* @example | |
* | |
* R.inc(42); //=> 43 | |
*/ | |
var inc = add(1); | |
/** | |
* Inserts the sub-list into the list, at index `index`. _Note that this | |
* is not destructive_: it returns a copy of the list with the changes. | |
* <small>No lists have been harmed in the application of this function.</small> | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig Number -> [a] -> [a] -> [a] | |
* @param {Number} index The position to insert the sub-list | |
* @param {Array} elts The sub-list to insert into the Array | |
* @param {Array} list The list to insert the sub-list into | |
* @return {Array} A new Array with `elts` inserted starting at `index`. | |
* @example | |
* | |
* R.insertAll(2, ['x','y','z'], [1,2,3,4]); //=> [1,2,'x','y','z',3,4] | |
*/ | |
var insertAll = _curry3(function insertAll(idx, elts, list) { | |
idx = idx < list.length && idx >= 0 ? idx : list.length; | |
return _concat(_concat(_slice(list, 0, idx), elts), _slice(list, idx)); | |
}); | |
/** | |
* See if an object (`val`) is an instance of the supplied constructor. | |
* This function will check up the inheritance chain, if any. | |
* | |
* @func | |
* @memberOf R | |
* @category Type | |
* @sig (* -> {*}) -> a -> Boolean | |
* @param {Object} ctor A constructor | |
* @param {*} val The value to test | |
* @return {Boolean} | |
* @example | |
* | |
* R.is(Object, {}); //=> true | |
* R.is(Number, 1); //=> true | |
* R.is(Object, 1); //=> false | |
* R.is(String, 's'); //=> true | |
* R.is(String, new String('')); //=> true | |
* R.is(Object, new String('')); //=> true | |
* R.is(Object, 's'); //=> false | |
* R.is(Number, {}); //=> false | |
*/ | |
var is = _curry2(function is(Ctor, val) { | |
return val != null && val.constructor === Ctor || val instanceof Ctor; | |
}); | |
/** | |
* Tests whether or not an object is similar to an array. | |
* | |
* @func | |
* @memberOf R | |
* @category Type | |
* @category List | |
* @sig * -> Boolean | |
* @param {*} x The object to test. | |
* @return {Boolean} `true` if `x` has a numeric length property and extreme indices defined; `false` otherwise. | |
* @example | |
* | |
* R.isArrayLike([]); //=> true | |
* R.isArrayLike(true); //=> false | |
* R.isArrayLike({}); //=> false | |
* R.isArrayLike({length: 10}); //=> false | |
* R.isArrayLike({0: 'zero', 9: 'nine', length: 10}); //=> true | |
*/ | |
var isArrayLike = _curry1(function isArrayLike(x) { | |
if (_isArray(x)) { | |
return true; | |
} | |
if (!x) { | |
return false; | |
} | |
if (typeof x !== 'object') { | |
return false; | |
} | |
if (x instanceof String) { | |
return false; | |
} | |
if (x.nodeType === 1) { | |
return !!x.length; | |
} | |
if (x.length === 0) { | |
return true; | |
} | |
if (x.length > 0) { | |
return x.hasOwnProperty(0) && x.hasOwnProperty(x.length - 1); | |
} | |
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 | |
* @category Type | |
* @sig * -> Boolean | |
* @param {*} x The value to test. | |
* @return {Boolean} `true` if `x` is `undefined` or `null`, otherwise `false`. | |
* @example | |
* | |
* R.isNil(null); //=> true | |
* R.isNil(undefined); //=> true | |
* R.isNil(0); //=> false | |
* R.isNil([]); //=> false | |
*/ | |
var isNil = _curry1(function isNil(x) { | |
return x == null; | |
}); | |
/** | |
* Returns a list containing the names of all the enumerable own | |
* properties of the supplied object. | |
* Note that the order of the output array is not guaranteed to be | |
* consistent across different JS platforms. | |
* | |
* @func | |
* @memberOf R | |
* @category Object | |
* @sig {k: v} -> [k] | |
* @param {Object} obj The object to extract properties from | |
* @return {Array} An array of the object's own properties. | |
* @example | |
* | |
* R.keys({a: 1, b: 2, c: 3}); //=> ['a', 'b', 'c'] | |
*/ | |
// cover IE < 9 keys issues | |
var keys = function () { | |
// cover IE < 9 keys issues | |
var hasEnumBug = !{ toString: null }.propertyIsEnumerable('toString'); | |
var nonEnumerableProps = [ | |
'constructor', | |
'valueOf', | |
'isPrototypeOf', | |
'toString', | |
'propertyIsEnumerable', | |
'hasOwnProperty', | |
'toLocaleString' | |
]; | |
var contains = function contains(list, item) { | |
var idx = 0; | |
while (idx < list.length) { | |
if (list[idx] === item) { | |
return true; | |
} | |
idx += 1; | |
} | |
return false; | |
}; | |
return typeof Object.keys === 'function' ? _curry1(function keys(obj) { | |
return Object(obj) !== obj ? [] : Object.keys(obj); | |
}) : _curry1(function keys(obj) { | |
if (Object(obj) !== obj) { | |
return []; | |
} | |
var prop, ks = [], nIdx; | |
for (prop in obj) { | |
if (_has(prop, obj)) { | |
ks[ks.length] = prop; | |
} | |
} | |
if (hasEnumBug) { | |
nIdx = nonEnumerableProps.length - 1; | |
while (nIdx >= 0) { | |
prop = nonEnumerableProps[nIdx]; | |
if (_has(prop, obj) && !contains(ks, prop)) { | |
ks[ks.length] = prop; | |
} | |
nIdx -= 1; | |
} | |
} | |
return ks; | |
}); | |
}(); | |
/** | |
* Returns a list containing the names of all the | |
* properties of the supplied object, including prototype properties. | |
* Note that the order of the output array is not guaranteed to be | |
* consistent across different JS platforms. | |
* | |
* @func | |
* @memberOf R | |
* @category Object | |
* @sig {k: v} -> [k] | |
* @param {Object} obj The object to extract properties from | |
* @return {Array} An array of the object's own and prototype properties. | |
* @example | |
* | |
* var F = function() { this.x = 'X'; }; | |
* F.prototype.y = 'Y'; | |
* var f = new F(); | |
* R.keysIn(f); //=> ['x', 'y'] | |
*/ | |
var keysIn = _curry1(function keysIn(obj) { | |
var prop, ks = []; | |
for (prop in obj) { | |
ks[ks.length] = prop; | |
} | |
return ks; | |
}); | |
/** | |
* Returns the number of elements in the array by returning `list.length`. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig [a] -> Number | |
* @param {Array} list The array to inspect. | |
* @return {Number} The length of the array. | |
* @example | |
* | |
* R.length([]); //=> 0 | |
* R.length([1, 2, 3]); //=> 3 | |
*/ | |
var length = _curry1(function length(list) { | |
return list != null && is(Number, list.length) ? list.length : NaN; | |
}); | |
/** | |
* Creates a lens. Supply a function to `get` values from inside an object, and a `set` | |
* function to change values on an object. (n.b.: This can, and should, be done without | |
* mutating the original object!) The lens is a function wrapped around the input `get` | |
* function, with the `set` function attached as a property on the wrapper. A `map` | |
* function is also attached to the returned function that takes a function to operate | |
* on the specified (`get`) property, which is then `set` before returning. The attached | |
* `set` and `map` functions are curried. | |
* | |
* @func | |
* @memberOf R | |
* @category Object | |
* @sig (k -> v) -> (v -> a -> *) -> (a -> b) | |
* @param {Function} get A function that gets a value by property name | |
* @param {Function} set A function that sets a value by property name | |
* @return {Function} the returned function has `set` and `map` properties that are | |
* also curried functions. | |
* @example | |
* | |
* var headLens = R.lens( | |
* function get(arr) { return arr[0]; }, | |
* function set(val, arr) { return [val].concat(arr.slice(1)); } | |
* ); | |
* headLens([10, 20, 30, 40]); //=> 10 | |
* headLens.set('mu', [10, 20, 30, 40]); //=> ['mu', 20, 30, 40] | |
* headLens.map(function(x) { return x + 1; }, [10, 20, 30, 40]); //=> [11, 20, 30, 40] | |
* | |
* var phraseLens = R.lens( | |
* function get(obj) { return obj.phrase; }, | |
* function set(val, obj) { | |
* var out = R.clone(obj); | |
* out.phrase = val; | |
* return out; | |
* } | |
* ); | |
* var obj1 = { phrase: 'Absolute filth . . . and I LOVED it!'}; | |
* var obj2 = { phrase: "What's all this, then?"}; | |
* phraseLens(obj1); // => 'Absolute filth . . . and I LOVED it!' | |
* phraseLens(obj2); // => "What's all this, then?" | |
* phraseLens.set('Ooh Betty', obj1); //=> { phrase: 'Ooh Betty'} | |
* phraseLens.map(R.toUpper, obj2); //=> { phrase: "WHAT'S ALL THIS, THEN?"} | |
*/ | |
var lens = _curry2(function lens(get, set) { | |
var lns = function (a) { | |
return get(a); | |
}; | |
lns.set = _curry2(set); | |
lns.map = _curry2(function (fn, a) { | |
return set(fn(get(a)), a); | |
}); | |
return lns; | |
}); | |
/** | |
* Returns a lens associated with the provided object. | |
* | |
* @func | |
* @memberOf R | |
* @category Object | |
* @sig ({} -> v) -> (v -> a -> *) -> {} -> (a -> b) | |
* @see R.lens | |
* @param {Function} get A function that gets a value by property name | |
* @param {Function} set A function that sets a value by property name | |
* @param {Object} the actual object of interest | |
* @return {Function} the returned function has `set` and `map` properties that are | |
* also curried functions. | |
* @example | |
* | |
* var xo = {x: 1}; | |
* var xoLens = R.lensOn(function get(o) { return o.x; }, | |
* function set(v) { return {x: v}; }, | |
* xo); | |
* xoLens(); //=> 1 | |
* xoLens.set(1000); //=> {x: 1000} | |
* xoLens.map(R.add(1)); //=> {x: 2} | |
*/ | |
var lensOn = _curry3(function lensOn(get, set, obj) { | |
var lns = function () { | |
return get(obj); | |
}; | |
lns.set = set; | |
lns.map = function (fn) { | |
return set(fn(get(obj))); | |
}; | |
return lns; | |
}); | |
/** | |
* Returns true if the first parameter is less than the second. | |
* | |
* @func | |
* @memberOf R | |
* @category Math | |
* @sig Number -> Number -> Boolean | |
* @param {Number} a | |
* @param {Number} b | |
* @return {Boolean} a < b | |
* @example | |
* | |
* R.lt(2, 6); //=> true | |
* R.lt(2, 0); //=> false | |
* R.lt(2, 2); //=> false | |
* R.lt(5)(10); //=> true | |
* R.lt(R.__, 5)(10); //=> false // right-sectioned currying | |
*/ | |
var lt = _curry2(_lt); | |
/** | |
* Returns true if the first parameter is less than or equal to the second. | |
* | |
* @func | |
* @memberOf R | |
* @category Math | |
* @sig Number -> Number -> Boolean | |
* @param {Number} a | |
* @param {Number} b | |
* @return {Boolean} a <= b | |
* @example | |
* | |
* R.lte(2, 6); //=> true | |
* R.lte(2, 0); //=> false | |
* R.lte(2, 2); //=> true | |
* R.lte(R.__, 2)(1); //=> true | |
* R.lte(2)(10); //=> true | |
*/ | |
var lte = _curry2(function lte(a, b) { | |
return a <= b; | |
}); | |
/** | |
* The mapAccum function behaves like a combination of map and reduce; it applies a | |
* function to each element of a list, passing an accumulating parameter from left to | |
* right, and returning a final value of this accumulator together with the new list. | |
* | |
* The iterator function receives two arguments, *acc* and *value*, and should return | |
* a tuple *[acc, value]*. | |
* | |
* @func | |
* @memberOf R | |
* @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`. | |
* @param {*} acc The accumulator value. | |
* @param {Array} list The list to iterate over. | |
* @return {*} The final, accumulated value. | |
* @example | |
* | |
* var digits = ['1', '2', '3', '4']; | |
* var append = function(a, b) { | |
* return [a + b, a + b]; | |
* } | |
* | |
* R.mapAccum(append, 0, digits); //=> ['01234', ['01', '012', '0123', '01234']] | |
*/ | |
var mapAccum = _curry3(function mapAccum(fn, acc, list) { | |
var idx = 0, len = list.length, result = [], tuple = [acc]; | |
while (idx < len) { | |
tuple = fn(tuple[0], list[idx]); | |
result[idx] = tuple[1]; | |
idx += 1; | |
} | |
return [ | |
tuple[0], | |
result | |
]; | |
}); | |
/** | |
* The mapAccumRight function behaves like a combination of map and reduce; it applies a | |
* function to each element of a list, passing an accumulating parameter from right | |
* to left, and returning a final value of this accumulator together with the new list. | |
* | |
* Similar to `mapAccum`, except moves through the input list from the right to the | |
* left. | |
* | |
* The iterator function receives two arguments, *acc* and *value*, and should return | |
* a tuple *[acc, value]*. | |
* | |
* @func | |
* @memberOf R | |
* @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`. | |
* @param {*} acc The accumulator value. | |
* @param {Array} list The list to iterate over. | |
* @return {*} The final, accumulated value. | |
* @example | |
* | |
* var digits = ['1', '2', '3', '4']; | |
* var append = function(a, b) { | |
* return [a + b, a + b]; | |
* } | |
* | |
* R.mapAccumRight(append, 0, digits); //=> ['04321', ['04321', '0432', '043', '04']] | |
*/ | |
var mapAccumRight = _curry3(function mapAccumRight(fn, acc, list) { | |
var idx = list.length - 1, result = [], tuple = [acc]; | |
while (idx >= 0) { | |
tuple = fn(tuple[0], list[idx]); | |
result[idx] = tuple[1]; | |
idx -= 1; | |
} | |
return [ | |
tuple[0], | |
result | |
]; | |
}); | |
/** | |
* Like `map`, but but passes additional parameters to the mapping function. | |
* `fn` receives three arguments: *(value, index, list)*. | |
* | |
* Note: `R.mapIndexed` does not skip deleted or unassigned indices (sparse arrays), unlike | |
* the 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 | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig (a,i,[b] -> b) -> [a] -> [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. | |
* @deprecated since v0.15.0 | |
* @see R.addIndex | |
* @example | |
* | |
* var squareEnds = function(elt, idx, list) { | |
* if (idx === 0 || idx === list.length - 1) { | |
* return elt * elt; | |
* } | |
* return elt; | |
* }; | |
* | |
* R.mapIndexed(squareEnds, [8, 5, 3, 0, 9]); //=> [64, 5, 3, 0, 81] | |
*/ | |
var mapIndexed = _curry2(function mapIndexed(fn, list) { | |
var idx = 0, len = list.length, result = []; | |
while (idx < len) { | |
result[idx] = fn(list[idx], idx, list); | |
idx += 1; | |
} | |
return result; | |
}); | |
/** | |
* mathMod behaves like the modulo operator should mathematically, unlike the `%` | |
* operator (and by extension, R.modulo). So while "-17 % 5" is -2, | |
* mathMod(-17, 5) is 3. mathMod requires Integer arguments, and returns NaN | |
* when the modulus is zero or negative. | |
* | |
* @func | |
* @memberOf R | |
* @category Math | |
* @sig Number -> Number -> Number | |
* @param {Number} m The dividend. | |
* @param {Number} p the modulus. | |
* @return {Number} The result of `b mod a`. | |
* @see R.moduloBy | |
* @example | |
* | |
* R.mathMod(-17, 5); //=> 3 | |
* R.mathMod(17, 5); //=> 2 | |
* R.mathMod(17, -5); //=> NaN | |
* R.mathMod(17, 0); //=> NaN | |
* R.mathMod(17.2, 5); //=> NaN | |
* R.mathMod(17, 5.3); //=> NaN | |
* | |
* var clock = R.mathMod(R.__, 12); | |
* clock(15); //=> 3 | |
* clock(24); //=> 0 | |
* | |
* var seventeenMod = R.mathMod(17); | |
* seventeenMod(3); //=> 2 | |
* seventeenMod(4); //=> 1 | |
* seventeenMod(10); //=> 7 | |
*/ | |
var mathMod = _curry2(function mathMod(m, p) { | |
if (!_isInteger(m)) { | |
return NaN; | |
} | |
if (!_isInteger(p) || p < 1) { | |
return NaN; | |
} | |
return (m % p + p) % p; | |
}); | |
/** | |
* Determines the largest of a list of items as determined by pairwise comparisons from the supplied comparator. | |
* Note that this will return undefined if supplied an empty list. | |
* | |
* @func | |
* @memberOf R | |
* @category Math | |
* @sig (a -> Number) -> [a] -> a | |
* @param {Function} keyFn A comparator function for elements in the list | |
* @param {Array} list A list of comparable elements | |
* @return {*} The greatest element in the list. `undefined` if the list is empty. | |
* @see R.max | |
* @example | |
* | |
* function cmp(obj) { return obj.x; } | |
* var a = {x: 1}, b = {x: 2}, c = {x: 3}; | |
* R.maxBy(cmp, [a, b, c]); //=> {x: 3} | |
*/ | |
var maxBy = _curry2(_createMaxMinBy(_gt)); | |
/** | |
* Determines the smallest of a list of items as determined by pairwise comparisons from the supplied comparator | |
* Note that this will return undefined if supplied an empty list. | |
* | |
* @func | |
* @memberOf R | |
* @category Math | |
* @sig (a -> Number) -> [a] -> a | |
* @param {Function} keyFn A comparator function for elements in the list | |
* @param {Array} list A list of comparable elements | |
* @see R.min | |
* @return {*} The greatest element in the list. `undefined` if the list is empty. | |
* @example | |
* | |
* function cmp(obj) { return obj.x; } | |
* var a = {x: 1}, b = {x: 2}, c = {x: 3}; | |
* R.minBy(cmp, [a, b, c]); //=> {x: 1} | |
*/ | |
var minBy = _curry2(_createMaxMinBy(_lt)); | |
/** | |
* 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` | |
* | |
* @func | |
* @memberOf R | |
* @category Math | |
* @sig Number -> Number -> Number | |
* @param {Number} a The value to the divide. | |
* @param {Number} b The pseudo-modulus | |
* @return {Number} The result of `b % a`. | |
* @see R.mathMod | |
* @example | |
* | |
* R.modulo(17, 3); //=> 2 | |
* // JS behavior: | |
* R.modulo(-17, 3); //=> -2 | |
* R.modulo(17, -3); //=> 2 | |
* | |
* var isOdd = R.modulo(R.__, 2); | |
* isOdd(42); //=> 0 | |
* isOdd(21); //=> 1 | |
*/ | |
var modulo = _curry2(function modulo(a, b) { | |
return a % b; | |
}); | |
/** | |
* Multiplies two numbers. Equivalent to `a * b` but curried. | |
* | |
* @func | |
* @memberOf R | |
* @category Math | |
* @sig Number -> Number -> Number | |
* @param {Number} a The first value. | |
* @param {Number} b The second value. | |
* @return {Number} The result of `a * b`. | |
* @example | |
* | |
* var double = R.multiply(2); | |
* var triple = R.multiply(3); | |
* double(3); //=> 6 | |
* triple(4); //=> 12 | |
* R.multiply(2, 5); //=> 10 | |
*/ | |
var multiply = _curry2(_multiply); | |
/** | |
* Wraps a function of any arity (including nullary) in a function that accepts exactly `n` | |
* parameters. Any extraneous parameters will not be passed to the supplied function. | |
* | |
* @func | |
* @memberOf R | |
* @category Function | |
* @sig Number -> (* -> a) -> (* -> a) | |
* @param {Number} n The desired arity of the new function. | |
* @param {Function} fn The function to wrap. | |
* @return {Function} A new function wrapping `fn`. The new function is guaranteed to be of | |
* arity `n`. | |
* @example | |
* | |
* var takesTwoArgs = function(a, b) { | |
* return [a, b]; | |
* }; | |
* takesTwoArgs.length; //=> 2 | |
* takesTwoArgs(1, 2); //=> [1, 2] | |
* | |
* var takesOneArg = R.nAry(1, takesTwoArgs); | |
* takesOneArg.length; //=> 1 | |
* // Only `n` arguments are passed to the wrapped function | |
* takesOneArg(1, 2); //=> [1, undefined] | |
*/ | |
var nAry = _curry2(function (n, fn) { | |
switch (n) { | |
case 0: | |
return function () { | |
return fn.call(this); | |
}; | |
case 1: | |
return function (a0) { | |
return fn.call(this, a0); | |
}; | |
case 2: | |
return function (a0, a1) { | |
return fn.call(this, a0, a1); | |
}; | |
case 3: | |
return function (a0, a1, a2) { | |
return fn.call(this, a0, a1, a2); | |
}; | |
case 4: | |
return function (a0, a1, a2, a3) { | |
return fn.call(this, a0, a1, a2, a3); | |
}; | |
case 5: | |
return function (a0, a1, a2, a3, a4) { | |
return fn.call(this, a0, a1, a2, a3, a4); | |
}; | |
case 6: | |
return function (a0, a1, a2, a3, a4, a5) { | |
return fn.call(this, a0, a1, a2, a3, a4, a5); | |
}; | |
case 7: | |
return function (a0, a1, a2, a3, a4, a5, a6) { | |
return fn.call(this, a0, a1, a2, a3, a4, a5, a6); | |
}; | |
case 8: | |
return function (a0, a1, a2, a3, a4, a5, a6, a7) { | |
return fn.call(this, a0, a1, a2, a3, a4, a5, a6, a7); | |
}; | |
case 9: | |
return function (a0, a1, a2, a3, a4, a5, a6, a7, a8) { | |
return fn.call(this, a0, a1, a2, a3, a4, a5, a6, a7, a8); | |
}; | |
case 10: | |
return function (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) { | |
return fn.call(this, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); | |
}; | |
default: | |
throw new Error('First argument to nAry must be a non-negative integer no greater than ten'); | |
} | |
}); | |
/** | |
* Negates its argument. | |
* | |
* @func | |
* @memberOf R | |
* @category Math | |
* @sig Number -> Number | |
* @param {Number} n | |
* @return {Number} | |
* @example | |
* | |
* R.negate(42); //=> -42 | |
*/ | |
var negate = _curry1(function negate(n) { | |
return -n; | |
}); | |
/** | |
* A function that returns the `!` of its argument. It will return `true` when | |
* passed false-y value, and `false` when passed a truth-y one. | |
* | |
* @func | |
* @memberOf R | |
* @category Logic | |
* @sig * -> Boolean | |
* @param {*} a any value | |
* @return {Boolean} the logical inverse of passed argument. | |
* @see R.complement | |
* @example | |
* | |
* R.not(true); //=> false | |
* R.not(false); //=> true | |
* R.not(0); => true | |
* R.not(1); => false | |
*/ | |
var not = _curry1(function not(a) { | |
return !a; | |
}); | |
/** | |
* Returns the nth element in a list. | |
* If n is negative the element at index length + n is returned. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig Number -> [a] -> a | |
* @param {Number} idx | |
* @param {Array} list | |
* @return {*} The nth element of the list. | |
* @example | |
* | |
* var list = ['foo', 'bar', 'baz', 'quux']; | |
* R.nth(1, list); //=> 'bar' | |
* R.nth(-1, list); //=> 'quux' | |
* R.nth(-99, list); //=> undefined | |
*/ | |
var nth = _curry2(_nth); | |
/** | |
* Returns a function which returns its nth argument. | |
* | |
* @func | |
* @memberOf R | |
* @category Function | |
* @sig Number -> *... -> * | |
* @param {Number} n | |
* @return {Function} | |
* @example | |
* | |
* R.nthArg(1)('a', 'b', 'c'); //=> 'b' | |
* R.nthArg(-1)('a', 'b', 'c'); //=> 'c' | |
*/ | |
var nthArg = _curry1(function nthArg(n) { | |
return function () { | |
return _nth(n, arguments); | |
}; | |
}); | |
/** | |
* 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} | |
* @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. | |
* | |
* @func | |
* @memberOf R | |
* @category String | |
* @sig Number -> String -> Number | |
* @param {Number} n | |
* @param {String} str | |
* @return {Number} | |
* @example | |
* | |
* R.nthCharCode(2, 'Ramda'); //=> 'm'.charCodeAt(0) | |
* R.nthCharCode(-2, 'Ramda'); //=> 'd'.charCodeAt(0) | |
*/ | |
var nthCharCode = _curry2(function nthCharCode(n, str) { | |
return str.charCodeAt(n < 0 ? str.length + n : n); | |
}); | |
/** | |
* Returns a singleton array containing the value provided. | |
* | |
* Note this `of` is different from the ES6 `of`; See | |
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/of | |
* | |
* @func | |
* @memberOf R | |
* @category Function | |
* @sig a -> [a] | |
* @param {*} x any value | |
* @return {Array} An array wrapping `x`. | |
* @example | |
* | |
* R.of(null); //=> [null] | |
* R.of([42]); //=> [[42]] | |
*/ | |
var of = _curry1(function of(x) { | |
return [x]; | |
}); | |
/** | |
* 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. | |
* | |
* @func | |
* @memberOf R | |
* @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; }); | |
* addOneOnce(10); //=> 11 | |
* addOneOnce(addOneOnce(50)); //=> 11 | |
*/ | |
var once = _curry1(function once(fn) { | |
var called = false, result; | |
return function () { | |
if (called) { | |
return result; | |
} | |
called = true; | |
result = fn.apply(this, arguments); | |
return result; | |
}; | |
}); | |
/** | |
* Retrieve the value at a given path. | |
* | |
* @func | |
* @memberOf R | |
* @category Object | |
* @sig [String] -> {*} -> * | |
* @param {Array} path The path to use. | |
* @return {*} The data at `path`. | |
* @example | |
* | |
* R.path(['a', 'b'], {a: {b: 2}}); //=> 2 | |
*/ | |
var path = _curry2(_path); | |
/** | |
* 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 | |
* @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. | |
* @example | |
* | |
* R.pick(['a', 'd'], {a: 1, b: 2, c: 3, d: 4}); //=> {a: 1, d: 4} | |
* R.pick(['a', 'e', 'f'], {a: 1, b: 2, c: 3, d: 4}); //=> {a: 1} | |
*/ | |
var pick = _curry2(function pick(names, obj) { | |
var result = {}; | |
var idx = 0; | |
while (idx < names.length) { | |
if (names[idx] in obj) { | |
result[names[idx]] = obj[names[idx]]; | |
} | |
idx += 1; | |
} | |
return result; | |
}); | |
/** | |
* Similar to `pick` except that this one includes a `key: undefined` pair for properties that don't exist. | |
* | |
* @func | |
* @memberOf R | |
* @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.pick | |
* @example | |
* | |
* R.pickAll(['a', 'd'], {a: 1, b: 2, c: 3, d: 4}); //=> {a: 1, d: 4} | |
* R.pickAll(['a', 'e', 'f'], {a: 1, b: 2, c: 3, d: 4}); //=> {a: 1, e: undefined, f: undefined} | |
*/ | |
var pickAll = _curry2(function pickAll(names, obj) { | |
var result = {}; | |
var idx = 0; | |
var len = names.length; | |
while (idx < len) { | |
var name = names[idx]; | |
result[name] = obj[name]; | |
idx += 1; | |
} | |
return result; | |
}); | |
/** | |
* Returns a partial copy of an object containing only the keys that | |
* satisfy the supplied predicate. | |
* | |
* @func | |
* @memberOf R | |
* @category Object | |
* @sig (v, k -> Boolean) -> {k: v} -> {k: v} | |
* @param {Function} pred A predicate to determine whether or not a key | |
* should be included on the output object. | |
* @param {Object} obj The object to copy from | |
* @return {Object} A new object with only properties that satisfy `pred` | |
* on it. | |
* @see R.pick | |
* @example | |
* | |
* var isUpperCase = function(val, key) { return 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) { | |
var result = {}; | |
for (var prop in obj) { | |
if (test(obj[prop], prop, obj)) { | |
result[prop] = obj[prop]; | |
} | |
} | |
return result; | |
}); | |
/** | |
* Returns a new list with the given element at the front, followed by the contents of the | |
* list. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig a -> [a] -> [a] | |
* @param {*} el The item to add to the head of the output list. | |
* @param {Array} list The array to add to the tail of the output list. | |
* @return {Array} A new array. | |
* @example | |
* | |
* R.prepend('fee', ['fi', 'fo', 'fum']); //=> ['fee', 'fi', 'fo', 'fum'] | |
*/ | |
var prepend = _curry2(_prepend); | |
/** | |
* Returns a function that when supplied an object returns the indicated property of that object, if it exists. | |
* | |
* @func | |
* @memberOf R | |
* @category Object | |
* @sig s -> {s: a} -> a | |
* @param {String} p The property name | |
* @param {Object} obj The object to query | |
* @return {*} The value at `obj.p`. | |
* @example | |
* | |
* R.prop('x', {x: 100}); //=> 100 | |
* R.prop('x', {}); //=> undefined | |
*/ | |
var prop = _curry2(function prop(p, obj) { | |
return obj[p]; | |
}); | |
/** | |
* If the given, non-null object has an own property with the specified name, | |
* returns the value of that property. | |
* Otherwise returns the provided default value. | |
* | |
* @func | |
* @memberOf R | |
* @category Object | |
* @sig a -> String -> Object -> a | |
* @param {*} val The default value. | |
* @param {String} p The name of the property to return. | |
* @param {Object} obj The object to query. | |
* @return {*} The value of given property of the supplied object or the default value. | |
* @example | |
* | |
* var alice = { | |
* name: 'ALICE', | |
* age: 101 | |
* }; | |
* var favorite = R.prop('favoriteLibrary'); | |
* var favoriteWithDefault = R.propOr('Ramda', 'favoriteLibrary'); | |
* | |
* favorite(alice); //=> undefined | |
* favoriteWithDefault(alice); //=> 'Ramda' | |
*/ | |
var propOr = _curry3(function propOr(val, p, obj) { | |
return obj != null && _has(p, obj) ? obj[p] : val; | |
}); | |
/** | |
* Acts as multiple `get`: array of keys in, array of values out. Preserves order. | |
* | |
* @func | |
* @memberOf R | |
* @category Object | |
* @sig [k] -> {k: v} -> [v] | |
* @param {Array} ps The property names to fetch | |
* @param {Object} obj The object to query | |
* @return {Array} The corresponding values or partially applied function. | |
* @example | |
* | |
* R.props(['x', 'y'], {x: 1, y: 2}); //=> [1, 2] | |
* R.props(['c', 'a', 'b'], {b: 2, a: 1}); //=> [undefined, 1, 2] | |
* | |
* var fullName = R.compose(R.join(' '), R.props(['first', 'last'])); | |
* fullName({last: 'Bullet-Tooth', age: 33, first: 'Tony'}); //=> 'Tony Bullet-Tooth' | |
*/ | |
var props = _curry2(function props(ps, obj) { | |
var len = ps.length; | |
var out = []; | |
var idx = 0; | |
while (idx < len) { | |
out[idx] = obj[ps[idx]]; | |
idx += 1; | |
} | |
return out; | |
}); | |
/** | |
* Returns a list of numbers from `from` (inclusive) to `to` | |
* (exclusive). | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig Number -> Number -> [Number] | |
* @param {Number} from The first number in the list. | |
* @param {Number} to One more than the last number in the list. | |
* @return {Array} The list of numbers in tthe set `[a, b)`. | |
* @example | |
* | |
* R.range(1, 5); //=> [1, 2, 3, 4] | |
* R.range(50, 53); //=> [50, 51, 52] | |
*/ | |
var range = _curry2(function range(from, to) { | |
var result = []; | |
var n = from; | |
while (n < to) { | |
result[result.length] = n; | |
n += 1; | |
} | |
return result; | |
}); | |
/** | |
* Like `reduce`, but passes additional parameters to the predicate function. | |
* | |
* The iterator function receives four values: *(acc, value, index, list)* | |
* | |
* Note: `R.reduceIndexed` does not skip deleted or unassigned indices (sparse arrays), | |
* unlike the native `Array.prototype.reduce` method. For more details on this behavior, | |
* see: | |
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce#Description | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig (a,b,i,[b] -> a) -> a -> [b] -> a | |
* @param {Function} fn The iterator function. Receives four values: the accumulator, the | |
* current element from `list`, that element's index, and the entire `list` itself. | |
* @param {*} acc The accumulator value. | |
* @param {Array} list The list to iterate over. | |
* @return {*} The final, accumulated value. | |
* @deprecated since v0.15.0 | |
* @see R.addIndex | |
* @example | |
* | |
* var letters = ['a', 'b', 'c']; | |
* var objectify = function(accObject, elem, idx, list) { | |
* accObject[elem] = idx; | |
* return accObject; | |
* }; | |
* | |
* R.reduceIndexed(objectify, {}, letters); //=> { 'a': 0, 'b': 1, 'c': 2 } | |
*/ | |
var reduceIndexed = _curry3(function reduceIndexed(fn, acc, list) { | |
var idx = 0, len = list.length; | |
while (idx < len) { | |
acc = fn(acc, list[idx], idx, list); | |
idx += 1; | |
} | |
return acc; | |
}); | |
/** | |
* Returns a single item by iterating through the list, successively calling the iterator | |
* function and passing it an accumulator value and the current value from the array, and | |
* then passing the result to the next call. | |
* | |
* Similar to `reduce`, except moves through the input list from the right to the left. | |
* | |
* The iterator function receives two values: *(acc, value)* | |
* | |
* Note: `R.reduceRight` does not skip deleted or unassigned indices (sparse arrays), unlike | |
* the native `Array.prototype.reduce` method. For more details on this behavior, see: | |
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduceRight#Description | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig (a,b -> a) -> a -> [b] -> a | |
* @param {Function} fn The iterator function. Receives two values, the accumulator and the | |
* current element from the array. | |
* @param {*} acc The accumulator value. | |
* @param {Array} list The list to iterate over. | |
* @return {*} The final, accumulated value. | |
* @example | |
* | |
* var pairs = [ ['a', 1], ['b', 2], ['c', 3] ]; | |
* var flattenPairs = function(acc, pair) { | |
* return acc.concat(pair); | |
* }; | |
* | |
* R.reduceRight(flattenPairs, [], pairs); //=> [ 'c', 3, 'b', 2, 'a', 1 ] | |
*/ | |
var reduceRight = _curry3(function reduceRight(fn, acc, list) { | |
var idx = list.length - 1; | |
while (idx >= 0) { | |
acc = fn(acc, list[idx]); | |
idx -= 1; | |
} | |
return acc; | |
}); | |
/** | |
* Like `reduceRight`, but passes additional parameters to the predicate function. Moves through | |
* the input list from the right to the left. | |
* | |
* The iterator function receives four values: *(acc, value, index, list)*. | |
* | |
* Note: `R.reduceRightIndexed` does not skip deleted or unassigned indices (sparse arrays), | |
* unlike the native `Array.prototype.reduce` method. For more details on this behavior, | |
* see: | |
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduceRight#Description | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig (a,b,i,[b] -> a -> [b] -> a | |
* @param {Function} fn The iterator function. Receives four values: the accumulator, the | |
* current element from `list`, that element's index, and the entire `list` itself. | |
* @param {*} acc The accumulator value. | |
* @param {Array} list The list to iterate over. | |
* @return {*} The final, accumulated value. | |
* @deprecated since v0.15.0 | |
* @see R.addIndex | |
* @example | |
* | |
* var letters = ['a', 'b', 'c']; | |
* var objectify = function(accObject, elem, idx, list) { | |
* accObject[elem] = idx; | |
* return accObject; | |
* }; | |
* | |
* R.reduceRightIndexed(objectify, {}, letters); //=> { 'c': 2, 'b': 1, 'a': 0 } | |
*/ | |
var reduceRightIndexed = _curry3(function reduceRightIndexed(fn, acc, list) { | |
var idx = list.length - 1; | |
while (idx >= 0) { | |
acc = fn(acc, list[idx], idx, list); | |
idx -= 1; | |
} | |
return acc; | |
}); | |
/** | |
* Returns a value wrapped to indicate that it is the final value of the | |
* reduce and transduce functions. The returned value | |
* should be considered a black box: the internal structure is not | |
* guaranteed to be stable. | |
* | |
* Note: this optimization is unavailable to functions not explicitly listed | |
* above. For instance, it is not currently supported by reduceIndexed, | |
* reduceRight, or reduceRightIndexed. | |
* @see R.reduce | |
* @see R.transduce | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig a -> * | |
* @param {*} x The final value of the reduce. | |
* @return {*} The wrapped value. | |
* @example | |
* | |
* R.reduce( | |
* R.pipe(R.add, R.ifElse(R.lte(10), R.reduced, R.identity)), | |
* 0, | |
* [1, 2, 3, 4, 5]) // 10 | |
*/ | |
var reduced = _curry1(_reduced); | |
/** | |
* Like `reject`, but passes additional parameters to the predicate function. The predicate | |
* function is passed three arguments: *(value, index, list)*. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig (a, i, [a] -> Boolean) -> [a] -> [a] | |
* @param {Function} fn The function called per iteration. | |
* @param {Array} list The collection to iterate over. | |
* @return {Array} The new filtered array. | |
* @deprecated since v0.15.0 | |
* @see R.addIndex | |
* @example | |
* | |
* var lastTwo = function(val, idx, list) { | |
* return list.length - idx <= 2; | |
* }; | |
* | |
* R.rejectIndexed(lastTwo, [8, 6, 7, 5, 3, 0, 9]); //=> [8, 6, 7, 5, 3] | |
*/ | |
var rejectIndexed = _curry2(function rejectIndexed(fn, list) { | |
return _filterIndexed(_complement(fn), list); | |
}); | |
/** | |
* Removes the sub-list of `list` starting at index `start` and containing | |
* `count` elements. _Note that this is not destructive_: it returns a | |
* copy of the list with the changes. | |
* <small>No lists have been harmed in the application of this function.</small> | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig Number -> Number -> [a] -> [a] | |
* @param {Number} start The position to start removing elements | |
* @param {Number} count The number of elements to remove | |
* @param {Array} list The list to remove from | |
* @return {Array} A new Array with `count` elements from `start` removed. | |
* @example | |
* | |
* R.remove(2, 3, [1,2,3,4,5,6,7,8]); //=> [1,2,6,7,8] | |
*/ | |
var remove = _curry3(function remove(start, count, list) { | |
return _concat(_slice(list, 0, Math.min(start, list.length)), _slice(list, Math.min(list.length, start + count))); | |
}); | |
/** | |
* Replace a substring or regex match in a string with a replacement. | |
* | |
* @func | |
* @memberOf R | |
* @category String | |
* @sig RegExp|String -> String -> String -> String | |
* @param {RegExp|String} pattern A regular expression or a substring to match. | |
* @param {String} replacement The string to replace the matches with. | |
* @param {String} str The String to do the search and replacement in. | |
* @return {String} The result. | |
* @example | |
* | |
* R.replace('foo', 'bar', 'foo foo foo'); //=> 'bar foo foo' | |
* R.replace(/foo/, 'bar', 'foo foo foo'); //=> 'bar foo foo' | |
* | |
* // Use the "g" (global) flag to replace all occurrences: | |
* R.replace(/foo/g, 'bar', 'foo foo foo'); //=> 'bar bar bar' | |
*/ | |
var replace = _curry3(function replace(regex, replacement, str) { | |
return str.replace(regex, replacement); | |
}); | |
/** | |
* Returns a new list with the same elements as the original list, just | |
* in the reverse order. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig [a] -> [a] | |
* @param {Array} list The list to reverse. | |
* @return {Array} A copy of the list in reverse order. | |
* @example | |
* | |
* R.reverse([1, 2, 3]); //=> [3, 2, 1] | |
* R.reverse([1, 2]); //=> [2, 1] | |
* R.reverse([1]); //=> [1] | |
* R.reverse([]); //=> [] | |
*/ | |
var reverse = _curry1(function reverse(list) { | |
return _slice(list).reverse(); | |
}); | |
/** | |
* Scan is similar to reduce, but returns a list of successively reduced values from the left | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig (a,b -> a) -> a -> [b] -> [a] | |
* @param {Function} fn The iterator function. Receives two values, the accumulator and the | |
* current element from the array | |
* @param {*} acc The accumulator value. | |
* @param {Array} list The list to iterate over. | |
* @return {Array} A list of all intermediately reduced values. | |
* @example | |
* | |
* var numbers = [1, 2, 3, 4]; | |
* var factorials = R.scan(R.multiply, 1, numbers); //=> [1, 1, 2, 6, 24] | |
*/ | |
var scan = _curry3(function scan(fn, acc, list) { | |
var idx = 0, len = list.length, result = [acc]; | |
while (idx < len) { | |
acc = fn(acc, list[idx]); | |
result[idx + 1] = acc; | |
idx += 1; | |
} | |
return result; | |
}); | |
/** | |
* Returns a copy of the list, sorted according to the comparator function, which should accept two values at a | |
* time and return a negative number if the first value is smaller, a positive number if it's larger, and zero | |
* if they are equal. Please note that this is a **copy** of the list. It does not modify the original. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig (a,a -> Number) -> [a] -> [a] | |
* @param {Function} comparator A sorting function :: a -> b -> Int | |
* @param {Array} list The list to sort | |
* @return {Array} a new array with its elements sorted by the comparator function. | |
* @example | |
* | |
* var diff = function(a, b) { return a - b; }; | |
* R.sort(diff, [4,2,7,5]); //=> [2, 4, 5, 7] | |
*/ | |
var sort = _curry2(function sort(comparator, list) { | |
return _slice(list).sort(comparator); | |
}); | |
/** | |
* Sorts the list according to the supplied function. | |
* | |
* @func | |
* @memberOf R | |
* @category Relation | |
* @sig Ord b => (a -> b) -> [a] -> [a] | |
* @param {Function} fn | |
* @param {Array} list The list to sort. | |
* @return {Array} A new list sorted by the keys generated by `fn`. | |
* @example | |
* | |
* var sortByFirstItem = R.sortBy(prop(0)); | |
* var sortByNameCaseInsensitive = R.sortBy(compose(R.toLower, prop('name'))); | |
* var pairs = [[-1, 1], [-2, 2], [-3, 3]]; | |
* sortByFirstItem(pairs); //=> [[-3, 3], [-2, 2], [-1, 1]] | |
* var alice = { | |
* name: 'ALICE', | |
* age: 101 | |
* }; | |
* var bob = { | |
* name: 'Bob', | |
* age: -10 | |
* }; | |
* var clara = { | |
* name: 'clara', | |
* age: 314.159 | |
* }; | |
* var people = [clara, bob, alice]; | |
* sortByNameCaseInsensitive(people); //=> [alice, bob, clara] | |
*/ | |
var sortBy = _curry2(function sortBy(fn, list) { | |
return _slice(list).sort(function (a, b) { | |
var aa = fn(a); | |
var bb = fn(b); | |
return aa < bb ? -1 : aa > bb ? 1 : 0; | |
}); | |
}); | |
/** | |
* Finds the first index of a substring in a string, returning -1 if it's not present | |
* | |
* @func | |
* @memberOf R | |
* @category String | |
* @sig String -> String -> Number | |
* @param {String} c A string to find. | |
* @param {String} str The string to search in | |
* @return {Number} The first index of `c` or -1 if not found. | |
* @deprecated since v0.15.0 | |
* @example | |
* | |
* R.strIndexOf('c', 'abcdefg'); //=> 2 | |
*/ | |
var strIndexOf = _curry2(function strIndexOf(c, str) { | |
return str.indexOf(c); | |
}); | |
/** | |
* | |
* Finds the last index of a substring in a string, returning -1 if it's not present | |
* | |
* @func | |
* @memberOf R | |
* @category String | |
* @sig String -> String -> Number | |
* @param {String} c A string to find. | |
* @param {String} str The string to search in | |
* @return {Number} The last index of `c` or -1 if not found. | |
* @deprecated since v0.15.0 | |
* @example | |
* | |
* R.strLastIndexOf('a', 'banana split'); //=> 5 | |
*/ | |
var strLastIndexOf = _curry2(function (c, str) { | |
return str.lastIndexOf(c); | |
}); | |
/** | |
* Subtracts two numbers. Equivalent to `a - b` but curried. | |
* | |
* @func | |
* @memberOf R | |
* @category Math | |
* @sig Number -> Number -> Number | |
* @param {Number} a The first value. | |
* @param {Number} b The second value. | |
* @return {Number} The result of `a - b`. | |
* @example | |
* | |
* R.subtract(10, 8); //=> 2 | |
* | |
* var minus5 = R.subtract(R.__, 5); | |
* minus5(17); //=> 12 | |
* | |
* var complementaryAngle = R.subtract(90); | |
* complementaryAngle(30); //=> 60 | |
* complementaryAngle(72); //=> 18 | |
*/ | |
var subtract = _curry2(function subtract(a, b) { | |
return a - b; | |
}); | |
/** | |
* Runs the given function with the supplied object, then returns the object. | |
* | |
* @func | |
* @memberOf R | |
* @category Function | |
* @sig (a -> *) -> a -> a | |
* @param {Function} fn The function to call with `x`. The return value of `fn` will be thrown away. | |
* @param {*} x | |
* @return {*} `x`. | |
* @example | |
* | |
* var sayX = function(x) { console.log('x is ' + x); }; | |
* R.tap(sayX, 100); //=> 100 | |
* //-> 'x is 100' | |
*/ | |
var tap = _curry2(function tap(fn, x) { | |
fn(x); | |
return x; | |
}); | |
/** | |
* Determines whether a given string matches a given regular expression. | |
* | |
* @func | |
* @memberOf R | |
* @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`. | |
* @example | |
* | |
* R.times(R.identity, 5); //=> [0, 1, 2, 3, 4] | |
*/ | |
var times = _curry2(function times(fn, n) { | |
var len = Number(n); | |
var list = new Array(len); | |
var idx = 0; | |
while (idx < len) { | |
list[idx] = fn(idx); | |
idx += 1; | |
} | |
return list; | |
}); | |
/** | |
* Converts an object into an array of key, value arrays. | |
* Only the object's own properties are used. | |
* Note that the order of the output array is not guaranteed to be | |
* consistent across different JS platforms. | |
* | |
* @func | |
* @memberOf R | |
* @category Object | |
* @sig {String: *} -> [[String,*]] | |
* @param {Object} obj The object to extract from | |
* @return {Array} An array of key, value arrays from the object's own properties. | |
* @example | |
* | |
* R.toPairs({a: 1, b: 2, c: 3}); //=> [['a', 1], ['b', 2], ['c', 3]] | |
*/ | |
var toPairs = _curry1(function toPairs(obj) { | |
var pairs = []; | |
for (var prop in obj) { | |
if (_has(prop, obj)) { | |
pairs[pairs.length] = [ | |
prop, | |
obj[prop] | |
]; | |
} | |
} | |
return pairs; | |
}); | |
/** | |
* Converts an object into an array of key, value arrays. | |
* The object's own properties and prototype properties are used. | |
* Note that the order of the output array is not guaranteed to be | |
* consistent across different JS platforms. | |
* | |
* @func | |
* @memberOf R | |
* @category Object | |
* @sig {String: *} -> [[String,*]] | |
* @param {Object} obj The object to extract from | |
* @return {Array} An array of key, value arrays from the object's own | |
* and prototype properties. | |
* @example | |
* | |
* var F = function() { this.x = 'X'; }; | |
* F.prototype.y = 'Y'; | |
* var f = new F(); | |
* R.toPairsIn(f); //=> [['x','X'], ['y','Y']] | |
*/ | |
var toPairsIn = _curry1(function toPairsIn(obj) { | |
var pairs = []; | |
for (var prop in obj) { | |
pairs[pairs.length] = [ | |
prop, | |
obj[prop] | |
]; | |
} | |
return pairs; | |
}); | |
/** | |
* Removes (strips) whitespace from both ends of the string. | |
* | |
* @func | |
* @memberOf R | |
* @category String | |
* @sig String -> String | |
* @param {String} str The string to trim. | |
* @return {String} Trimmed version of `str`. | |
* @example | |
* | |
* R.trim(' xyz '); //=> 'xyz' | |
* R.map(R.trim, R.split(',', 'x, y, z')); //=> ['x', 'y', 'z'] | |
*/ | |
var trim = function () { | |
var ws = '\t\n\x0B\f\r \xA0\u1680\u180E\u2000\u2001\u2002\u2003' + '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028' + '\u2029\uFEFF'; | |
var zeroWidth = '\u200B'; | |
var hasProtoTrim = typeof String.prototype.trim === 'function'; | |
if (!hasProtoTrim || (ws.trim() || !zeroWidth.trim())) { | |
return _curry1(function trim(str) { | |
var beginRx = new RegExp('^[' + ws + '][' + ws + ']*'); | |
var endRx = new RegExp('[' + ws + '][' + ws + ']*$'); | |
return str.replace(beginRx, '').replace(endRx, ''); | |
}); | |
} else { | |
return _curry1(function trim(str) { | |
return str.trim(); | |
}); | |
} | |
}(); | |
/** | |
* Gives a single-word string description of the (native) type of a value, returning such | |
* answers as 'Object', 'Number', 'Array', or 'Null'. Does not attempt to distinguish user | |
* Object types any further, reporting them all as 'Object'. | |
* | |
* @func | |
* @memberOf R | |
* @category Type | |
* @sig (* -> {*}) -> String | |
* @param {*} val The value to test | |
* @return {String} | |
* @example | |
* | |
* R.type({}); //=> "Object" | |
* R.type(1); //=> "Number" | |
* R.type(false); //=> "Boolean" | |
* R.type('s'); //=> "String" | |
* R.type(null); //=> "Null" | |
* R.type([]); //=> "Array" | |
* R.type(/[A-z]/); //=> "RegExp" | |
*/ | |
var type = _curry1(function type(val) { | |
return val === null ? 'Null' : val === undefined ? 'Undefined' : Object.prototype.toString.call(val).slice(8, -1); | |
}); | |
/** | |
* Takes a function `fn`, which takes a single array argument, and returns | |
* a function which: | |
* | |
* - takes any number of positional arguments; | |
* - passes these arguments to `fn` as an array; and | |
* - returns the result. | |
* | |
* In other words, R.unapply derives a variadic function from a function | |
* which takes an array. R.unapply is the inverse of R.apply. | |
* | |
* @func | |
* @memberOf R | |
* @category Function | |
* @sig ([*...] -> a) -> (*... -> a) | |
* @param {Function} fn | |
* @return {Function} | |
* @see R.apply | |
* @example | |
* | |
* R.unapply(JSON.stringify)(1, 2, 3); //=> '[1,2,3]' | |
*/ | |
var unapply = _curry1(function unapply(fn) { | |
return function () { | |
return fn(_slice(arguments)); | |
}; | |
}); | |
/** | |
* Wraps a function of any arity (including nullary) in a function that accepts exactly 1 | |
* parameter. Any extraneous parameters will not be passed to the supplied function. | |
* | |
* @func | |
* @memberOf R | |
* @category Function | |
* @sig (* -> b) -> (a -> b) | |
* @param {Function} fn The function to wrap. | |
* @return {Function} A new function wrapping `fn`. The new function is guaranteed to be of | |
* arity 1. | |
* @example | |
* | |
* var takesTwoArgs = function(a, b) { | |
* return [a, b]; | |
* }; | |
* takesTwoArgs.length; //=> 2 | |
* takesTwoArgs(1, 2); //=> [1, 2] | |
* | |
* var takesOneArg = R.unary(takesTwoArgs); | |
* takesOneArg.length; //=> 1 | |
* // Only 1 argument is passed to the wrapped function | |
* takesOneArg(1, 2); //=> [1, undefined] | |
*/ | |
var unary = _curry1(function unary(fn) { | |
return nAry(1, fn); | |
}); | |
/** | |
* Builds a list from a seed value. Accepts an iterator function, which returns either false | |
* to stop iteration or an array of length 2 containing the value to add to the resulting | |
* list and the seed to be used in the next call to the iterator function. | |
* | |
* The iterator function receives one argument: *(seed)*. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig (a -> [b]) -> * -> [b] | |
* @param {Function} fn The iterator function. receives one argument, `seed`, and returns | |
* either false to quit iteration or an array of length two to proceed. The element | |
* at index 0 of this array will be added to the resulting array, and the element | |
* at index 1 will be passed to the next call to `fn`. | |
* @param {*} seed The seed value. | |
* @return {Array} The final list. | |
* @example | |
* | |
* var f = function(n) { return n > 50 ? false : [-n, n + 10] }; | |
* R.unfold(f, 10); //=> [-10, -20, -30, -40, -50] | |
*/ | |
var unfold = _curry2(function unfold(fn, seed) { | |
var pair = fn(seed); | |
var result = []; | |
while (pair && pair.length) { | |
result[result.length] = pair[0]; | |
pair = fn(pair[1]); | |
} | |
return result; | |
}); | |
/** | |
* Returns a new list containing only one copy of each element in the original list, based | |
* upon the value returned by applying the supplied predicate to two list elements. Prefers | |
* the first item if two items compare equal based on the predicate. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig (a, a -> Boolean) -> [a] -> [a] | |
* @param {Function} pred A predicate used to test whether two items are equal. | |
* @param {Array} list The array to consider. | |
* @return {Array} The list of unique items. | |
* @example | |
* | |
* var strEq = function(a, b) { return String(a) === String(b); }; | |
* R.uniqWith(strEq)([1, '1', 2, 1]); //=> [1, 2] | |
* R.uniqWith(strEq)([{}, {}]); //=> [{}] | |
* R.uniqWith(strEq)([1, '1', 1]); //=> [1] | |
* R.uniqWith(strEq)(['1', 1, 1]); //=> ['1'] | |
*/ | |
var uniqWith = _curry2(function uniqWith(pred, list) { | |
var idx = 0, len = list.length; | |
var result = [], item; | |
while (idx < len) { | |
item = list[idx]; | |
if (!_containsWith(pred, item, result)) { | |
result[result.length] = item; | |
} | |
idx += 1; | |
} | |
return result; | |
}); | |
/** | |
* Returns a new copy of the array with the element at the | |
* provided index replaced with the given value. | |
* @see R.adjust | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig Number -> a -> [a] -> [a] | |
* @param {Number} idx The index to update. | |
* @param {*} x The value to exist at the given index of the returned array. | |
* @param {Array|Arguments} list The source array-like object to be updated. | |
* @return {Array} A copy of `list` with the value at index `idx` replaced with `x`. | |
* @example | |
* | |
* R.update(1, 11, [0, 1, 2]); //=> [0, 11, 2] | |
* R.update(1)(11)([0, 1, 2]); //=> [0, 11, 2] | |
*/ | |
var update = _curry3(function (idx, x, list) { | |
return adjust(always(x), idx, list); | |
}); | |
/** | |
* Returns a list of all the enumerable own properties of the supplied object. | |
* Note that the order of the output array is not guaranteed across | |
* different JS platforms. | |
* | |
* @func | |
* @memberOf R | |
* @category Object | |
* @sig {k: v} -> [v] | |
* @param {Object} obj The object to extract values from | |
* @return {Array} An array of the values of the object's own properties. | |
* @example | |
* | |
* R.values({a: 1, b: 2, c: 3}); //=> [1, 2, 3] | |
*/ | |
var values = _curry1(function values(obj) { | |
var props = keys(obj); | |
var len = props.length; | |
var vals = []; | |
var idx = 0; | |
while (idx < len) { | |
vals[idx] = obj[props[idx]]; | |
idx += 1; | |
} | |
return vals; | |
}); | |
/** | |
* Returns a list of all the properties, including prototype properties, | |
* of the supplied object. | |
* Note that the order of the output array is not guaranteed to be | |
* consistent across different JS platforms. | |
* | |
* @func | |
* @memberOf R | |
* @category Object | |
* @sig {k: v} -> [v] | |
* @param {Object} obj The object to extract values from | |
* @return {Array} An array of the values of the object's own and prototype properties. | |
* @example | |
* | |
* var F = function() { this.x = 'X'; }; | |
* F.prototype.y = 'Y'; | |
* var f = new F(); | |
* R.valuesIn(f); //=> ['X', 'Y'] | |
*/ | |
var valuesIn = _curry1(function valuesIn(obj) { | |
var prop, vs = []; | |
for (prop in obj) { | |
vs[vs.length] = obj[prop]; | |
} | |
return vs; | |
}); | |
/** | |
* 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. | |
* Each predicate is applied to the value of the corresponding property of | |
* the test object. `where` returns true if all the predicates return true, | |
* false otherwise. | |
* | |
* `where` is well suited to declaratively expressing constraints for other | |
* functions such as `filter` and `find`. | |
* | |
* @func | |
* @memberOf R | |
* @category Object | |
* @sig {String: (* -> Boolean)} -> {String: *} -> Boolean | |
* @param {Object} spec | |
* @param {Object} testObj | |
* @return {Boolean} | |
* @example | |
* | |
* // pred :: Object -> Boolean | |
* var pred = R.where({ | |
* a: R.equals('foo'), | |
* b: R.complement(R.equals('bar')), | |
* x: R.gt(_, 10), | |
* y: R.lt(_, 20) | |
* }); | |
* | |
* pred({a: 'foo', b: 'xxx', x: 11, y: 19}); //=> true | |
* pred({a: 'xxx', b: 'xxx', x: 11, y: 19}); //=> false | |
* pred({a: 'foo', b: 'bar', x: 11, y: 19}); //=> false | |
* pred({a: 'foo', b: 'xxx', x: 10, y: 19}); //=> false | |
* pred({a: 'foo', b: 'xxx', x: 11, y: 20}); //=> false | |
*/ | |
var where = _curry2(function where(spec, testObj) { | |
for (var prop in spec) { | |
if (_has(prop, spec) && !spec[prop](testObj[prop])) { | |
return false; | |
} | |
} | |
return true; | |
}); | |
/** | |
* Creates a new list out of the two supplied by creating each possible | |
* pair from the lists. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig [a] -> [b] -> [[a,b]] | |
* @param {Array} as The first list. | |
* @param {Array} bs The second list. | |
* @return {Array} The list made by combining each possible pair from | |
* `as` and `bs` into pairs (`[a, b]`). | |
* @example | |
* | |
* R.xprod([1, 2], ['a', 'b']); //=> [[1, 'a'], [1, 'b'], [2, 'a'], [2, 'b']] | |
*/ | |
// = xprodWith(prepend); (takes about 3 times as long...) | |
var xprod = _curry2(function xprod(a, b) { | |
// = xprodWith(prepend); (takes about 3 times as long...) | |
var idx = 0; | |
var ilen = a.length; | |
var j; | |
var jlen = b.length; | |
var result = []; | |
while (idx < ilen) { | |
j = 0; | |
while (j < jlen) { | |
result[result.length] = [ | |
a[idx], | |
b[j] | |
]; | |
j += 1; | |
} | |
idx += 1; | |
} | |
return result; | |
}); | |
/** | |
* Creates a new list out of the two supplied by pairing up | |
* equally-positioned items from both lists. The returned list is | |
* truncated to the length of the shorter of the two input lists. | |
* Note: `zip` is equivalent to `zipWith(function(a, b) { return [a, b] })`. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig [a] -> [b] -> [[a,b]] | |
* @param {Array} list1 The first array to consider. | |
* @param {Array} list2 The second array to consider. | |
* @return {Array} The list made by pairing up same-indexed elements of `list1` and `list2`. | |
* @example | |
* | |
* R.zip([1, 2, 3], ['a', 'b', 'c']); //=> [[1, 'a'], [2, 'b'], [3, 'c']] | |
*/ | |
var zip = _curry2(function zip(a, b) { | |
var rv = []; | |
var idx = 0; | |
var len = Math.min(a.length, b.length); | |
while (idx < len) { | |
rv[idx] = [ | |
a[idx], | |
b[idx] | |
]; | |
idx += 1; | |
} | |
return rv; | |
}); | |
/** | |
* Creates a new object out of a list of keys and a list of values. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig [String] -> [*] -> {String: *} | |
* @param {Array} keys The array that will be properties on the output object. | |
* @param {Array} values The list of values on the output object. | |
* @return {Object} The object made by pairing up same-indexed elements of `keys` and `values`. | |
* @example | |
* | |
* R.zipObj(['a', 'b', 'c'], [1, 2, 3]); //=> {a: 1, b: 2, c: 3} | |
*/ | |
var zipObj = _curry2(function zipObj(keys, values) { | |
var idx = 0, len = keys.length, out = {}; | |
while (idx < len) { | |
out[keys[idx]] = values[idx]; | |
idx += 1; | |
} | |
return out; | |
}); | |
/** | |
* Creates a new list out of the two supplied by applying the function to | |
* each equally-positioned pair in the lists. The returned list is | |
* truncated to the length of the shorter of the two input lists. | |
* | |
* @function | |
* @memberOf R | |
* @category List | |
* @sig (a,b -> c) -> [a] -> [b] -> [c] | |
* @param {Function} fn The function used to combine the two elements into one value. | |
* @param {Array} list1 The first array to consider. | |
* @param {Array} list2 The second array to consider. | |
* @return {Array} The list made by combining same-indexed elements of `list1` and `list2` | |
* using `fn`. | |
* @example | |
* | |
* var f = function(x, y) { | |
* // ... | |
* }; | |
* R.zipWith(f, [1, 2, 3], ['a', 'b', 'c']); | |
* //=> [f(1, 'a'), f(2, 'b'), f(3, 'c')] | |
*/ | |
var zipWith = _curry3(function zipWith(fn, a, b) { | |
var rv = [], idx = 0, len = Math.min(a.length, b.length); | |
while (idx < len) { | |
rv[idx] = fn(a[idx], b[idx]); | |
idx += 1; | |
} | |
return rv; | |
}); | |
/** | |
* A function that always returns `false`. Any passed in parameters are ignored. | |
* | |
* @func | |
* @memberOf R | |
* @category Function | |
* @sig * -> false | |
* @see R.always | |
* @return {Boolean} false | |
* @example | |
* | |
* R.F(); //=> false | |
*/ | |
var F = always(false); | |
/** | |
* A function that always returns `true`. Any passed in parameters are ignored. | |
* | |
* @func | |
* @memberOf R | |
* @category Function | |
* @sig * -> true | |
* @see R.always | |
* @return {Boolean} `true`. | |
* @example | |
* | |
* R.T(); //=> true | |
*/ | |
var T = always(true); | |
var _append = function _append(el, list) { | |
return _concat(list, [el]); | |
}; | |
var _assocPath = function _assocPath(path, val, obj) { | |
switch (path.length) { | |
case 0: | |
return obj; | |
case 1: | |
return _assoc(path[0], val, obj); | |
default: | |
return _assoc(path[0], _assocPath(_slice(path, 1), val, Object(obj[path[0]])), obj); | |
} | |
}; | |
/** | |
* Copies an object. | |
* | |
* @private | |
* @param {*} value The value to be copied | |
* @param {Array} refFrom Array containing the source references | |
* @param {Array} refTo Array containing the copied source references | |
* @return {*} The copied value. | |
*/ | |
var _baseCopy = function _baseCopy(value, refFrom, refTo) { | |
var copy = function copy(copiedValue) { | |
var len = refFrom.length; | |
var idx = 0; | |
while (idx < len) { | |
if (value === refFrom[idx]) { | |
return refTo[idx]; | |
} | |
idx += 1; | |
} | |
refFrom[idx + 1] = value; | |
refTo[idx + 1] = copiedValue; | |
for (var key in value) { | |
copiedValue[key] = _baseCopy(value[key], refFrom, refTo); | |
} | |
return copiedValue; | |
}; | |
switch (type(value)) { | |
case 'Object': | |
return copy({}); | |
case 'Array': | |
return copy([]); | |
case 'Date': | |
return new Date(value); | |
case 'RegExp': | |
return _cloneRegExp(value); | |
default: | |
return value; | |
} | |
}; | |
/** | |
* 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 | |
* default to the ramda implementation. | |
* | |
* @private | |
* @param {Function} fn ramda implemtation | |
* @param {String} methodname property to check for a custom implementation | |
* @return {Object} Whatever the return value of the method is. | |
*/ | |
var _checkForMethod = function _checkForMethod(methodname, fn) { | |
return function () { | |
var length = arguments.length; | |
if (length === 0) { | |
return fn(); | |
} | |
var obj = arguments[length - 1]; | |
return _isArray(obj) || typeof obj[methodname] !== 'function' ? fn.apply(this, arguments) : obj[methodname].apply(obj, _slice(arguments, 0, length - 1)); | |
}; | |
}; | |
var _composeL = function _composeL(innerLens, outerLens) { | |
return lens(_compose(innerLens, outerLens), function (x, source) { | |
var newInnerValue = innerLens.set(x, outerLens(source)); | |
return outerLens.set(newInnerValue, source); | |
}); | |
}; | |
/** | |
* A right-associative two-argument composition function like `_compose` | |
* but with automatic handling of promises (or, more precisely, | |
* "thenables"). This function is used to construct a more general | |
* `composeP` function, which accepts any number of arguments. | |
* | |
* @private | |
* @category Function | |
* @param {Function} f A function. | |
* @param {Function} g A function. | |
* @return {Function} A new function that is the equivalent of `f(g(x))`. | |
* @example | |
* | |
* var Q = require('q'); | |
* var double = function(x) { return x * 2; }; | |
* var squareAsync = function(x) { return Q.when(x * x); }; | |
* var squareAsyncThenDouble = _composeP(double, squareAsync); | |
* | |
* squareAsyncThenDouble(5) | |
* .then(function(result) { | |
* // the result is now 50. | |
* }); | |
*/ | |
var _composeP = function _composeP(f, g) { | |
return function () { | |
var context = this; | |
var value = g.apply(this, arguments); | |
if (_isThenable(value)) { | |
return value.then(function (result) { | |
return f.call(context, result); | |
}); | |
} else { | |
return f.call(this, value); | |
} | |
}; | |
}; | |
/* | |
* Returns a function that makes a multi-argument version of compose from | |
* either _compose or _composeP. | |
*/ | |
var _createComposer = function _createComposer(composeFunction) { | |
return function () { | |
var fn = arguments[arguments.length - 1]; | |
var length = fn.length; | |
var idx = arguments.length - 2; | |
while (idx >= 0) { | |
fn = composeFunction(arguments[idx], fn); | |
idx -= 1; | |
} | |
return arity(length, fn); | |
}; | |
}; | |
/** | |
* Create a function which takes a list | |
* and determines the winning value by a comparator. Used internally | |
* by `R.max` and `R.min` | |
* | |
* @private | |
* @param {Function} compatator a function to compare two items | |
* @param {*} intialVal, default value if nothing else wins | |
* @category Math | |
* @return {Function} | |
*/ | |
var _createMaxMin = function _createMaxMin(comparator, initialVal) { | |
return _curry1(function (list) { | |
var idx = 0, winner = initialVal, computed; | |
while (idx < list.length) { | |
computed = +list[idx]; | |
if (comparator(computed, winner)) { | |
winner = computed; | |
} | |
idx += 1; | |
} | |
return winner; | |
}); | |
}; | |
var _createPartialApplicator = function _createPartialApplicator(concat) { | |
return function (fn) { | |
var args = _slice(arguments, 1); | |
return arity(Math.max(0, fn.length - args.length), function () { | |
return fn.apply(this, concat(args, arguments)); | |
}); | |
}; | |
}; | |
/** | |
* Internal curryN function. | |
* | |
* @private | |
* @category Function | |
* @param {Number} length The arity of the curried function. | |
* @return {array} An array of arguments received thus far. | |
* @param {Function} fn The function to curry. | |
*/ | |
var _curryN = function _curryN(length, received, fn) { | |
return function () { | |
var combined = []; | |
var argsIdx = 0; | |
var left = length; | |
var combinedIdx = 0; | |
while (combinedIdx < received.length || argsIdx < arguments.length) { | |
var result; | |
if (combinedIdx < received.length && (received[combinedIdx] == null || received[combinedIdx]['@@functional/placeholder'] !== true || argsIdx >= arguments.length)) { | |
result = received[combinedIdx]; | |
} else { | |
result = arguments[argsIdx]; | |
argsIdx += 1; | |
} | |
combined[combinedIdx] = result; | |
if (result == null || result['@@functional/placeholder'] !== true) { | |
left -= 1; | |
} | |
combinedIdx += 1; | |
} | |
return left <= 0 ? fn.apply(this, combined) : arity(left, _curryN(length, combined, fn)); | |
}; | |
}; | |
/** | |
* Returns a function that dispatches with different strategies based on the | |
* object in list position (last argument). If it is an array, executes [fn]. | |
* Otherwise, if it has a function with [methodname], it will execute that | |
* function (functor case). Otherwise, if it is a transformer, uses transducer | |
* [xf] to return a new transformer (transducer case). Otherwise, it will | |
* default to executing [fn]. | |
* | |
* @private | |
* @param {String} methodname property to check for a custom implementation | |
* @param {Function} xf transducer to initialize if object is transformer | |
* @param {Function} fn default ramda implementation | |
* @return {Function} A function that dispatches on object in list position | |
*/ | |
var _dispatchable = function _dispatchable(methodname, xf, fn) { | |
return function () { | |
var length = arguments.length; | |
if (length === 0) { | |
return fn(); | |
} | |
var obj = arguments[length - 1]; | |
if (!_isArray(obj)) { | |
var args = _slice(arguments, 0, length - 1); | |
if (typeof obj[methodname] === 'function') { | |
return obj[methodname].apply(obj, args); | |
} | |
if (_isTransformer(obj)) { | |
var transducer = xf.apply(null, args); | |
return transducer(obj); | |
} | |
} | |
return fn.apply(this, arguments); | |
}; | |
}; | |
var _dissocPath = function _dissocPath(path, obj) { | |
switch (path.length) { | |
case 0: | |
return obj; | |
case 1: | |
return _dissoc(path[0], obj); | |
default: | |
var head = path[0]; | |
var tail = _slice(path, 1); | |
return obj[head] == null ? obj : _assoc(head, _dissocPath(tail, obj[head]), obj); | |
} | |
}; | |
// The algorithm used to handle cyclic structures is | |
// inspired by underscore's isEqual | |
// RegExp equality algorithm: http://stackoverflow.com/a/10776635 | |
var _equals = function _eqDeep(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 (Object(a) === a) { | |
if (typeA === 'Date' && a.getTime() !== b.getTime()) { | |
return false; | |
} | |
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[stackA.length] = a; | |
stackB[stackB.length] = b; | |
idx = keysA.length - 1; | |
while (idx >= 0) { | |
var key = keysA[idx]; | |
if (!_has(key, b) || !_eqDeep(b[key], a[key], stackA, stackB)) { | |
return false; | |
} | |
idx -= 1; | |
} | |
stackA.pop(); | |
stackB.pop(); | |
return true; | |
} | |
return false; | |
}; | |
/** | |
* Assigns own enumerable properties of the other object to the destination | |
* object preferring items in other. | |
* | |
* @private | |
* @memberOf R | |
* @category Object | |
* @param {Object} destination The destination object. | |
* @param {Object} other The other object to merge with destination. | |
* @return {Object} The destination object. | |
* @example | |
* | |
* _extend({ 'name': 'fred', 'age': 10 }, { 'age': 40 }); | |
* //=> { 'name': 'fred', 'age': 40 } | |
*/ | |
var _extend = function _extend(destination, other) { | |
var props = keys(other); | |
var idx = 0, length = props.length; | |
while (idx < length) { | |
destination[props[idx]] = other[props[idx]]; | |
idx += 1; | |
} | |
return destination; | |
}; | |
/** | |
* 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'; | |
}; | |
/** | |
* `_makeFlat` is a helper function that returns a one-level or fully recursive function | |
* based on the flag passed in. | |
* | |
* @private | |
*/ | |
var _makeFlat = function _makeFlat(recursive) { | |
return function flatt(list) { | |
var value, result = [], idx = 0, j, ilen = list.length, jlen; | |
while (idx < ilen) { | |
if (isArrayLike(list[idx])) { | |
value = recursive ? flatt(list[idx]) : list[idx]; | |
j = 0; | |
jlen = value.length; | |
while (j < jlen) { | |
result[result.length] = value[j]; | |
j += 1; | |
} | |
} else { | |
result[result.length] = list[idx]; | |
} | |
idx += 1; | |
} | |
return result; | |
}; | |
}; | |
var _reduce = function () { | |
function _arrayReduce(xf, acc, list) { | |
var idx = 0, len = list.length; | |
while (idx < len) { | |
acc = xf['@@transducer/step'](acc, list[idx]); | |
if (acc && acc['@@transducer/reduced']) { | |
acc = acc['@@transducer/value']; | |
break; | |
} | |
idx += 1; | |
} | |
return xf['@@transducer/result'](acc); | |
} | |
function _iterableReduce(xf, acc, iter) { | |
var step = iter.next(); | |
while (!step.done) { | |
acc = xf['@@transducer/step'](acc, step.value); | |
if (acc && acc['@@transducer/reduced']) { | |
acc = acc['@@transducer/value']; | |
break; | |
} | |
step = iter.next(); | |
} | |
return xf['@@transducer/result'](acc); | |
} | |
function _methodReduce(xf, acc, obj) { | |
return xf['@@transducer/result'](obj.reduce(bind(xf['@@transducer/step'], xf), acc)); | |
} | |
var symIterator = typeof Symbol !== 'undefined' ? Symbol.iterator : '@@iterator'; | |
return function _reduce(fn, acc, list) { | |
if (typeof fn === 'function') { | |
fn = _xwrap(fn); | |
} | |
if (isArrayLike(list)) { | |
return _arrayReduce(fn, acc, list); | |
} | |
if (typeof list.reduce === 'function') { | |
return _methodReduce(fn, acc, list); | |
} | |
if (list[symIterator] != null) { | |
return _iterableReduce(fn, acc, list[symIterator]()); | |
} | |
if (typeof list.next === 'function') { | |
return _iterableReduce(fn, acc, list); | |
} | |
throw new TypeError('reduce: list must be array or iterable'); | |
}; | |
}(); | |
var _xall = function () { | |
function XAll(f, xf) { | |
this.xf = xf; | |
this.f = f; | |
this.all = true; | |
} | |
XAll.prototype['@@transducer/init'] = _xfBase.init; | |
XAll.prototype['@@transducer/result'] = function (result) { | |
if (this.all) { | |
result = this.xf['@@transducer/step'](result, true); | |
} | |
return this.xf['@@transducer/result'](result); | |
}; | |
XAll.prototype['@@transducer/step'] = function (result, input) { | |
if (!this.f(input)) { | |
this.all = false; | |
result = _reduced(this.xf['@@transducer/step'](result, false)); | |
} | |
return result; | |
}; | |
return _curry2(function _xall(f, xf) { | |
return new XAll(f, xf); | |
}); | |
}(); | |
var _xany = function () { | |
function XAny(f, xf) { | |
this.xf = xf; | |
this.f = f; | |
this.any = false; | |
} | |
XAny.prototype['@@transducer/init'] = _xfBase.init; | |
XAny.prototype['@@transducer/result'] = function (result) { | |
if (!this.any) { | |
result = this.xf['@@transducer/step'](result, false); | |
} | |
return this.xf['@@transducer/result'](result); | |
}; | |
XAny.prototype['@@transducer/step'] = function (result, input) { | |
if (this.f(input)) { | |
this.any = true; | |
result = _reduced(this.xf['@@transducer/step'](result, true)); | |
} | |
return result; | |
}; | |
return _curry2(function _xany(f, xf) { | |
return new XAny(f, xf); | |
}); | |
}(); | |
var _xdrop = function () { | |
function XDrop(n, xf) { | |
this.xf = xf; | |
this.n = n; | |
} | |
XDrop.prototype['@@transducer/init'] = _xfBase.init; | |
XDrop.prototype['@@transducer/result'] = _xfBase.result; | |
XDrop.prototype.step = function (result, input) { | |
if (this.n > 0) { | |
this.n -= 1; | |
return result; | |
} | |
return this.xf['@@transducer/step'](result, input); | |
}; | |
return _curry2(function _xdrop(n, xf) { | |
return new XDrop(n, xf); | |
}); | |
}(); | |
var _xdropWhile = function () { | |
function XDropWhile(f, xf) { | |
this.xf = xf; | |
this.f = f; | |
} | |
XDropWhile.prototype['@@transducer/init'] = _xfBase.init; | |
XDropWhile.prototype['@@transducer/result'] = _xfBase.result; | |
XDropWhile.prototype['@@transducer/step'] = function (result, input) { | |
if (this.f) { | |
if (this.f(input)) { | |
return result; | |
} | |
this.f = null; | |
} | |
return this.xf['@@transducer/step'](result, input); | |
}; | |
return _curry2(function _xdropWhile(f, xf) { | |
return new XDropWhile(f, xf); | |
}); | |
}(); | |
var _xgroupBy = function () { | |
function XGroupBy(f, xf) { | |
this.xf = xf; | |
this.f = f; | |
this.inputs = {}; | |
} | |
XGroupBy.prototype['@@transducer/init'] = _xfBase.init; | |
XGroupBy.prototype['@@transducer/result'] = function (result) { | |
var key; | |
for (key in this.inputs) { | |
if (_has(key, this.inputs)) { | |
result = this.xf['@@transducer/step'](result, this.inputs[key]); | |
if (result['@@transducer/reduced']) { | |
result = result['@@transducer/value']; | |
break; | |
} | |
} | |
} | |
return this.xf['@@transducer/result'](result); | |
}; | |
XGroupBy.prototype['@@transducer/step'] = function (result, input) { | |
var key = this.f(input); | |
this.inputs[key] = this.inputs[key] || [ | |
key, | |
[] | |
]; | |
this.inputs[key][1] = _append(input, this.inputs[key][1]); | |
return result; | |
}; | |
return _curry2(function _xgroupBy(f, xf) { | |
return new XGroupBy(f, xf); | |
}); | |
}(); | |
/** | |
* Returns `true` if all elements of the list match the predicate, `false` if there are any | |
* that don't. | |
* | |
* Acts as a transducer if a transformer is given in list position. | |
* @see R.transduce | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig (a -> Boolean) -> [a] -> Boolean | |
* @param {Function} fn The predicate function. | |
* @param {Array} list The array to consider. | |
* @return {Boolean} `true` if the predicate is satisfied by every element, `false` | |
* otherwise. | |
* @example | |
* | |
* var lessThan2 = R.flip(R.lt)(2); | |
* var lessThan3 = R.flip(R.lt)(3); | |
* R.all(lessThan2)([1, 2]); //=> false | |
* R.all(lessThan3)([1, 2]); //=> true | |
*/ | |
var all = _curry2(_dispatchable('all', _xall, _all)); | |
/** | |
* 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. | |
* @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. | |
* | |
* Acts as a transducer if a transformer is given in list position. | |
* @see R.transduce | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig (a -> Boolean) -> [a] -> Boolean | |
* @param {Function} fn The predicate function. | |
* @param {Array} list The array to consider. | |
* @return {Boolean} `true` if the predicate is satisfied by at least one element, `false` | |
* otherwise. | |
* @example | |
* | |
* var lessThan0 = R.flip(R.lt)(0); | |
* var lessThan2 = R.flip(R.lt)(2); | |
* R.any(lessThan0)([1, 2]); //=> false | |
* R.any(lessThan2)([1, 2]); //=> true | |
*/ | |
var any = _curry2(_dispatchable('any', _xany, _any)); | |
/** | |
* Returns a new list containing the contents of the given list, followed by the given | |
* element. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig a -> [a] -> [a] | |
* @param {*} el The element to add to the end of the new list. | |
* @param {Array} list The list whose contents will be added to the beginning of the output | |
* list. | |
* @return {Array} A new list containing the contents of the old list followed by `el`. | |
* @example | |
* | |
* R.append('tests', ['write', 'more']); //=> ['write', 'more', 'tests'] | |
* R.append('tests', []); //=> ['tests'] | |
* R.append(['tests'], ['write', 'more']); //=> ['write', 'more', ['tests']] | |
*/ | |
var append = _curry2(_append); | |
/** | |
* Makes a shallow clone of an object, setting or overriding the nodes | |
* required to create the given path, and placing the specific value at the | |
* tail end of that path. Note that this copies and flattens prototype | |
* properties onto the new object as well. All non-primitive properties | |
* are copied by reference. | |
* | |
* @func | |
* @memberOf R | |
* @category Object | |
* @sig [String] -> a -> {k: v} -> {k: v} | |
* @param {Array} path the path to set | |
* @param {*} val the new value | |
* @param {Object} obj the object to clone | |
* @return {Object} a new object similar to the original except along the specified path. | |
* @example | |
* | |
* R.assocPath(['a', 'b', 'c'], 42, {a: {b: {c: 0}}}); //=> {a: {b: {c: 42}}} | |
*/ | |
var assocPath = _curry3(_assocPath); | |
/** | |
* 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 | |
* @category Function | |
* @sig (* -> c) -> (a, b -> c) | |
* @param {Function} fn The function to wrap. | |
* @return {Function} A new function wrapping `fn`. The new function is guaranteed to be of | |
* arity 2. | |
* @example | |
* | |
* var takesThreeArgs = function(a, b, c) { | |
* return [a, b, c]; | |
* }; | |
* takesThreeArgs.length; //=> 3 | |
* takesThreeArgs(1, 2, 3); //=> [1, 2, 3] | |
* | |
* var takesTwoArgs = R.binary(takesThreeArgs); | |
* takesTwoArgs.length; //=> 2 | |
* // Only 2 arguments are passed to the wrapped function | |
* takesTwoArgs(1, 2, 3); //=> [1, 2, undefined] | |
*/ | |
var binary = _curry1(function binary(fn) { | |
return nAry(2, fn); | |
}); | |
/** | |
* 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. | |
* | |
* @func | |
* @memberOf R | |
* @category Object | |
* @sig {*} -> {*} | |
* @param {*} value The object or array to clone | |
* @return {*} A new object or array. | |
* @example | |
* | |
* var objects = [{}, {}, {}]; | |
* var objectsClone = R.clone(objects); | |
* objects[0] === objectsClone[0]; //=> false | |
*/ | |
var clone = _curry1(function clone(value) { | |
return _baseCopy(value, [], []); | |
}); | |
/** | |
* Creates a new function that runs each of the functions supplied as parameters in turn, | |
* passing the return value of each function invocation to the next function invocation, | |
* beginning with whatever arguments were passed to the initial invocation. | |
* | |
* Note that `compose` is a right-associative function, which means the functions provided | |
* will be invoked in order from right to left. In the example `var h = compose(f, g)`, | |
* the function `h` is equivalent to `f( g(x) )`, where `x` represents the arguments | |
* originally passed to `h`. | |
* | |
* @func | |
* @memberOf R | |
* @category Function | |
* @sig ((y -> z), (x -> y), ..., (b -> c), (a... -> b)) -> (a... -> z) | |
* @param {...Function} functions A variable number of functions. | |
* @return {Function} A new function which represents the result of calling each of the | |
* input `functions`, passing the result of each function call to the next, from | |
* right to left. | |
* @example | |
* | |
* var triple = function(x) { return x * 3; }; | |
* var double = function(x) { return x * 2; }; | |
* var square = function(x) { return x * x; }; | |
* var squareThenDoubleThenTriple = R.compose(triple, double, square); | |
* | |
* //≅ triple(double(square(5))) | |
* squareThenDoubleThenTriple(5); //=> 150 | |
*/ | |
var compose = _createComposer(_compose); | |
/** | |
* Creates a new lens that allows getting and setting values of nested properties, by | |
* following each given lens in succession. | |
* | |
* Note that `composeL` is a right-associative function, which means the lenses provided | |
* will be invoked in order from right to left. | |
* | |
* @func | |
* @memberOf R | |
* @category Function | |
* @see R.lens | |
* @sig ((y -> z), (x -> y), ..., (b -> c), (a -> b)) -> (a -> z) | |
* @param {...Function} lenses A variable number of lenses. | |
* @return {Function} A new lens which represents the result of calling each of the | |
* input `lenses`, passing the result of each getter/setter as the source | |
* to the next, from right to left. | |
* @example | |
* | |
* var headLens = R.lensIndex(0); | |
* var secondLens = R.lensIndex(1); | |
* var xLens = R.lensProp('x'); | |
* var secondOfXOfHeadLens = R.composeL(secondLens, xLens, headLens); | |
* | |
* var source = [{x: [0, 1], y: [2, 3]}, {x: [4, 5], y: [6, 7]}]; | |
* secondOfXOfHeadLens(source); //=> 1 | |
* secondOfXOfHeadLens.set(123, source); //=> [{x: [0, 123], y: [2, 3]}, {x: [4, 5], y: [6, 7]}] | |
*/ | |
var composeL = function () { | |
var fn = arguments[arguments.length - 1]; | |
var idx = arguments.length - 2; | |
while (idx >= 0) { | |
fn = _composeL(arguments[idx], fn); | |
idx -= 1; | |
} | |
return fn; | |
}; | |
/** | |
* Similar to `compose` but with automatic handling of promises (or, more | |
* precisely, "thenables"). The behavior is identical to that of | |
* compose() if all composed functions return something other than | |
* promises (i.e., objects with a .then() method). If one of the function | |
* returns a promise, however, then the next function in the composition | |
* is called asynchronously, in the success callback of the promise, using | |
* the resolved value as an input. Note that `composeP` is a right- | |
* associative function, just like `compose`. | |
* | |
* @func | |
* @memberOf R | |
* @category Function | |
* @sig ((y -> z), (x -> y), ..., (b -> c), (a... -> b)) -> (a... -> z) | |
* @param {...Function} functions A variable number of functions. | |
* @return {Function} A new function which represents the result of calling each of the | |
* input `functions`, passing either the returned result or the asynchronously | |
* resolved value) of each function call to the next, from right to left. | |
* @example | |
* | |
* var Q = require('q'); | |
* var triple = function(x) { return x * 3; }; | |
* var double = function(x) { return x * 2; }; | |
* var squareAsync = function(x) { return Q.when(x * x); }; | |
* var squareAsyncThenDoubleThenTriple = R.composeP(triple, double, squareAsync); | |
* | |
* //≅ squareAsync(5).then(function(x) { return triple(double(x)) }; | |
* squareAsyncThenDoubleThenTriple(5) | |
* .then(function(result) { | |
* // result is 150 | |
* }); | |
*/ | |
var composeP = _createComposer(_composeP); | |
/** | |
* Returns a new list consisting of the elements of the first list followed by the elements | |
* of the second. | |
* | |
* @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`. | |
* | |
* @example | |
* | |
* R.concat([], []); //=> [] | |
* R.concat([4, 5, 6], [1, 2, 3]); //=> [4, 5, 6, 1, 2, 3] | |
* R.concat('ABC', 'DEF'); // 'ABCDEF' | |
*/ | |
var concat = _curry2(function (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); | |
} | |
}); | |
/** | |
* Returns a curried equivalent of the provided function, with the | |
* specified arity. The curried function has two unusual capabilities. | |
* First, its arguments needn't be provided one at a time. If `g` is | |
* `R.curryN(3, f)`, the following are equivalent: | |
* | |
* - `g(1)(2)(3)` | |
* - `g(1)(2, 3)` | |
* - `g(1, 2)(3)` | |
* - `g(1, 2, 3)` | |
* | |
* Secondly, the special placeholder value `R.__` may be used to specify | |
* "gaps", allowing partial application of any combination of arguments, | |
* regardless of their positions. If `g` is as above and `_` is `R.__`, | |
* the following are equivalent: | |
* | |
* - `g(1, 2, 3)` | |
* - `g(_, 2, 3)(1)` | |
* - `g(_, _, 3)(1)(2)` | |
* - `g(_, _, 3)(1, 2)` | |
* - `g(_, 2)(1)(3)` | |
* - `g(_, 2)(1, 3)` | |
* - `g(_, 2)(_, 3)(1)` | |
* | |
* @func | |
* @memberOf R | |
* @category Function | |
* @sig Number -> (* -> a) -> (* -> a) | |
* @param {Number} length The arity for the returned function. | |
* @param {Function} fn The function to curry. | |
* @return {Function} A new, curried function. | |
* @see R.curry | |
* @example | |
* | |
* var addFourNumbers = function() { | |
* return R.sum([].slice.call(arguments, 0, 4)); | |
* }; | |
* | |
* var curriedAddFourNumbers = R.curryN(4, addFourNumbers); | |
* var f = curriedAddFourNumbers(1, 2); | |
* var g = f(3); | |
* g(4); //=> 10 | |
*/ | |
var curryN = _curry2(function curryN(length, fn) { | |
return arity(length, _curryN(length, [], fn)); | |
}); | |
/** | |
* Makes a shallow clone of an object, omitting the property at the | |
* given path. Note that this copies and flattens prototype properties | |
* onto the new object as well. All non-primitive properties are copied | |
* by reference. | |
* | |
* @func | |
* @memberOf R | |
* @category Object | |
* @sig [String] -> {k: v} -> {k: v} | |
* @param {Array} path the path to set | |
* @param {Object} obj the object to clone | |
* @return {Object} a new object without the property at path | |
* @example | |
* | |
* R.dissocPath(['a', 'b', 'c'], {a: {b: {c: 42}}}); //=> {a: {b: {}}} | |
*/ | |
var dissocPath = _curry2(_dissocPath); | |
/** | |
* Returns a new list containing the last `n` elements of a given list, passing each value | |
* to the supplied predicate function, skipping elements while the predicate function returns | |
* `true`. The predicate function is passed one argument: *(value)*. | |
* | |
* Acts as a transducer if a transformer is given in list position. | |
* @see R.transduce | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig (a -> Boolean) -> [a] -> [a] | |
* @param {Function} fn The function called per iteration. | |
* @param {Array} list The collection to iterate over. | |
* @return {Array} A new array. | |
* @example | |
* | |
* var lteTwo = function(x) { | |
* return x <= 2; | |
* }; | |
* | |
* R.dropWhile(lteTwo, [1, 2, 3, 4, 3, 2, 1]); //=> [3, 4, 3, 2, 1] | |
*/ | |
var dropWhile = _curry2(_dispatchable('dropWhile', _xdropWhile, function dropWhile(pred, list) { | |
var idx = 0, len = list.length; | |
while (idx < len && pred(list[idx])) { | |
idx += 1; | |
} | |
return _slice(list, idx); | |
})); | |
/** | |
* `empty` returns an empty list for any argument, except when the argument satisfies the | |
* Fantasy-land Monoid spec. In that case, this function will return the result of invoking | |
* `empty` on that Monoid. | |
* | |
* @func | |
* @memberOf R | |
* @category Function | |
* @sig * -> [] | |
* @return {Array} An empty array. | |
* @example | |
* | |
* R.empty([1,2,3,4,5]); //=> [] | |
*/ | |
var empty = _curry1(function empty(x) { | |
return _hasMethod('empty', x) ? x.empty() : []; | |
}); | |
/** | |
* Returns `true` if its arguments are equivalent, `false` otherwise. | |
* Dispatches to an `equals` method if present. Handles cyclical data | |
* structures. | |
* | |
* @func | |
* @memberOf R | |
* @category Relation | |
* @sig a -> b -> Boolean | |
* @param {*} a | |
* @param {*} b | |
* @return {Boolean} | |
* @example | |
* | |
* R.equals(1, 1); //=> true | |
* R.equals(1, '1'); //=> false | |
* R.equals([1, 2, 3], [1, 2, 3]); //=> true | |
* | |
* var a = {}; a.v = a; | |
* var b = {}; b.v = b; | |
* 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, [], []); | |
}); | |
/** | |
* Returns a new list containing only those items that match a given predicate function. | |
* The predicate function is passed one argument: *(value)*. | |
* | |
* Note that `R.filter` does not skip deleted or unassigned indices, unlike the native | |
* `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 | |
* | |
* Acts as a transducer if a transformer is given in list position. | |
* @see R.transduce | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig (a -> Boolean) -> [a] -> [a] | |
* @param {Function} fn The function called per iteration. | |
* @param {Array} list The collection to iterate over. | |
* @return {Array} The new filtered array. | |
* @example | |
* | |
* var isEven = function(n) { | |
* return n % 2 === 0; | |
* }; | |
* R.filter(isEven, [1, 2, 3, 4]); //=> [2, 4] | |
*/ | |
var filter = _curry2(_dispatchable('filter', _xfilter, _filter)); | |
/** | |
* Returns the first element of the list which matches the predicate, or `undefined` if no | |
* element matches. | |
* | |
* Acts as a transducer if a transformer is given in list position. | |
* @see R.transduce | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig (a -> Boolean) -> [a] -> a | undefined | |
* @param {Function} fn The predicate function used to determine if the element is the | |
* desired one. | |
* @param {Array} list The array to consider. | |
* @return {Object} The element found, or `undefined`. | |
* @example | |
* | |
* var xs = [{a: 1}, {a: 2}, {a: 3}]; | |
* R.find(R.propEq('a', 2))(xs); //=> {a: 2} | |
* R.find(R.propEq('a', 4))(xs); //=> undefined | |
*/ | |
var find = _curry2(_dispatchable('find', _xfind, function find(fn, list) { | |
var idx = 0; | |
var len = list.length; | |
while (idx < len) { | |
if (fn(list[idx])) { | |
return list[idx]; | |
} | |
idx += 1; | |
} | |
})); | |
/** | |
* Returns the index of the first element of the list which matches the predicate, or `-1` | |
* if no element matches. | |
* | |
* Acts as a transducer if a transformer is given in list position. | |
* @see R.transduce | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig (a -> Boolean) -> [a] -> Number | |
* @param {Function} fn The predicate function used to determine if the element is the | |
* desired one. | |
* @param {Array} list The array to consider. | |
* @return {Number} The index of the element found, or `-1`. | |
* @example | |
* | |
* var xs = [{a: 1}, {a: 2}, {a: 3}]; | |
* R.findIndex(R.propEq('a', 2))(xs); //=> 1 | |
* R.findIndex(R.propEq('a', 4))(xs); //=> -1 | |
*/ | |
var findIndex = _curry2(_dispatchable('findIndex', _xfindIndex, function findIndex(fn, list) { | |
var idx = 0; | |
var len = list.length; | |
while (idx < len) { | |
if (fn(list[idx])) { | |
return idx; | |
} | |
idx += 1; | |
} | |
return -1; | |
})); | |
/** | |
* Returns the last element of the list which matches the predicate, or `undefined` if no | |
* element matches. | |
* | |
* Acts as a transducer if a transformer is given in list position. | |
* @see R.transduce | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig (a -> Boolean) -> [a] -> a | undefined | |
* @param {Function} fn The predicate function used to determine if the element is the | |
* desired one. | |
* @param {Array} list The array to consider. | |
* @return {Object} The element found, or `undefined`. | |
* @example | |
* | |
* var xs = [{a: 1, b: 0}, {a:1, b: 1}]; | |
* R.findLast(R.propEq('a', 1))(xs); //=> {a: 1, b: 1} | |
* R.findLast(R.propEq('a', 4))(xs); //=> undefined | |
*/ | |
var findLast = _curry2(_dispatchable('findLast', _xfindLast, function findLast(fn, list) { | |
var idx = list.length - 1; | |
while (idx >= 0) { | |
if (fn(list[idx])) { | |
return list[idx]; | |
} | |
idx -= 1; | |
} | |
})); | |
/** | |
* Returns the index of the last element of the list which matches the predicate, or | |
* `-1` if no element matches. | |
* | |
* Acts as a transducer if a transformer is given in list position. | |
* @see R.transduce | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig (a -> Boolean) -> [a] -> Number | |
* @param {Function} fn The predicate function used to determine if the element is the | |
* desired one. | |
* @param {Array} list The array to consider. | |
* @return {Number} The index of the element found, or `-1`. | |
* @example | |
* | |
* var xs = [{a: 1, b: 0}, {a:1, b: 1}]; | |
* R.findLastIndex(R.propEq('a', 1))(xs); //=> 1 | |
* R.findLastIndex(R.propEq('a', 4))(xs); //=> -1 | |
*/ | |
var findLastIndex = _curry2(_dispatchable('findLastIndex', _xfindLastIndex, function findLastIndex(fn, list) { | |
var idx = list.length - 1; | |
while (idx >= 0) { | |
if (fn(list[idx])) { | |
return idx; | |
} | |
idx -= 1; | |
} | |
return -1; | |
})); | |
/** | |
* Returns a new list by pulling every item out of it (and all its sub-arrays) and putting | |
* them in a new array, depth-first. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig [a] -> [b] | |
* @param {Array} list The array to consider. | |
* @return {Array} The flattened list. | |
* @example | |
* | |
* R.flatten([1, 2, [3, 4], 5, [6, [7, 8, [9, [10, 11], 12]]]]); | |
* //=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] | |
*/ | |
var flatten = _curry1(_makeFlat(true)); | |
/** | |
* Iterate over an input `list`, calling a provided function `fn` for each element in the | |
* list. | |
* | |
* `fn` receives one argument: *(value)*. | |
* | |
* Note: `R.forEach` does not skip deleted or unassigned indices (sparse arrays), unlike | |
* the native `Array.prototype.forEach` method. For more details on this behavior, see: | |
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach#Description | |
* | |
* Also note that, unlike `Array.prototype.forEach`, Ramda's `forEach` returns the original | |
* array. In some libraries this function is named `each`. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig (a -> *) -> [a] -> [a] | |
* @param {Function} fn The function to invoke. Receives one argument, `value`. | |
* @param {Array} list The list to iterate over. | |
* @return {Array} The original list. | |
* @example | |
* | |
* var printXPlusFive = function(x) { console.log(x + 5); }; | |
* R.forEach(printXPlusFive, [1, 2, 3]); //=> [1, 2, 3] | |
* //-> 6 | |
* //-> 7 | |
* //-> 8 | |
*/ | |
var forEach = _curry2(function forEach(fn, list) { | |
return _hasMethod('forEach', list) ? list.forEach(fn) : _forEach(fn, list); | |
}); | |
/** | |
* Returns a list of function names of object's own functions | |
* | |
* @func | |
* @memberOf R | |
* @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. | |
* @example | |
* | |
* R.functions(R); // returns list of ramda's own function names | |
* | |
* var F = function() { this.x = function(){}; this.y = 1; } | |
* F.prototype.z = function() {}; | |
* F.prototype.a = 100; | |
* R.functions(new F()); //=> ["x"] | |
*/ | |
var functions = _curry1(_functionsWith(keys)); | |
/** | |
* Returns a list of function names of object's own and prototype functions | |
* | |
* @func | |
* @memberOf R | |
* @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. | |
* @example | |
* | |
* R.functionsIn(R); // returns list of ramda's own and prototype function names | |
* | |
* var F = function() { this.x = function(){}; this.y = 1; } | |
* F.prototype.z = function() {}; | |
* F.prototype.a = 100; | |
* R.functionsIn(new F()); //=> ["x", "z"] | |
*/ | |
var functionsIn = _curry1(_functionsWith(keysIn)); | |
/** | |
* 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. | |
* | |
* Acts as a transducer if a transformer is given in list position. | |
* @see R.transduce | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig (a -> String) -> [a] -> {String: [a]} | |
* @param {Function} fn Function :: a -> String | |
* @param {Array} list The array to group | |
* @return {Object} An object with the output of `fn` for keys, mapped to arrays of elements | |
* that produced that key when passed to `fn`. | |
* @example | |
* | |
* var byGrade = R.groupBy(function(student) { | |
* var score = student.score; | |
* return score < 65 ? 'F' : | |
* score < 70 ? 'D' : | |
* score < 80 ? 'C' : | |
* score < 90 ? 'B' : 'A'; | |
* }); | |
* var students = [{name: 'Abby', score: 84}, | |
* {name: 'Eddy', score: 58}, | |
* // ... | |
* {name: 'Jack', score: 69}]; | |
* byGrade(students); | |
* // { | |
* // 'A': [{name: 'Dianne', score: 99}], | |
* // 'B': [{name: 'Abby', score: 84}] | |
* // // ..., | |
* // 'F': [{name: 'Eddy', score: 58}] | |
* // } | |
*/ | |
var groupBy = _curry2(_dispatchable('groupBy', _xgroupBy, function groupBy(fn, list) { | |
return _reduce(function (acc, elt) { | |
var key = fn(elt); | |
acc[key] = _append(elt, acc[key] || (acc[key] = [])); | |
return acc; | |
}, {}, list); | |
})); | |
/** | |
* Returns the first element in a list. | |
* In some libraries this function is named `first`. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig [a] -> a | |
* @param {Array} list The array to consider. | |
* @return {*} The first element of the list, or `undefined` if the list is empty. | |
* @example | |
* | |
* R.head(['fi', 'fo', 'fum']); //=> 'fi' | |
*/ | |
var head = nth(0); | |
/** | |
* Creates a function that will process either the `onTrue` or the `onFalse` function depending | |
* upon the result of the `condition` predicate. | |
* | |
* @func | |
* @memberOf R | |
* @category Logic | |
* @sig (*... -> Boolean) -> (*... -> *) -> (*... -> *) -> (*... -> *) | |
* @param {Function} condition A predicate function | |
* @param {Function} onTrue A function to invoke when the `condition` evaluates to a truthy value. | |
* @param {Function} onFalse A function to invoke when the `condition` evaluates to a falsy value. | |
* @return {Function} A new unary function that will process either the `onTrue` or the `onFalse` | |
* 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 ifElse = _curry3(function ifElse(condition, onTrue, onFalse) { | |
return curryN(Math.max(condition.length, onTrue.length, onFalse.length), function _ifElse() { | |
return condition.apply(this, arguments) ? onTrue.apply(this, arguments) : onFalse.apply(this, arguments); | |
}); | |
}); | |
/** | |
* Inserts the supplied element into the list, at index `index`. _Note | |
* that this is not destructive_: it returns a copy of the list with the changes. | |
* <small>No lists have been harmed in the application of this function.</small> | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig Number -> a -> [a] -> [a] | |
* @param {Number} index The position to insert the element | |
* @param {*} elt The element to insert into the Array | |
* @param {Array} list The list to insert into | |
* @return {Array} A new Array with `elt` inserted at `index`. | |
* @example | |
* | |
* R.insert(2, 'x', [1,2,3,4]); //=> [1,2,'x',3,4] | |
*/ | |
var insert = _curry3(function insert(idx, elt, list) { | |
idx = idx < list.length && idx >= 0 ? idx : list.length; | |
return _concat(_append(elt, _slice(list, 0, idx)), _slice(list, idx)); | |
}); | |
/** | |
* Combines two lists into a set (i.e. no duplicates) composed of those | |
* elements common to both lists. Duplication is determined according | |
* to the value returned by applying the supplied predicate to two list | |
* elements. | |
* | |
* @func | |
* @memberOf R | |
* @category Relation | |
* @sig (a,a -> Boolean) -> [a] -> [a] -> [a] | |
* @param {Function} pred A predicate function that determines whether | |
* the two supplied elements are equal. | |
* @param {Array} list1 One list of items to compare | |
* @param {Array} list2 A second list of items to compare | |
* @see R.intersection | |
* @return {Array} A new list containing those elements common to both lists. | |
* @example | |
* | |
* var buffaloSpringfield = [ | |
* {id: 824, name: 'Richie Furay'}, | |
* {id: 956, name: 'Dewey Martin'}, | |
* {id: 313, name: 'Bruce Palmer'}, | |
* {id: 456, name: 'Stephen Stills'}, | |
* {id: 177, name: 'Neil Young'} | |
* ]; | |
* var csny = [ | |
* {id: 204, name: 'David Crosby'}, | |
* {id: 456, name: 'Stephen Stills'}, | |
* {id: 539, name: 'Graham Nash'}, | |
* {id: 177, name: 'Neil Young'} | |
* ]; | |
* | |
* var sameId = function(o1, o2) {return o1.id === o2.id;}; | |
* | |
* R.intersectionWith(sameId, buffaloSpringfield, csny); | |
* //=> [{id: 456, name: 'Stephen Stills'}, {id: 177, name: 'Neil Young'}] | |
*/ | |
var intersectionWith = _curry3(function intersectionWith(pred, list1, list2) { | |
var results = [], idx = 0; | |
while (idx < list1.length) { | |
if (_containsWith(pred, list1[idx], list2)) { | |
results[results.length] = list1[idx]; | |
} | |
idx += 1; | |
} | |
return uniqWith(pred, results); | |
}); | |
/** | |
* Creates a new list with the separator interposed between elements. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig a -> [a] -> [a] | |
* @param {*} separator The element to add to the list. | |
* @param {Array} list The list to be interposed. | |
* @return {Array} The new list. | |
* @example | |
* | |
* R.intersperse('n', ['ba', 'a', 'a']); //=> ['ba', 'n', 'a', 'n', 'a'] | |
*/ | |
var intersperse = _curry2(_checkForMethod('intersperse', function intersperse(separator, list) { | |
var out = []; | |
var idx = 0; | |
var length = list.length; | |
while (idx < length) { | |
if (idx === length - 1) { | |
out.push(list[idx]); | |
} else { | |
out.push(list[idx], separator); | |
} | |
idx += 1; | |
} | |
return out; | |
})); | |
/** | |
* Same as R.invertObj, however this accounts for objects | |
* with duplicate values by putting the values into an | |
* array. | |
* | |
* @func | |
* @memberOf R | |
* @category Object | |
* @sig {s: x} -> {x: [ s, ... ]} | |
* @param {Object} obj The object or array to invert | |
* @return {Object} out A new object with keys | |
* in an array. | |
* @example | |
* | |
* var raceResultsByFirstName = { | |
* first: 'alice', | |
* second: 'jake', | |
* third: 'alice', | |
* }; | |
* R.invert(raceResultsByFirstName); | |
* //=> { 'alice': ['first', 'third'], 'jake':['second'] } | |
*/ | |
var invert = _curry1(function invert(obj) { | |
var props = keys(obj); | |
var len = props.length; | |
var idx = 0; | |
var out = {}; | |
while (idx < len) { | |
var key = props[idx]; | |
var val = obj[key]; | |
var list = _has(val, out) ? out[val] : out[val] = []; | |
list[list.length] = key; | |
idx += 1; | |
} | |
return out; | |
}); | |
/** | |
* Returns a new object with the keys of the given object | |
* as values, and the values of the given object as keys. | |
* | |
* @func | |
* @memberOf R | |
* @category Object | |
* @sig {s: x} -> {x: s} | |
* @param {Object} obj The object or array to invert | |
* @return {Object} out A new object | |
* @example | |
* | |
* var raceResults = { | |
* first: 'alice', | |
* second: 'jake' | |
* }; | |
* R.invertObj(raceResults); | |
* //=> { 'alice': 'first', 'jake':'second' } | |
* | |
* // Alternatively: | |
* var raceResults = ['alice', 'jake']; | |
* R.invertObj(raceResults); | |
* //=> { 'alice': '0', 'jake':'1' } | |
*/ | |
var invertObj = _curry1(function invertObj(obj) { | |
var props = keys(obj); | |
var len = props.length; | |
var idx = 0; | |
var out = {}; | |
while (idx < len) { | |
var key = props[idx]; | |
out[obj[key]] = key; | |
idx += 1; | |
} | |
return out; | |
}); | |
/** | |
* Turns a named method with a specified arity into a function | |
* that can be called directly supplied with arguments and a target object. | |
* | |
* The returned function is curried and accepts `arity + 1` parameters where | |
* the final parameter is the target object. | |
* | |
* @func | |
* @memberOf R | |
* @category Function | |
* @sig Number -> String -> (a -> b -> ... -> n -> Object -> *) | |
* @param {Number} arity Number of arguments the returned function should take | |
* before the target object. | |
* @param {Function} method Name of the method to call. | |
* @return {Function} A new curried function. | |
* @example | |
* | |
* var sliceFrom = R.invoker(1, 'slice'); | |
* sliceFrom(6, 'abcdefghijklm'); //=> 'ghijklm' | |
* var sliceFrom6 = R.invoker(2, 'slice')(6); | |
* sliceFrom6(8, 'abcdefghijklm'); //=> 'gh' | |
*/ | |
var invoker = _curry2(function invoker(arity, method) { | |
return curryN(arity + 1, function () { | |
var target = arguments[arity]; | |
return target[method].apply(target, _slice(arguments, 0, arity)); | |
}); | |
}); | |
/** | |
* Returns a string made by inserting the `separator` between each | |
* element and concatenating all the elements into a single string. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig String -> [a] -> String | |
* @param {Number|String} separator The string used to separate the elements. | |
* @param {Array} xs The elements to join into a string. | |
* @return {String} str The string made by concatenating `xs` with `separator`. | |
* @example | |
* | |
* var spacer = R.join(' '); | |
* spacer(['a', 2, 3.4]); //=> 'a 2 3.4' | |
* R.join('|', [1, 2, 3]); //=> '1|2|3' | |
*/ | |
var join = invoker(1, 'join'); | |
/** | |
* Returns the last element from a list. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig [a] -> a | |
* @param {Array} list The array to consider. | |
* @return {*} The last element of the list, or `undefined` if the list is empty. | |
* @example | |
* | |
* R.last(['fi', 'fo', 'fum']); //=> 'fum' | |
*/ | |
var last = nth(-1); | |
/** | |
* Creates a lens that will focus on index `n` of the source array. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @see R.lens | |
* @sig Number -> (a -> b) | |
* @param {Number} n The index of the array that the returned lens will focus on. | |
* @return {Function} the returned function has `set` and `map` properties that are | |
* also curried functions. | |
* @example | |
* | |
* var headLens = R.lensIndex(0); | |
* headLens([10, 20, 30, 40]); //=> 10 | |
* headLens.set('mu', [10, 20, 30, 40]); //=> ['mu', 20, 30, 40] | |
* headLens.map(function(x) { return x + 1; }, [10, 20, 30, 40]); //=> [11, 20, 30, 40] | |
*/ | |
var lensIndex = _curry1(function lensIndex(n) { | |
return lens(nth(n), update(n)); | |
}); | |
/** | |
* Creates a lens that will focus on property `k` of the source object. | |
* | |
* @func | |
* @memberOf R | |
* @category Object | |
* @see R.lens | |
* @sig String -> (a -> b) | |
* @param {String} k A string that represents a property to focus on. | |
* @return {Function} the returned function has `set` and `map` properties that are | |
* also curried functions. | |
* @example | |
* | |
* var phraseLens = R.lensProp('phrase'); | |
* var obj1 = { phrase: 'Absolute filth . . . and I LOVED it!'}; | |
* var obj2 = { phrase: "What's all this, then?"}; | |
* phraseLens(obj1); // => 'Absolute filth . . . and I LOVED it!' | |
* phraseLens(obj2); // => "What's all this, then?" | |
* phraseLens.set('Ooh Betty', obj1); //=> { phrase: 'Ooh Betty'} | |
* phraseLens.map(R.toUpper, obj2); //=> { phrase: "WHAT'S ALL THIS, THEN?"} | |
*/ | |
var lensProp = _curry1(function lensProp(k) { | |
return lens(prop(k), assoc(k)); | |
}); | |
/** | |
* Returns a new list, constructed by applying the supplied function to every element of the | |
* supplied list. | |
* | |
* Note: `R.map` does not skip deleted or unassigned indices (sparse arrays), unlike the | |
* 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 | |
* | |
* Acts as a transducer if a transformer is given in list position. | |
* @see R.transduce | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig (a -> b) -> [a] -> [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; | |
* }; | |
* | |
* R.map(double, [1, 2, 3]); //=> [2, 4, 6] | |
*/ | |
var map = _curry2(_dispatchable('map', _xmap, _map)); | |
/** | |
* Map, but for objects. Creates an object with the same keys as `obj` and values | |
* generated by running each property of `obj` through `fn`. `fn` is passed one argument: | |
* *(value)*. | |
* | |
* @func | |
* @memberOf R | |
* @category Object | |
* @sig (v -> v) -> {k: v} -> {k: v} | |
* @param {Function} fn A function called for each property in `obj`. Its return value will | |
* become a new property on the return object. | |
* @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`. | |
* @example | |
* | |
* var values = { x: 1, y: 2, z: 3 }; | |
* var double = function(num) { | |
* return num * 2; | |
* }; | |
* | |
* R.mapObj(double, values); //=> { x: 2, y: 4, z: 6 } | |
*/ | |
var mapObj = _curry2(function mapObject(fn, obj) { | |
return _reduce(function (acc, key) { | |
acc[key] = fn(obj[key]); | |
return acc; | |
}, {}, keys(obj)); | |
}); | |
/** | |
* Like `mapObj`, but but passes additional arguments to the predicate function. The | |
* predicate function is passed three arguments: *(value, key, obj)*. | |
* | |
* @func | |
* @memberOf R | |
* @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 | |
* become a new property on the return object. | |
* @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`. | |
* @example | |
* | |
* var values = { x: 1, y: 2, z: 3 }; | |
* var prependKeyAndDouble = function(num, key, obj) { | |
* return key + (num * 2); | |
* }; | |
* | |
* R.mapObjIndexed(prependKeyAndDouble, values); //=> { x: 'x2', y: 'y4', z: 'z6' } | |
*/ | |
var mapObjIndexed = _curry2(function mapObjectIndexed(fn, obj) { | |
return _reduce(function (acc, key) { | |
acc[key] = fn(obj[key], key, obj); | |
return acc; | |
}, {}, keys(obj)); | |
}); | |
/** | |
* Tests a regular expression against a String | |
* | |
* @func | |
* @memberOf R | |
* @category String | |
* @sig RegExp -> String -> [String] | null | |
* @param {RegExp} rx A regular expression. | |
* @param {String} str The string to match against | |
* @return {Array} The list of matches, or null if no matches found. | |
* @see R.invoker | |
* @example | |
* | |
* R.match(/([a-z]a)/g, 'bananas'); //=> ['ba', 'na', 'na'] | |
*/ | |
var match = invoker(1, 'match'); | |
/** | |
* Determines the largest of a list of numbers (or elements that can be cast to numbers) | |
* | |
* @func | |
* @memberOf R | |
* @category Math | |
* @sig [Number] -> Number | |
* @see R.maxBy | |
* @param {Array} list A list of numbers | |
* @return {Number} The greatest number in the list. | |
* @example | |
* | |
* R.max([7, 3, 9, 2, 4, 9, 3]); //=> 9 | |
*/ | |
var max = _createMaxMin(_gt, -Infinity); | |
/** | |
* Create a new object with the own properties of `a` | |
* merged with the own properties of object `b`. | |
* This function will *not* mutate passed-in objects. | |
* | |
* @func | |
* @memberOf R | |
* @category Object | |
* @sig {k: v} -> {k: v} -> {k: v} | |
* @param {Object} a source object | |
* @param {Object} b object with higher precedence in output | |
* @return {Object} The destination object. | |
* @example | |
* | |
* R.merge({ 'name': 'fred', 'age': 10 }, { 'age': 40 }); | |
* //=> { 'name': 'fred', 'age': 40 } | |
* | |
* var resetToDefault = R.merge(R.__, {x: 0}); | |
* resetToDefault({x: 5, y: 2}); //=> {x: 0, y: 2} | |
*/ | |
var merge = _curry2(function merge(a, b) { | |
return _extend(_extend({}, a), b); | |
}); | |
/** | |
* Determines the smallest of a list of numbers (or elements that can be cast to numbers) | |
* | |
* @func | |
* @memberOf R | |
* @category Math | |
* @sig [Number] -> Number | |
* @param {Array} list A list of numbers | |
* @return {Number} The greatest number in the list. | |
* @see R.minBy | |
* @example | |
* | |
* R.min([7, 3, 9, 2, 4, 9, 3]); //=> 2 | |
*/ | |
var min = _createMaxMin(_lt, Infinity); | |
/** | |
* Returns `true` if no elements of the list match the predicate, | |
* `false` otherwise. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig (a -> Boolean) -> [a] -> Boolean | |
* @param {Function} fn The predicate function. | |
* @param {Array} list The array to consider. | |
* @return {Boolean} `true` if the predicate is not satisfied by every element, `false` otherwise. | |
* @example | |
* | |
* R.none(R.isNaN, [1, 2, 3]); //=> true | |
* R.none(R.isNaN, [1, 2, 3, NaN]); //=> false | |
*/ | |
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. | |
* @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; | |
}); | |
/** | |
* Takes a predicate and a list and returns the pair of lists of | |
* elements which do and do not satisfy the predicate, respectively. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig (a -> Boolean) -> [a] -> [[a],[a]] | |
* @param {Function} pred A predicate to determine which array the element belongs to. | |
* @param {Array} list The array to partition. | |
* @return {Array} A nested array, containing first an array of elements that satisfied the predicate, | |
* and second an array of elements that did not satisfy. | |
* @example | |
* | |
* R.partition(R.contains('s'), ['sss', 'ttt', 'foo', 'bars']); | |
* //=> [ [ 'sss', 'bars' ], [ 'ttt', 'foo' ] ] | |
*/ | |
var partition = _curry2(function partition(pred, list) { | |
return _reduce(function (acc, elt) { | |
var xs = acc[pred(elt) ? 0 : 1]; | |
xs[xs.length] = elt; | |
return acc; | |
}, [ | |
[], | |
[] | |
], list); | |
}); | |
/** | |
* Determines whether a nested path on an object has a specific value, | |
* in `R.equals` terms. Most likely used to filter a list. | |
* | |
* @func | |
* @memberOf R | |
* @category Relation | |
* @sig [String] -> * -> {String: *} -> Boolean | |
* @param {Array} path The path of the nested property to use | |
* @param {*} val The value to compare the nested property with | |
* @param {Object} obj The object to check the nested property in | |
* @return {Boolean} `true` if the value equals the nested object property, | |
* `false` otherwise. | |
* @example | |
* | |
* var user1 = { address: { zipCode: 90210 } }; | |
* var user2 = { address: { zipCode: 55555 } }; | |
* var user3 = { name: 'Bob' }; | |
* var users = [ user1, user2, user3 ]; | |
* var isFamous = R.pathEq(['address', 'zipCode'], 90210); | |
* R.filter(isFamous, users); //=> [ user1 ] | |
*/ | |
var pathEq = _curry3(function pathEq(path, val, obj) { | |
return equals(_path(path, obj), val); | |
}); | |
/** | |
* Creates a new function that runs each of the functions supplied as parameters in turn, | |
* passing the return value of each function invocation to the next function invocation, | |
* beginning with whatever arguments were passed to the initial invocation. | |
* | |
* `pipe` is the mirror version of `compose`. `pipe` is left-associative, which means that | |
* each of the functions provided is executed in order from left to right. | |
* | |
* In some libraries this function is named `sequence`. | |
* @func | |
* @memberOf R | |
* @category Function | |
* @sig ((a... -> b), (b -> c), ..., (x -> y), (y -> z)) -> (a... -> z) | |
* @param {...Function} functions A variable number of functions. | |
* @return {Function} A new function which represents the result of calling each of the | |
* input `functions`, passing the result of each function call to the next, from | |
* left to right. | |
* @example | |
* | |
* var triple = function(x) { return x * 3; }; | |
* var double = function(x) { return x * 2; }; | |
* var square = function(x) { return x * x; }; | |
* var squareThenDoubleThenTriple = R.pipe(square, double, triple); | |
* | |
* //≅ triple(double(square(5))) | |
* squareThenDoubleThenTriple(5); //=> 150 | |
*/ | |
var pipe = function pipe() { | |
return compose.apply(this, reverse(arguments)); | |
}; | |
/** | |
* Creates a new lens that allows getting and setting values of nested properties, by | |
* following each given lens in succession. | |
* | |
* `pipeL` is the mirror version of `composeL`. `pipeL` is left-associative, which means that | |
* each of the functions provided is executed in order from left to right. | |
* | |
* @func | |
* @memberOf R | |
* @category Function | |
* @see R.lens | |
* @sig ((a -> b), (b -> c), ..., (x -> y), (y -> z)) -> (a -> z) | |
* @param {...Function} lenses A variable number of lenses. | |
* @return {Function} A new lens which represents the result of calling each of the | |
* input `lenses`, passing the result of each getter/setter as the source | |
* to the next, from right to left. | |
* @example | |
* | |
* var headLens = R.lensIndex(0); | |
* var secondLens = R.lensIndex(1); | |
* var xLens = R.lensProp('x'); | |
* var headThenXThenSecondLens = R.pipeL(headLens, xLens, secondLens); | |
* | |
* var source = [{x: [0, 1], y: [2, 3]}, {x: [4, 5], y: [6, 7]}]; | |
* headThenXThenSecondLens(source); //=> 1 | |
* headThenXThenSecondLens.set(123, source); //=> [{x: [0, 123], y: [2, 3]}, {x: [4, 5], y: [6, 7]}] | |
*/ | |
var pipeL = compose(apply(composeL), unapply(reverse)); | |
/** | |
* Creates a new function that runs each of the functions supplied as parameters in turn, | |
* passing to the next function invocation either the value returned by the previous | |
* function or the resolved value if the returned value is a promise. In other words, | |
* if some of the functions in the sequence return promises, `pipeP` pipes the values | |
* asynchronously. If none of the functions return promises, the behavior is the same as | |
* that of `pipe`. | |
* | |
* `pipeP` is the mirror version of `composeP`. `pipeP` is left-associative, which means that | |
* each of the functions provided is executed in order from left to right. | |
* | |
* @func | |
* @memberOf R | |
* @category Function | |
* @sig ((a... -> b), (b -> c), ..., (x -> y), (y -> z)) -> (a... -> z) | |
* @param {...Function} functions A variable number of functions. | |
* @return {Function} A new function which represents the result of calling each of the | |
* input `functions`, passing either the returned result or the asynchronously | |
* resolved value) of each function call to the next, from left to right. | |
* @example | |
* | |
* var Q = require('q'); | |
* var triple = function(x) { return x * 3; }; | |
* var double = function(x) { return x * 2; }; | |
* var squareAsync = function(x) { return Q.when(x * x); }; | |
* var squareAsyncThenDoubleThenTriple = R.pipeP(squareAsync, double, triple); | |
* | |
* //≅ squareAsync(5).then(function(x) { return triple(double(x)) }; | |
* squareAsyncThenDoubleThenTriple(5) | |
* .then(function(result) { | |
* // result is 150 | |
* }); | |
*/ | |
var pipeP = function pipeP() { | |
return composeP.apply(this, reverse(arguments)); | |
}; | |
/** | |
* Determines whether the given property of an object has a specific value, | |
* in `R.equals` terms. Most likely used to filter a list. | |
* | |
* @func | |
* @memberOf R | |
* @category Relation | |
* @sig k -> v -> {k: v} -> Boolean | |
* @param {Number|String} name The property name (or index) to use. | |
* @param {*} val The value to compare the property with. | |
* @return {Boolean} `true` if the properties are equal, `false` otherwise. | |
* @example | |
* | |
* var abby = {name: 'Abby', age: 7, hair: 'blond'}; | |
* var fred = {name: 'Fred', age: 12, hair: 'brown'}; | |
* var rusty = {name: 'Rusty', age: 10, hair: 'brown'}; | |
* var alois = {name: 'Alois', age: 15, disposition: 'surly'}; | |
* var kids = [abby, fred, rusty, alois]; | |
* var hasBrownHair = R.propEq('hair', 'brown'); | |
* R.filter(hasBrownHair, kids); //=> [fred, rusty] | |
*/ | |
var propEq = _curry3(function propEq(name, val, obj) { | |
return equals(obj[name], val); | |
}); | |
/** | |
* Returns a single item by iterating through the list, successively calling the iterator | |
* function and passing it an accumulator value and the current value from the array, and | |
* then passing the result to the next call. | |
* | |
* The iterator function receives two values: *(acc, value)*. It may use `R.reduced` to | |
* shortcut the iteration. | |
* | |
* Note: `R.reduce` does not skip deleted or unassigned indices (sparse arrays), unlike | |
* the native `Array.prototype.reduce` method. For more details on this behavior, see: | |
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce#Description | |
* @see R.reduced | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig (a,b -> a) -> a -> [b] -> a | |
* @param {Function} fn The iterator function. Receives two values, the accumulator and the | |
* current element from the array. | |
* @param {*} acc The accumulator value. | |
* @param {Array} list The list to iterate over. | |
* @return {*} The final, accumulated value. | |
* @example | |
* | |
* var numbers = [1, 2, 3]; | |
* var add = function(a, b) { | |
* return a + b; | |
* }; | |
* | |
* R.reduce(add, 10, numbers); //=> 16 | |
*/ | |
var reduce = _curry3(_reduce); | |
/** | |
* Similar to `filter`, except that it keeps only values for which the given predicate | |
* function returns falsy. The predicate function is passed one argument: *(value)*. | |
* | |
* Acts as a transducer if a transformer is given in list position. | |
* @see R.transduce | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig (a -> Boolean) -> [a] -> [a] | |
* @param {Function} fn The function called per iteration. | |
* @param {Array} list The collection to iterate over. | |
* @return {Array} The new filtered array. | |
* @example | |
* | |
* var isOdd = function(n) { | |
* return n % 2 === 1; | |
* }; | |
* R.reject(isOdd, [1, 2, 3, 4]); //=> [2, 4] | |
*/ | |
var reject = _curry2(function reject(fn, list) { | |
return filter(_complement(fn), list); | |
}); | |
/** | |
* Returns a fixed list of size `n` containing a specified identical value. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig a -> n -> [a] | |
* @param {*} value The value to repeat. | |
* @param {Number} n The desired size of the output list. | |
* @return {Array} A new array containing `n` `value`s. | |
* @example | |
* | |
* R.repeat('hi', 5); //=> ['hi', 'hi', 'hi', 'hi', 'hi'] | |
* | |
* var obj = {}; | |
* var repeatedObjs = R.repeat(obj, 5); //=> [{}, {}, {}, {}, {}] | |
* repeatedObjs[0] === repeatedObjs[1]; //=> true | |
*/ | |
var repeat = _curry2(function repeat(value, n) { | |
return times(always(value), n); | |
}); | |
/** | |
* Returns a list containing the elements of `xs` from `fromIndex` (inclusive) | |
* to `toIndex` (exclusive). | |
* | |
* Dispatches to its third argument's `slice` method if present. As a | |
* result, one may replace `[a]` with `String` in the type signature. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig Number -> Number -> [a] -> [a] | |
* @param {Number} fromIndex The start index (inclusive). | |
* @param {Number} toIndex The end index (exclusive). | |
* @param {Array} xs The list to take elements from. | |
* @return {Array} The slice of `xs` from `fromIndex` to `toIndex`. | |
* @example | |
* | |
* R.slice(1, 3, ['a', 'b', 'c', 'd']); //=> ['b', 'c'] | |
* R.slice(1, Infinity, ['a', 'b', 'c', 'd']); //=> ['b', 'c', 'd'] | |
* R.slice(0, -1, ['a', 'b', 'c', 'd']); //=> ['a', 'b', 'c'] | |
* R.slice(-3, -1, ['a', 'b', 'c', 'd']); //=> ['b', 'c'] | |
* R.slice(0, 3, 'ramda'); //=> 'ram' | |
*/ | |
var slice = _curry3(_checkForMethod('slice', function slice(fromIndex, toIndex, xs) { | |
return Array.prototype.slice.call(xs, fromIndex, toIndex); | |
})); | |
/** | |
* Splits a string into an array of strings based on the given | |
* separator. | |
* | |
* @func | |
* @memberOf R | |
* @category String | |
* @sig String -> String -> [String] | |
* @param {String} sep The separator string. | |
* @param {String} str The string to separate into an array. | |
* @return {Array} The array of strings from `str` separated by `str`. | |
* @example | |
* | |
* var pathComponents = R.split('/'); | |
* R.tail(pathComponents('/usr/local/bin/node')); //=> ['usr', 'local', 'bin', 'node'] | |
* | |
* R.split('.', 'a.b.c.xyz.d'); //=> ['a', 'b', 'c', 'xyz', 'd'] | |
*/ | |
var split = invoker(1, 'split'); | |
/** | |
* Returns a string containing the characters of `str` from `fromIndex` | |
* (inclusive) to `toIndex` (exclusive). | |
* | |
* @func | |
* @memberOf R | |
* @category String | |
* @sig Number -> Number -> String -> String | |
* @param {Number} fromIndex The start index (inclusive). | |
* @param {Number} toIndex The end index (exclusive). | |
* @param {String} str The string to slice. | |
* @return {String} | |
* @see R.slice | |
* @deprecated since v0.15.0 | |
* @example | |
* | |
* R.substring(2, 5, 'abcdefghijklm'); //=> 'cde' | |
*/ | |
var substring = slice; | |
/** | |
* Returns a string containing the characters of `str` from `fromIndex` | |
* (inclusive) to the end of `str`. | |
* | |
* @func | |
* @memberOf R | |
* @category String | |
* @sig Number -> String -> String | |
* @param {Number} fromIndex | |
* @param {String} str | |
* @return {String} | |
* @deprecated since v0.15.0 | |
* @example | |
* | |
* R.substringFrom(3, 'Ramda'); //=> 'da' | |
* R.substringFrom(-2, 'Ramda'); //=> 'da' | |
*/ | |
var substringFrom = substring(__, Infinity); | |
/** | |
* Returns a string containing the first `toIndex` characters of `str`. | |
* | |
* @func | |
* @memberOf R | |
* @category String | |
* @sig Number -> String -> String | |
* @param {Number} toIndex | |
* @param {String} str | |
* @return {String} | |
* @deprecated since v0.15.0 | |
* @example | |
* | |
* R.substringTo(3, 'Ramda'); //=> 'Ram' | |
* R.substringTo(-2, 'Ramda'); //=> 'Ram' | |
*/ | |
var substringTo = substring(0); | |
/** | |
* Adds together all the elements of a list. | |
* | |
* @func | |
* @memberOf R | |
* @category Math | |
* @sig [Number] -> Number | |
* @param {Array} list An array of numbers | |
* @return {Number} The sum of all the numbers in the list. | |
* @see R.reduce | |
* @example | |
* | |
* R.sum([2,4,6,8,100,1]); //=> 121 | |
*/ | |
var sum = reduce(_add, 0); | |
/** | |
* Returns all but the first element of a list. If the list provided has the `tail` method, | |
* it will instead return `list.tail()`. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig [a] -> [a] | |
* @param {Array} list The array to consider. | |
* @return {Array} A new array containing all but the first element of the input list, or an | |
* empty list if the input list is empty. | |
* @example | |
* | |
* R.tail(['fi', 'fo', 'fum']); //=> ['fo', 'fum'] | |
*/ | |
var tail = _checkForMethod('tail', function (list) { | |
return _slice(list, 1); | |
}); | |
/** | |
* Returns a new list containing the first `n` elements of the given list. | |
* If `n > list.length`, returns a list of `list.length` elements. | |
* | |
* Acts as a transducer if a transformer is given in list position. | |
* @see R.transduce | |
* | |
* Dispatches to its second argument's `slice` method if present. As a | |
* result, one may replace `[a]` with `String` in the type signature. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig Number -> [a] -> [a] | |
* @param {Number} n The number of elements to return. | |
* @param {Array} xs The collection to consider. | |
* @return {Array} | |
* @example | |
* | |
* R.take(1, ['foo', 'bar', 'baz']); //=> ['foo'] | |
* R.take(2, ['foo', 'bar', 'baz']); //=> ['foo', 'bar'] | |
* R.take(3, ['foo', 'bar', 'baz']); //=> ['foo', 'bar', 'baz'] | |
* R.take(4, ['foo', 'bar', 'baz']); //=> ['foo', 'bar', 'baz'] | |
* R.take(3, 'ramda'); //=> 'ram' | |
* | |
* var personnel = [ | |
* 'Dave Brubeck', | |
* 'Paul Desmond', | |
* 'Eugene Wright', | |
* 'Joe Morello', | |
* 'Gerry Mulligan', | |
* 'Bob Bates', | |
* 'Joe Dodge', | |
* 'Ron Crotty' | |
* ]; | |
* | |
* takeFive(personnel); | |
* //=> ['Dave Brubeck', 'Paul Desmond', 'Eugene Wright', 'Joe Morello', 'Gerry Mulligan'] | |
*/ | |
var take = _curry2(_dispatchable('take', _xtake, function take(n, xs) { | |
return slice(0, n < 0 ? Infinity : n, xs); | |
})); | |
/** | |
* Returns a new list containing the first `n` elements of a given list, passing each value | |
* to the supplied predicate function, and terminating when the predicate function returns | |
* `false`. Excludes the element that caused the predicate function to fail. The predicate | |
* function is passed one argument: *(value)*. | |
* | |
* Acts as a transducer if a transformer is given in list position. | |
* @see R.transduce | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig (a -> Boolean) -> [a] -> [a] | |
* @param {Function} fn The function called per iteration. | |
* @param {Array} list The collection to iterate over. | |
* @return {Array} A new array. | |
* @example | |
* | |
* var isNotFour = function(x) { | |
* return !(x === 4); | |
* }; | |
* | |
* R.takeWhile(isNotFour, [1, 2, 3, 4]); //=> [1, 2, 3] | |
*/ | |
var takeWhile = _curry2(_dispatchable('takeWhile', _xtakeWhile, function takeWhile(fn, list) { | |
var idx = 0, len = list.length; | |
while (idx < len && fn(list[idx])) { | |
idx += 1; | |
} | |
return _slice(list, 0, idx); | |
})); | |
/** | |
* The lower case version of a string. | |
* | |
* @func | |
* @memberOf R | |
* @category String | |
* @sig String -> String | |
* @param {String} str The string to lower case. | |
* @return {String} The lower case version of `str`. | |
* @example | |
* | |
* R.toLower('XYZ'); //=> 'xyz' | |
*/ | |
var toLower = invoker(0, 'toLowerCase'); | |
/** | |
* The upper case version of a string. | |
* | |
* @func | |
* @memberOf R | |
* @category String | |
* @sig String -> String | |
* @param {String} str The string to upper case. | |
* @return {String} The upper case version of `str`. | |
* @example | |
* | |
* R.toUpper('abc'); //=> 'ABC' | |
*/ | |
var toUpper = invoker(0, 'toUpperCase'); | |
/** | |
* Initializes a transducer using supplied iterator function. Returns a single item by | |
* iterating through the list, successively calling the transformed iterator function and | |
* passing it an accumulator value and the current value from the array, and then passing | |
* the result to the next call. | |
* | |
* The iterator function receives two values: *(acc, value)*. It will be wrapped as a | |
* transformer to initialize the transducer. A transformer can be passed directly in place | |
* of an iterator function. In both cases, iteration may be stopped early with the | |
* `R.reduced` function. | |
* | |
* A transducer is a function that accepts a transformer and returns a transformer and can | |
* be composed directly. | |
* | |
* A transformer is an an 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 can be used to provide an initial accumulator, but is ignored by transduce. | |
* | |
* The iteration is performed with R.reduce after initializing the transducer. | |
* @see R.reduce | |
* @see R.reduced | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig (c -> c) -> (a,b -> a) -> a -> [b] -> a | |
* @param {Function} xf The transducer function. Receives a transformer and returns a transformer. | |
* @param {Function} fn The iterator function. Receives two values, the accumulator and the | |
* current element from the array. Wrapped as transformer, if necessary, and used to | |
* initialize the transducer | |
* @param {*} acc The initial accumulator value. | |
* @param {Array} list The list to iterate over. | |
* @see R.into | |
* @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.transduce(transducer, R.flip(R.append), [], numbers); //=> [2, 3] | |
*/ | |
var transduce = curryN(4, function (xf, fn, acc, list) { | |
return _reduce(xf(typeof fn === 'function' ? _xwrap(fn) : fn), acc, list); | |
}); | |
/** | |
* Returns a function of arity `n` from a (manually) curried function. | |
* | |
* @func | |
* @memberOf R | |
* @category Function | |
* @sig Number -> (a -> b) -> (a -> c) | |
* @param {Number} length The arity for the returned function. | |
* @param {Function} fn The function to uncurry. | |
* @return {Function} A new function. | |
* @see R.curry | |
* @example | |
* | |
* var addFour = function(a) { | |
* return function(b) { | |
* return function(c) { | |
* return function(d) { | |
* return a + b + c + d; | |
* }; | |
* }; | |
* }; | |
* }; | |
* | |
* var uncurriedAddFour = R.uncurryN(4, addFour); | |
* curriedAddFour(1, 2, 3, 4); //=> 10 | |
*/ | |
var uncurryN = _curry2(function uncurryN(depth, fn) { | |
return curryN(depth, function () { | |
var currentDepth = 1; | |
var value = fn; | |
var idx = 0; | |
var endIdx; | |
while (currentDepth <= depth && typeof value === 'function') { | |
endIdx = currentDepth === depth ? arguments.length : idx + value.length; | |
value = value.apply(this, _slice(arguments, idx, endIdx)); | |
currentDepth += 1; | |
idx = endIdx; | |
} | |
return value; | |
}); | |
}); | |
/** | |
* Combines two lists into a set (i.e. no duplicates) composed of the elements of each list. Duplication is | |
* determined according to the value returned by applying the supplied predicate to two list elements. | |
* | |
* @func | |
* @memberOf R | |
* @category Relation | |
* @sig (a,a -> Boolean) -> [a] -> [a] -> [a] | |
* @param {Function} pred A predicate used to test whether two items are equal. | |
* @param {Array} list1 The first list. | |
* @param {Array} list2 The second list. | |
* @return {Array} The first and second lists concatenated, with | |
* duplicates removed. | |
* @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}] | |
*/ | |
var unionWith = _curry3(function unionWith(pred, list1, list2) { | |
return uniqWith(pred, _concat(list1, list2)); | |
}); | |
/** | |
* Returns a new list containing only one copy of each element in the original list. | |
* `R.equals` is used to determine equality. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig [a] -> [a] | |
* @param {Array} list The array to consider. | |
* @return {Array} The list of unique items. | |
* @example | |
* | |
* R.uniq([1, 1, 2, 1]); //=> [1, 2] | |
* R.uniq([1, '1']); //=> [1, '1'] | |
* R.uniq([[42], [42]]); //=> [[42]] | |
*/ | |
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. | |
* @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)); | |
/** | |
* Takes a spec object and a test object; returns true if the test satisfies | |
* the spec, false otherwise. An object satisfies the spec if, for each of the | |
* spec's own properties, accessing that property of the object gives the same | |
* value (in `R.equals` terms) as accessing that property of the spec. | |
* | |
* `whereEq` is a specialization of [`where`](#where). | |
* | |
* @func | |
* @memberOf R | |
* @category Object | |
* @sig {String: *} -> {String: *} -> Boolean | |
* @param {Object} spec | |
* @param {Object} testObj | |
* @return {Boolean} | |
* @see R.where | |
* @example | |
* | |
* // pred :: Object -> Boolean | |
* var pred = R.whereEq({a: 1, b: 2}); | |
* | |
* pred({a: 1}); //=> false | |
* pred({a: 1, b: 2}); //=> true | |
* pred({a: 1, b: 2, c: 3}); //=> true | |
* pred({a: 1, b: 1}); //=> false | |
*/ | |
var whereEq = _curry2(function whereEq(spec, testObj) { | |
return where(mapObj(equals, spec), testObj); | |
}); | |
/** | |
* Wrap a function inside another to allow you to make adjustments to the parameters, or do | |
* other processing either before the internal function is called or with its results. | |
* | |
* @func | |
* @memberOf R | |
* @category Function | |
* @sig (a... -> b) -> ((a... -> b) -> a... -> c) -> (a... -> c) | |
* @param {Function} fn The function to wrap. | |
* @param {Function} wrapper The wrapper function. | |
* @return {Function} The wrapped function. | |
* @example | |
* | |
* var greet = function(name) {return 'Hello ' + name;}; | |
* | |
* var shoutedGreet = R.wrap(greet, function(gr, name) { | |
* return gr(name).toUpperCase(); | |
* }); | |
* shoutedGreet("Kathy"); //=> "HELLO KATHY" | |
* | |
* var shortenedGreet = R.wrap(greet, function(gr, name) { | |
* return gr(name.substring(0, 3)); | |
* }); | |
* shortenedGreet("Robert"); //=> "Hello Rob" | |
*/ | |
var wrap = _curry2(function wrap(fn, wrapper) { | |
return curryN(fn.length, function () { | |
return wrapper.apply(this, _concat([fn], arguments)); | |
}); | |
}); | |
var _chain = _curry2(function _chain(f, list) { | |
return unnest(map(f, list)); | |
}); | |
var _flatCat = function () { | |
var preservingReduced = function (xf) { | |
return { | |
'@@transducer/init': _xfBase.init, | |
'@@transducer/result': function (result) { | |
return xf['@@transducer/result'](result); | |
}, | |
'@@transducer/step': function (result, input) { | |
var ret = xf['@@transducer/step'](result, input); | |
return ret['@@transducer/reduced'] ? _forceReduced(ret) : ret; | |
} | |
}; | |
}; | |
return function _xcat(xf) { | |
var rxf = preservingReduced(xf); | |
return { | |
'@@transducer/init': _xfBase.init, | |
'@@transducer/result': function (result) { | |
return rxf['@@transducer/result'](result); | |
}, | |
'@@transducer/step': function (result, input) { | |
return !isArrayLike(input) ? _reduce(rxf, result, [input]) : _reduce(rxf, result, input); | |
} | |
}; | |
}; | |
}(); | |
var _indexOf = function _indexOf(list, item, from) { | |
var idx = 0, len = list.length; | |
if (typeof from === 'number') { | |
idx = from < 0 ? Math.max(0, len + from) : from; | |
} | |
while (idx < len) { | |
if (equals(list[idx], item)) { | |
return idx; | |
} | |
idx += 1; | |
} | |
return -1; | |
}; | |
var _lastIndexOf = function _lastIndexOf(list, item, from) { | |
var idx; | |
if (typeof from === 'number') { | |
idx = from < 0 ? list.length + from : Math.min(list.length - 1, from); | |
} else { | |
idx = list.length - 1; | |
} | |
while (idx >= 0) { | |
if (equals(list[idx], item)) { | |
return idx; | |
} | |
idx -= 1; | |
} | |
return -1; | |
}; | |
var _pluck = function _pluck(p, list) { | |
return map(prop(p), list); | |
}; | |
/** | |
* 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(max(_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': _add, | |
'@@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); | |
}; | |
}(); | |
// Function, RegExp, user-defined types | |
var _toString = function _toString(x, seen) { | |
var recur = function recur(y) { | |
var xs = seen.concat([x]); | |
return _indexOf(xs, y) >= 0 ? '<Circular>' : _toString(y, xs); | |
}; | |
switch (Object.prototype.toString.call(x)) { | |
case '[object Arguments]': | |
return '(function() { return arguments; }(' + _map(recur, x).join(', ') + '))'; | |
case '[object Array]': | |
return '[' + _map(recur, x).join(', ') + ']'; | |
case '[object Boolean]': | |
return typeof x === 'object' ? 'new Boolean(' + recur(x.valueOf()) + ')' : x.toString(); | |
case '[object Date]': | |
return 'new Date(' + _quote(_toISOString(x)) + ')'; | |
case '[object Null]': | |
return 'null'; | |
case '[object Number]': | |
return typeof x === 'object' ? 'new Number(' + recur(x.valueOf()) + ')' : 1 / x === -Infinity ? '-0' : x.toString(10); | |
case '[object String]': | |
return typeof x === 'object' ? 'new String(' + recur(x.valueOf()) + ')' : _quote(x); | |
case '[object Undefined]': | |
return 'undefined'; | |
default: | |
return typeof x.constructor === 'function' && x.constructor.name !== 'Object' && typeof x.toString === 'function' && x.toString() !== '[object Object]' ? x.toString() : // Function, RegExp, user-defined types | |
'{' + _map(function (k) { | |
return _quote(k) + ': ' + recur(x[k]); | |
}, keys(x).sort()).join(', ') + '}'; | |
} | |
}; | |
var _xchain = _curry2(function _xchain(f, xf) { | |
return map(f, _flatCat(xf)); | |
}); | |
/** | |
* Creates a new list iteration function from an existing one by adding two new parameters | |
* to its callback function: the current index, and the entire list. | |
* | |
* This would turn, for instance, Ramda's simple `map` function into one that more closely | |
* resembles `Array.prototype.map`. Note that this will only work for functions in which | |
* the iteration callback function is the first parameter, and where the list is the last | |
* parameter. (This latter might be unimportant if the list parameter is not used.) | |
* | |
* @func | |
* @memberOf R | |
* @category Function | |
* @category List | |
* @sig ((a ... -> b) ... -> [a] -> *) -> (a ..., Int, [a] -> b) ... -> [a] -> *) | |
* @param {Function} fn A list iteration function that does not pass index/list to its callback | |
* @return An altered list iteration function thats passes index/list to its callback | |
* @example | |
* | |
* var mapIndexed = R.addIndex(R.map); | |
* mapIndexed(function(val, idx) {return idx + '-' + val;}, ['f', 'o', 'o', 'b', 'a', 'r']); | |
* //=> ['0-f', '1-o', '2-o', '3-b', '4-a', '5-r'] | |
*/ | |
var addIndex = _curry1(function (fn) { | |
return curryN(fn.length, function () { | |
var idx = 0; | |
var origFn = arguments[0]; | |
var list = arguments[arguments.length - 1]; | |
var indexedFn = function () { | |
var result = origFn.apply(this, _concat(arguments, [ | |
idx, | |
list | |
])); | |
idx += 1; | |
return result; | |
}; | |
return fn.apply(this, _prepend(indexedFn, _slice(arguments, 1))); | |
}); | |
}); | |
/** | |
* ap applies a list of functions to a list of values. | |
* | |
* @func | |
* @memberOf R | |
* @category Function | |
* @sig [f] -> [a] -> [f a] | |
* @param {Array} fns An array of functions | |
* @param {Array} vs An array of values | |
* @return {Array} An array of results of applying each of `fns` to all of `vs` in turn. | |
* @example | |
* | |
* 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); | |
}); | |
/** | |
* `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 | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig (a -> [b]) -> [a] -> [b] | |
* @param {Function} fn | |
* @param {Array} list | |
* @return {Array} | |
* @example | |
* | |
* var duplicate = function(n) { | |
* return [n, n]; | |
* }; | |
* R.chain(duplicate, [1, 2, 3]); //=> [1, 1, 2, 2, 3, 3] | |
*/ | |
var chain = _curry2(_dispatchable('chain', _xchain, _chain)); | |
/** | |
* Turns a list of Functors into a Functor of a list, applying | |
* a mapping function to the elements of the list along the way. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @see R.commute | |
* @sig Functor f => (f a -> f b) -> (x -> f x) -> [f 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 commuteMap = _curry3(function commuteMap(fn, of, list) { | |
function consF(acc, ftor) { | |
return ap(map(append, fn(ftor)), acc); | |
} | |
return _reduce(consF, of([]), list); | |
}); | |
/** | |
* Returns a curried equivalent of the provided function. The curried | |
* function has two unusual capabilities. First, its arguments needn't | |
* be provided one at a time. If `f` is a ternary function and `g` is | |
* `R.curry(f)`, the following are equivalent: | |
* | |
* - `g(1)(2)(3)` | |
* - `g(1)(2, 3)` | |
* - `g(1, 2)(3)` | |
* - `g(1, 2, 3)` | |
* | |
* Secondly, the special placeholder value `R.__` may be used to specify | |
* "gaps", allowing partial application of any combination of arguments, | |
* regardless of their positions. If `g` is as above and `_` is `R.__`, | |
* the following are equivalent: | |
* | |
* - `g(1, 2, 3)` | |
* - `g(_, 2, 3)(1)` | |
* - `g(_, _, 3)(1)(2)` | |
* - `g(_, _, 3)(1, 2)` | |
* - `g(_, 2)(1)(3)` | |
* - `g(_, 2)(1, 3)` | |
* - `g(_, 2)(_, 3)(1)` | |
* | |
* @func | |
* @memberOf R | |
* @category Function | |
* @sig (* -> a) -> (* -> a) | |
* @param {Function} fn The function to curry. | |
* @return {Function} A new, curried function. | |
* @see R.curryN | |
* @example | |
* | |
* var addFourNumbers = function(a, b, c, d) { | |
* return a + b + c + d; | |
* }; | |
* | |
* var curriedAddFourNumbers = R.curry(addFourNumbers); | |
* var f = curriedAddFourNumbers(1, 2); | |
* var g = f(3); | |
* g(4); //=> 10 | |
*/ | |
var curry = _curry1(function curry(fn) { | |
return curryN(fn.length, fn); | |
}); | |
/** | |
* Returns a list containing all but the first `n` elements of the given `list`. | |
* | |
* Acts as a transducer if a transformer is given in list position. | |
* @see R.transduce | |
* | |
* Dispatches to its second argument's `slice` method if present. As a | |
* result, one may replace `[a]` with `String` in the type signature. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig Number -> [a] -> [a] | |
* @param {Number} n The number of elements of `xs` to skip. | |
* @param {Array} xs The collection to consider. | |
* @return {Array} | |
* @example | |
* | |
* R.drop(1, ['foo', 'bar', 'baz']); //=> ['bar', 'baz'] | |
* R.drop(2, ['foo', 'bar', 'baz']); //=> ['baz'] | |
* R.drop(3, ['foo', 'bar', 'baz']); //=> [] | |
* R.drop(4, ['foo', 'bar', 'baz']); //=> [] | |
* R.drop(3, 'ramda'); //=> 'da' | |
*/ | |
var drop = _curry2(_dispatchable('drop', _xdrop, function drop(n, xs) { | |
return slice(Math.max(0, n), Infinity, xs); | |
})); | |
/** | |
* Returns a new list without any consecutively repeating elements. Equality is | |
* determined by applying the supplied predicate two consecutive elements. | |
* The first element in a series of equal element is the one being preserved. | |
* | |
* Acts as a transducer if a transformer is given in list position. | |
* @see R.transduce | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig (a, a -> Boolean) -> [a] -> [a] | |
* @param {Function} pred A predicate used to test whether two items are equal. | |
* @param {Array} list The array to consider. | |
* @return {Array} `list` without repeating elements. | |
* @example | |
* | |
* function lengthEq(x, y) { return 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] | |
*/ | |
var dropRepeatsWith = _curry2(_dispatchable('dropRepeatsWith', _xdropRepeatsWith, function dropRepeatsWith(pred, list) { | |
var result = []; | |
var idx = 1; | |
var len = list.length; | |
if (len !== 0) { | |
result[0] = list[0]; | |
while (idx < len) { | |
if (!pred(last(result), list[idx])) { | |
result[result.length] = list[idx]; | |
} | |
idx += 1; | |
} | |
} | |
return result; | |
})); | |
/** | |
* Performs a deep test on whether two items are equal. | |
* Equality implies the two items are semmatically equivalent. | |
* Cyclic structures are handled as expected | |
* @see R.equals | |
* | |
* @func | |
* @memberOf R | |
* @category Relation | |
* @sig a -> b -> Boolean | |
* @param {*} a | |
* @param {*} b | |
* @return {Boolean} | |
* @deprecated since v0.15.0 | |
* @example | |
* | |
* var o = {}; | |
* R.eqDeep(o, o); //=> true | |
* R.eqDeep(o, {}); //=> true | |
* R.eqDeep(1, 1); //=> true | |
* R.eqDeep(1, '1'); //=> false | |
* | |
* var a = {}; a.v = a; | |
* var b = {}; b.v = b; | |
* R.eqDeep(a, b); //=> true | |
*/ | |
var eqDeep = equals; | |
/** | |
* Reports whether two objects have the same value, in `R.equals` terms, | |
* for the specified property. Useful as a curried predicate. | |
* | |
* @func | |
* @memberOf R | |
* @category Object | |
* @sig k -> {k: v} -> {k: v} -> Boolean | |
* @param {String} prop The name of the property to compare | |
* @param {Object} obj1 | |
* @param {Object} obj2 | |
* @return {Boolean} | |
* | |
* @example | |
* | |
* var o1 = { a: 1, b: 2, c: 3, d: 4 }; | |
* var o2 = { a: 10, b: 20, c: 3, d: 40 }; | |
* R.eqProps('a', o1, o2); //=> false | |
* R.eqProps('c', o1, o2); //=> true | |
*/ | |
var eqProps = _curry3(function eqProps(prop, obj1, obj2) { | |
return equals(obj1[prop], obj2[prop]); | |
}); | |
/** | |
* Returns a new function much like the supplied one, except that the first two arguments' | |
* order is reversed. | |
* | |
* @func | |
* @memberOf R | |
* @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); | |
* }; | |
* | |
* mergeThree(1, 2, 3); //=> [1, 2, 3] | |
* | |
* R.flip(mergeThree)(1, 2, 3); //=> [2, 1, 3] | |
*/ | |
var flip = _curry1(function flip(fn) { | |
return curry(function (a, b) { | |
var args = _slice(arguments); | |
args[0] = b; | |
args[1] = a; | |
return fn.apply(this, args); | |
}); | |
}); | |
/** | |
* Returns the position of the first occurrence of an item in an array, | |
* or -1 if the item is not included in the array. `R.equals` is used to | |
* determine equality. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig a -> [a] -> Number | |
* @param {*} target The item to find. | |
* @param {Array} xs The array to search in. | |
* @return {Number} the index of the target, or -1 if the target is not found. | |
* | |
* @example | |
* | |
* R.indexOf(3, [1,2,3,4]); //=> 2 | |
* 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); | |
}); | |
/** | |
* Returns all but the last element of a list. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig [a] -> [a] | |
* @param {Array} list The array to consider. | |
* @return {Array} A new array containing all but the last element of the input list, or an | |
* empty list if the input list is empty. | |
* @example | |
* | |
* R.init(['fi', 'fo', 'fum']); //=> ['fi', 'fo'] | |
*/ | |
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 | |
* @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 the result of applying `obj[methodName]` to `args`. | |
* | |
* @func | |
* @memberOf R | |
* @category Object | |
* @sig String -> [*] -> Object -> * | |
* @param {String} methodName | |
* @param {Array} args | |
* @param {Object} obj | |
* @return {*} | |
* @deprecated since v0.15.0 | |
* @example | |
* | |
* // toBinary :: Number -> String | |
* var toBinary = R.invoke('toString', [2]) | |
* | |
* toBinary(42); //=> '101010' | |
* toBinary(63); //=> '111111' | |
*/ | |
var invoke = curry(function invoke(methodName, args, obj) { | |
return obj[methodName].apply(obj, args); | |
}); | |
/** | |
* Returns `true` if all elements are unique, in `R.equals` terms, | |
* otherwise `false`. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig [a] -> Boolean | |
* @param {Array} list The array to consider. | |
* @return {Boolean} `true` if all elements are unique, else `false`. | |
* @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; | |
}); | |
/** | |
* Returns the position of the last occurrence of an item in | |
* an array, or -1 if the item is not included in the array. | |
* `R.equals` is used to determine equality. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig a -> [a] -> Number | |
* @param {*} target The item to find. | |
* @param {Array} xs The array to search in. | |
* @return {Number} the index of the target, or -1 if the target is not found. | |
* | |
* @example | |
* | |
* R.lastIndexOf(3, [-1,3,3,0,1,2,3,4]); //=> 6 | |
* R.lastIndexOf(10, [1,2,3,4]); //=> -1 | |
*/ | |
var lastIndexOf = _curry2(function lastIndexOf(target, xs) { | |
return _hasMethod('lastIndexOf', xs) ? xs.lastIndexOf(target) : _lastIndexOf(xs, target); | |
}); | |
/** | |
* "lifts" a function to be the specified arity, so that it may "map over" that many | |
* lists (or other Functors). | |
* | |
* @func | |
* @memberOf R | |
* @see R.lift | |
* @category Function | |
* @sig Number -> (*... -> *) -> ([*]... -> [*]) | |
* @param {Function} fn The function to lift into higher context | |
* @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); | |
* })); | |
* madd3([1,2,3], [1,2,3], [1]); //=> [3, 4, 5, 4, 5, 6, 5, 6, 7] | |
*/ | |
var liftN = _curry2(function liftN(arity, fn) { | |
var lifted = curryN(arity, fn); | |
return curryN(arity, function () { | |
return _reduce(ap, map(lifted, arguments[0]), _slice(arguments, 1)); | |
}); | |
}); | |
/** | |
* Returns the mean of the given list of numbers. | |
* | |
* @func | |
* @memberOf R | |
* @category Math | |
* @sig [Number] -> Number | |
* @param {Array} list | |
* @return {Number} | |
* @example | |
* | |
* R.mean([2, 7, 9]); //=> 6 | |
* R.mean([]); //=> NaN | |
*/ | |
var mean = _curry1(function mean(list) { | |
return sum(list) / list.length; | |
}); | |
/** | |
* Returns the median of the given list of numbers. | |
* | |
* @func | |
* @memberOf R | |
* @category Math | |
* @sig [Number] -> Number | |
* @param {Array} list | |
* @return {Number} | |
* @example | |
* | |
* R.median([2, 9, 7]); //=> 7 | |
* R.median([7, 2, 10, 9]); //=> 8 | |
* R.median([]); //=> NaN | |
*/ | |
var median = _curry1(function median(list) { | |
var len = list.length; | |
if (len === 0) { | |
return NaN; | |
} | |
var width = 2 - len % 2; | |
var idx = (len - width) / 2; | |
return mean(_slice(list).sort(function (a, b) { | |
return a < b ? -1 : a > b ? 1 : 0; | |
}).slice(idx, idx + width)); | |
}); | |
/** | |
* Merges a list of objects together into one object. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig [{k: v}] -> {k: v} | |
* @param {Array} list An array of objects | |
* @return {Object} A merged object. | |
* @see R.reduce | |
* @example | |
* | |
* R.mergeAll([{foo:1},{bar:2},{baz:3}]); //=> {foo:1,bar:2,baz:3} | |
* R.mergeAll([{foo:1},{foo:2},{bar:2}]); //=> {foo:2,bar:2} | |
*/ | |
var mergeAll = _curry1(function mergeAll(list) { | |
return reduce(merge, {}, list); | |
}); | |
/** | |
* Returns a partial copy of an object omitting the keys specified. | |
* | |
* @func | |
* @memberOf R | |
* @category Object | |
* @sig [String] -> {String: *} -> {String: *} | |
* @param {Array} names an array of String property names to omit from the new object | |
* @param {Object} obj The object to copy from | |
* @return {Object} A new object with properties from `names` not on it. | |
* @example | |
* | |
* R.omit(['a', 'd'], {a: 1, b: 2, c: 3, d: 4}); //=> {b: 2, c: 3} | |
*/ | |
var omit = _curry2(function omit(names, obj) { | |
var result = {}; | |
for (var prop in obj) { | |
if (_indexOf(names, prop) < 0) { | |
result[prop] = obj[prop]; | |
} | |
} | |
return result; | |
}); | |
/** | |
* 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`. | |
* | |
* @func | |
* @memberOf R | |
* @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. | |
* @example | |
* | |
* var multiply = function(a, b) { return 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.'); | |
* sayHelloToMs('Jane', 'Jones'); //=> 'Hello, Ms. Jane Jones!' | |
*/ | |
var partial = curry(_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`. | |
* | |
* @func | |
* @memberOf R | |
* @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. | |
* @example | |
* | |
* var greet = function(salutation, title, firstName, lastName) { | |
* return salutation + ', ' + title + ' ' + firstName + ' ' + lastName + '!'; | |
* }; | |
* var greetMsJaneJones = R.partialRight(greet, 'Ms.', 'Jane', 'Jones'); | |
* | |
* greetMsJaneJones('Hello'); //=> 'Hello, Ms. Jane Jones!' | |
*/ | |
var partialRight = curry(_createPartialApplicator(flip(_concat))); | |
/** | |
* Returns a new list by plucking the same named property off all objects in the list supplied. | |
* | |
* @func | |
* @memberOf R | |
* @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. | |
* @example | |
* | |
* R.pluck('a')([{a: 1}, {a: 2}]); //=> [1, 2] | |
* R.pluck(0)([[1, 2], [3, 4]]); //=> [1, 3] | |
*/ | |
var pluck = _curry2(_pluck); | |
/** | |
* Multiplies together all the elements of a list. | |
* | |
* @func | |
* @memberOf R | |
* @category Math | |
* @sig [Number] -> Number | |
* @param {Array} list An array of numbers | |
* @return {Number} The product of all the numbers in the list. | |
* @see R.reduce | |
* @example | |
* | |
* R.product([2,4,6,8,100,1]); //=> 38400 | |
*/ | |
var product = reduce(_multiply, 1); | |
/** | |
* Returns the string representation of the given value. `eval`'ing the output | |
* should result in a value equivalent to the input value. Many of the built-in | |
* `toString` methods do not satisfy this requirement. | |
* | |
* If the given value is an `[object Object]` with a `toString` method other | |
* than `Object.prototype.toString`, this method is invoked with no arguments | |
* to produce the return value. This means user-defined constructor functions | |
* can provide a suitable `toString` method. For example: | |
* | |
* function Point(x, y) { | |
* this.x = x; | |
* this.y = y; | |
* } | |
* | |
* Point.prototype.toString = function() { | |
* return 'new Point(' + this.x + ', ' + this.y + ')'; | |
* }; | |
* | |
* R.toString(new Point(1, 2)); //=> 'new Point(1, 2)' | |
* | |
* @func | |
* @memberOf R | |
* @category String | |
* @sig * -> String | |
* @param {*} val | |
* @return {String} | |
* @example | |
* | |
* R.toString(42); //=> '42' | |
* R.toString('abc'); //=> '"abc"' | |
* R.toString([1, 2, 3]); //=> '[1, 2, 3]' | |
* R.toString({foo: 1, bar: 2, baz: 3}); //=> '{"bar": 2, "baz": 3, "foo": 1}' | |
* R.toString(new Date('2001-02-03T04:05:06Z')); //=> 'new Date("2001-02-03T04:05:06.000Z")' | |
*/ | |
var toString = _curry1(function toString(val) { | |
return _toString(val, []); | |
}); | |
/** | |
* Combines two lists into a set (i.e. no duplicates) composed of the | |
* elements of each list. | |
* | |
* @func | |
* @memberOf R | |
* @category Relation | |
* @sig [a] -> [a] -> [a] | |
* @param {Array} as The first list. | |
* @param {Array} bs The second list. | |
* @return {Array} The first and second lists concatenated, with | |
* duplicates removed. | |
* @example | |
* | |
* R.union([1, 2, 3], [2, 3, 4]); //=> [1, 2, 3, 4] | |
*/ | |
var union = _curry2(compose(uniq, _concat)); | |
/** | |
* Accepts a function `fn` and any number of transformer functions and returns a new | |
* 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. | |
* | |
* If more arguments are passed to the returned function than transformer functions, those | |
* arguments are passed directly to `fn` as additional parameters. If you expect additional | |
* arguments that don't need to be transformed, although you can ignore them, it's best to | |
* pass an identity function so that the new function reports the correct arity. | |
* | |
* @func | |
* @memberOf R | |
* @category Function | |
* @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 | |
* @return {Function} The wrapped function. | |
* @example | |
* | |
* // Example 1: | |
* | |
* // Number -> [Person] -> [Person] | |
* var byAge = R.useWith(R.filter, R.propEq('age'), R.identity); | |
* | |
* var kids = [ | |
* {name: 'Abbie', age: 6}, | |
* {name: 'Brian', age: 5}, | |
* {name: 'Chris', age: 6}, | |
* {name: 'David', age: 4}, | |
* {name: 'Ellie', age: 5} | |
* ]; | |
* | |
* byAge(5, kids); //=> [{name: 'Brian', age: 5}, {name: 'Ellie', age: 5}] | |
* | |
* // Example 2: | |
* | |
* 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 () { | |
var args = [], idx = 0; | |
while (idx < tlen) { | |
args[idx] = transformers[idx](arguments[idx]); | |
idx += 1; | |
} | |
return fn.apply(this, args.concat(_slice(arguments, tlen))); | |
})); | |
}); | |
var _contains = function _contains(a, list) { | |
return _indexOf(list, a) >= 0; | |
}; | |
/** | |
* Given a list of predicates, returns a new predicate that will be true exactly when all of them are. | |
* | |
* @func | |
* @memberOf R | |
* @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. | |
* @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 allPass = curry(_predicateWrap(_all)); | |
/** | |
* Given a list of predicates returns a new predicate that will be true exactly when any one of them is. | |
* | |
* @func | |
* @memberOf R | |
* @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. | |
* @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 anyPass = curry(_predicateWrap(_any)); | |
/** | |
* Returns the result of calling its first argument with the remaining | |
* arguments. This is occasionally useful as a converging function for | |
* `R.converge`: the left branch can produce a function while the right | |
* branch produces a value to be passed to that function as an argument. | |
* | |
* @func | |
* @memberOf R | |
* @category Function | |
* @sig (*... -> a),*... -> a | |
* @param {Function} fn The function to apply to the remaining arguments. | |
* @param {...*} args Any number of positional arguments. | |
* @return {*} | |
* @example | |
* | |
* var indentN = R.pipe(R.times(R.always(' ')), | |
* R.join(''), | |
* R.replace(/^(?!$)/gm)); | |
* | |
* var format = R.converge(R.call, | |
* R.pipe(R.prop('indent'), indentN), | |
* R.prop('value')); | |
* | |
* format({indent: 2, value: 'foo\nbar\nbaz\n'}); //=> ' foo\n bar\n baz\n' | |
*/ | |
var call = curry(function call(fn) { | |
return fn.apply(this, _slice(arguments, 1)); | |
}); | |
/** | |
* Turns a list of Functors into a Functor of a list. | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @see R.commuteMap | |
* @sig Functor f => (x -> f x) -> [f a] -> f [a] | |
* @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.commute(R.of, [[1], [2, 3]]); //=> [[1, 2], [1, 3]] | |
* R.commute(R.of, [[1, 2], [3]]); //=> [[1, 3], [2, 3]] | |
* R.commute(R.of, [[1], [2], [3]]); //=> [[1, 2, 3]] | |
* R.commute(Maybe.of, [Just(1), Just(2), Just(3)]); //=> Just([1, 2, 3]) | |
* R.commute(Maybe.of, [Just(1), Just(2), Nothing()]); //=> Nothing() | |
*/ | |
var commute = commuteMap(map(identity)); | |
/** | |
* Wraps a constructor function inside a curried function that can be called with the same | |
* arguments and returns the same type. The arity of the function returned is specified | |
* to allow using variadic constructor functions. | |
* | |
* @func | |
* @memberOf R | |
* @category Function | |
* @sig Number -> (* -> {*}) -> (* -> {*}) | |
* @param {Number} n The arity of the constructor function. | |
* @param {Function} Fn The constructor function to wrap. | |
* @return {Function} A wrapped, curried constructor function. | |
* @example | |
* | |
* // Variadic constructor function | |
* var Widget = function() { | |
* this.children = Array.prototype.slice.call(arguments); | |
* // ... | |
* }; | |
* Widget.prototype = { | |
* // ... | |
* }; | |
* var allConfigs = [ | |
* // ... | |
* ]; | |
* R.map(R.constructN(1, Widget), allConfigs); // a list of Widgets | |
*/ | |
var constructN = _curry2(function constructN(n, Fn) { | |
if (n > 10) { | |
throw new Error('Constructor with greater than ten arguments'); | |
} | |
if (n === 0) { | |
return function () { | |
return new Fn(); | |
}; | |
} | |
return curry(nAry(n, function ($0, $1, $2, $3, $4, $5, $6, $7, $8, $9) { | |
switch (arguments.length) { | |
case 1: | |
return new Fn($0); | |
case 2: | |
return new Fn($0, $1); | |
case 3: | |
return new Fn($0, $1, $2); | |
case 4: | |
return new Fn($0, $1, $2, $3); | |
case 5: | |
return new Fn($0, $1, $2, $3, $4); | |
case 6: | |
return new Fn($0, $1, $2, $3, $4, $5); | |
case 7: | |
return new Fn($0, $1, $2, $3, $4, $5, $6); | |
case 8: | |
return new Fn($0, $1, $2, $3, $4, $5, $6, $7); | |
case 9: | |
return new Fn($0, $1, $2, $3, $4, $5, $6, $7, $8); | |
case 10: | |
return new Fn($0, $1, $2, $3, $4, $5, $6, $7, $8, $9); | |
} | |
})); | |
}); | |
/** | |
* Returns `true` if the specified value is equal, in `R.equals` terms, | |
* to at least one element of the given list; `false` otherwise. | |
* | |
* @func | |
* @memberOf R | |
* @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. | |
* | |
* @example | |
* | |
* R.contains(3, [1, 2, 3]); //=> true | |
* R.contains(4, [1, 2, 3]); //=> false | |
* R.contains([42], [[42]]); //=> true | |
*/ | |
var contains = _curry2(_contains); | |
/** | |
* 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. | |
* | |
* @func | |
* @memberOf R | |
* @category Function | |
* @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. | |
* @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; }; | |
* | |
* //≅ multiply( add(1, 2), subtract(1, 2) ); | |
* 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 converge = curryN(3, function (after) { | |
var fns = _slice(arguments, 1); | |
return curryN(max(pluck('length', fns)), function () { | |
var args = arguments; | |
var context = this; | |
return after.apply(context, _map(function (fn) { | |
return fn.apply(context, args); | |
}, fns)); | |
}); | |
}); | |
/** | |
* Finds the set (i.e. no duplicates) of all elements in the first list not contained in the second list. | |
* | |
* @func | |
* @memberOf R | |
* @category Relation | |
* @sig [a] -> [a] -> [a] | |
* @param {Array} list1 The first list. | |
* @param {Array} list2 The second list. | |
* @return {Array} The elements in `list1` that are not in `list2`. | |
* @see R.differenceWith | |
* @example | |
* | |
* R.difference([1,2,3,4], [7,6,5,4,3]); //=> [1,2] | |
* R.difference([7,6,5,4,3], [1,2,3,4]); //=> [7,6,5] | |
*/ | |
var difference = _curry2(function difference(first, second) { | |
var out = []; | |
var idx = 0; | |
var firstLen = first.length; | |
while (idx < firstLen) { | |
if (!_contains(first[idx], second) && !_contains(first[idx], out)) { | |
out[out.length] = first[idx]; | |
} | |
idx += 1; | |
} | |
return out; | |
}); | |
/** | |
* Returns a new list without any consecutively repeating elements. | |
* `R.equals` is used to determine equality. | |
* | |
* Acts as a transducer if a transformer is given in list position. | |
* @see R.transduce | |
* | |
* @func | |
* @memberOf R | |
* @category List | |
* @sig [a] -> [a] | |
* @param {Array} list The array to consider. | |
* @return {Array} `list` without repeating elements. | |
* @example | |
* | |
* R.dropRepeats([1, 1, 1, 2, 3, 4, 4, 2, 2]); //=> [1, 2, 3, 4, 2] | |
*/ | |
var dropRepeats = _curry1(_dispatchable('dropRepeats', _xdropRepeatsWith(equals), dropRepeatsWith(equals))); | |
/** | |
* Combines two lists into a set (i.e. no duplicates) composed of those elements common to both lists. | |
* | |
* @func | |
* @memberOf R | |
* @category Relation | |
* @sig [a] -> [a] -> [a] | |
* @param {Array} list1 The first list. | |
* @param {Array} list2 The second list. | |
* @see R.intersectionWith | |
* @return {Array} The list of elements found in both `list1` and `list2`. | |
* @example | |
* | |
* R.intersection([1,2,3,4], [7,6,5,4,3]); //=> [4, 3] | |
*/ | |
var intersection = _curry2(function intersection(list1, list2) { | |
return uniq(_filter(flip(_contains)(list1), list2)); | |
}); | |
/** | |
* "lifts" a function of arity > 1 so that it may "map over" an Array or | |
* other Functor. | |
* | |
* @func | |
* @memberOf R | |
* @see R.liftN | |
* @category Function | |
* @sig (*... -> *) -> ([*]... -> [*]) | |
* @param {Function} fn The function to lift into higher context | |
* @return {Function} The function `fn` applicable to mappable objects. | |
* @example | |
* | |
* var madd3 = R.lift(R.curry(function(a, b, c) { | |
* return 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; | |
* })); | |
* madd5([1,2], [3], [4, 5], [6], [7, 8]); //=> [21, 22, 22, 23, 22, 23, 23, 24] | |
*/ | |
var lift = _curry1(function lift(fn) { | |
return liftN(fn.length, fn); | |
}); | |
/** | |
* Creates a new function that, when invoked, caches the result of calling `fn` for a given | |
* argument set and returns the result. Subsequent calls to the memoized `fn` with the same | |
* argument set will not result in an additional call to `fn`; instead, the cached result | |
* for that set of arguments will be returned. | |
* | |
* @func | |
* @memberOf R | |
* @category Function | |
* @sig (*... -> a) -> (*... -> a) | |
* @param {Function} fn The function to memoize. | |
* @return {Function} Memoized version of `fn`. | |
* @example | |
* | |
* var count = 0; | |
* var factorial = R.memoize(function(n) { | |
* count += 1; | |
* return R.product(R.range(1, n + 1)); | |
* }); | |
* factorial(5); //=> 120 | |
* factorial(5); //=> 120 | |
* factorial(5); //=> 120 | |
* count; //=> 1 | |
*/ | |
var memoize = _curry1(function memoize(fn) { | |
var cache = {}; | |
return function () { | |
var key = toString(arguments); | |
if (!_has(key, cache)) { | |
cache[key] = fn.apply(this, arguments); | |
} | |
return cache[key]; | |
}; | |
}); | |
/** | |
* Reasonable analog to SQL `select` statement. | |
* | |
* @func | |
* @memberOf R | |
* @category Object | |
* @category Relation | |
* @sig [k] -> [{k: v}] -> [{k: v}] | |
* @param {Array} props The property names to project | |
* @param {Array} objs The objects to query | |
* @return {Array} An array of objects with just the `props` properties. | |
* @example | |
* | |
* var abby = {name: 'Abby', age: 7, hair: 'blond', grade: 2}; | |
* var fred = {name: 'Fred', age: 12, hair: 'brown', grade: 7}; | |
* var kids = [abby, fred]; | |
* R.project(['name', 'grade'], kids); //=> [{name: 'Abby', grade: 2}, {name: 'Fred', grade: 7}] | |
*/ | |
// passing `identity` gives correct arity | |
var project = useWith(_map, pickAll, identity); | |
/** | |
* Wraps a constructor function inside a curried function that can be called with the same | |
* arguments and returns the same type. | |
* | |
* @func | |
* @memberOf R | |
* @category Function | |
* @sig (* -> {*}) -> (* -> {*}) | |
* @param {Function} Fn The constructor function to wrap. | |
* @return {Function} A wrapped, curried constructor function. | |
* @example | |
* | |
* // Constructor function | |
* var Widget = function(config) { | |
* // ... | |
* }; | |
* Widget.prototype = { | |
* // ... | |
* }; | |
* var allConfigs = [ | |
* // ... | |
* ]; | |
* R.map(R.construct(Widget), allConfigs); // a list of Widgets | |
*/ | |
var construct = _curry1(function construct(Fn) { | |
return constructN(Fn.length, Fn); | |
}); | |
var R = { | |
F: F, | |
T: T, | |
__: __, | |
add: add, | |
addIndex: addIndex, | |
adjust: adjust, | |
all: all, | |
allPass: allPass, | |
always: always, | |
and: and, | |
any: any, | |
anyPass: anyPass, | |
ap: ap, | |
aperture: aperture, | |
append: append, | |
apply: apply, | |
arity: arity, | |
assoc: assoc, | |
assocPath: assocPath, | |
binary: binary, | |
bind: bind, | |
both: both, | |
call: call, | |
chain: chain, | |
clone: clone, | |
commute: commute, | |
commuteMap: commuteMap, | |
comparator: comparator, | |
complement: complement, | |
compose: compose, | |
composeL: composeL, | |
composeP: composeP, | |
concat: concat, | |
cond: cond, | |
construct: construct, | |
constructN: constructN, | |
contains: contains, | |
containsWith: containsWith, | |
converge: converge, | |
countBy: countBy, | |
createMapEntry: createMapEntry, | |
curry: curry, | |
curryN: curryN, | |
dec: dec, | |
defaultTo: defaultTo, | |
difference: difference, | |
differenceWith: differenceWith, | |
dissoc: dissoc, | |
dissocPath: dissocPath, | |
divide: divide, | |
drop: drop, | |
dropRepeats: dropRepeats, | |
dropRepeatsWith: dropRepeatsWith, | |
dropWhile: dropWhile, | |
either: either, | |
empty: empty, | |
eq: eq, | |
eqDeep: eqDeep, | |
eqProps: eqProps, | |
equals: equals, | |
evolve: evolve, | |
filter: filter, | |
filterIndexed: filterIndexed, | |
find: find, | |
findIndex: findIndex, | |
findLast: findLast, | |
findLastIndex: findLastIndex, | |
flatten: flatten, | |
flip: flip, | |
forEach: forEach, | |
forEachIndexed: forEachIndexed, | |
fromPairs: fromPairs, | |
functions: functions, | |
functionsIn: functionsIn, | |
groupBy: groupBy, | |
gt: gt, | |
gte: gte, | |
has: has, | |
hasIn: hasIn, | |
head: head, | |
identical: identical, | |
identity: identity, | |
ifElse: ifElse, | |
inc: inc, | |
indexOf: indexOf, | |
init: init, | |
insert: insert, | |
insertAll: insertAll, | |
intersection: intersection, | |
intersectionWith: intersectionWith, | |
intersperse: intersperse, | |
into: into, | |
invert: invert, | |
invertObj: invertObj, | |
invoke: invoke, | |
invoker: invoker, | |
is: is, | |
isArrayLike: isArrayLike, | |
isEmpty: isEmpty, | |
isNil: isNil, | |
isSet: isSet, | |
join: join, | |
keys: keys, | |
keysIn: keysIn, | |
last: last, | |
lastIndexOf: lastIndexOf, | |
length: length, | |
lens: lens, | |
lensIndex: lensIndex, | |
lensOn: lensOn, | |
lensProp: lensProp, | |
lift: lift, | |
liftN: liftN, | |
lt: lt, | |
lte: lte, | |
map: map, | |
mapAccum: mapAccum, | |
mapAccumRight: mapAccumRight, | |
mapIndexed: mapIndexed, | |
mapObj: mapObj, | |
mapObjIndexed: mapObjIndexed, | |
match: match, | |
mathMod: mathMod, | |
max: max, | |
maxBy: maxBy, | |
mean: mean, | |
median: median, | |
memoize: memoize, | |
merge: merge, | |
mergeAll: mergeAll, | |
min: min, | |
minBy: minBy, | |
modulo: modulo, | |
multiply: multiply, | |
nAry: nAry, | |
negate: negate, | |
none: none, | |
not: not, | |
nth: nth, | |
nthArg: nthArg, | |
nthChar: nthChar, | |
nthCharCode: nthCharCode, | |
of: of, | |
omit: omit, | |
once: once, | |
or: or, | |
partial: partial, | |
partialRight: partialRight, | |
partition: partition, | |
path: path, | |
pathEq: pathEq, | |
pick: pick, | |
pickAll: pickAll, | |
pickBy: pickBy, | |
pipe: pipe, | |
pipeL: pipeL, | |
pipeP: pipeP, | |
pluck: pluck, | |
prepend: prepend, | |
product: product, | |
project: project, | |
prop: prop, | |
propEq: propEq, | |
propOr: propOr, | |
props: props, | |
range: range, | |
reduce: reduce, | |
reduceIndexed: reduceIndexed, | |
reduceRight: reduceRight, | |
reduceRightIndexed: reduceRightIndexed, | |
reduced: reduced, | |
reject: reject, | |
rejectIndexed: rejectIndexed, | |
remove: remove, | |
repeat: repeat, | |
replace: replace, | |
reverse: reverse, | |
scan: scan, | |
slice: slice, | |
sort: sort, | |
sortBy: sortBy, | |
split: split, | |
strIndexOf: strIndexOf, | |
strLastIndexOf: strLastIndexOf, | |
substring: substring, | |
substringFrom: substringFrom, | |
substringTo: substringTo, | |
subtract: subtract, | |
sum: sum, | |
tail: tail, | |
take: take, | |
takeWhile: takeWhile, | |
tap: tap, | |
test: test, | |
times: times, | |
toLower: toLower, | |
toPairs: toPairs, | |
toPairsIn: toPairsIn, | |
toString: toString, | |
toUpper: toUpper, | |
transduce: transduce, | |
trim: trim, | |
type: type, | |
unapply: unapply, | |
unary: unary, | |
uncurryN: uncurryN, | |
unfold: unfold, | |
union: union, | |
unionWith: unionWith, | |
uniq: uniq, | |
uniqWith: uniqWith, | |
unnest: unnest, | |
update: update, | |
useWith: useWith, | |
values: values, | |
valuesIn: valuesIn, | |
where: where, | |
whereEq: whereEq, | |
wrap: wrap, | |
xprod: xprod, | |
zip: zip, | |
zipObj: zipObj, | |
zipWith: zipWith | |
}; | |
/* TEST_ENTRY_POINT */ | |
if (true) { | |
module.exports = R; | |
} else if (typeof define === 'function' && define.amd) { | |
define(function() { return R; }); | |
} else { | |
this.R = R; | |
} | |
}.call(this)); | |
/***/ }, | |
/* 2 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var _equals = __webpack_require__(1).equals; | |
module.exports = { | |
baseMap: function(f) { | |
return f(this.value); | |
}, | |
getEquals: function(constructor) { | |
return function equals(that) { | |
return that instanceof constructor && _equals(this.value, that.value); | |
}; | |
}, | |
extend: function(Child, Parent) { | |
function Ctor() { | |
this.constructor = Child; | |
} | |
Ctor.prototype = Parent.prototype; | |
Child.prototype = new Ctor(); | |
Child.super_ = Parent.prototype; | |
}, | |
identity: function(x) { return x; }, | |
notImplemented: function(str) { | |
return function() { | |
throw new Error(str + ' is not implemented'); | |
}; | |
}, | |
notCallable: function(fn) { | |
return function() { | |
throw new Error(fn + ' cannot be called directly'); | |
}; | |
}, | |
returnThis: function() { return this; } | |
}; | |
/***/ }, | |
/* 3 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var R = __webpack_require__(1); | |
var util = __webpack_require__(2); | |
function Either(left, right) { | |
switch (arguments.length) { | |
case 0: | |
throw new TypeError('no arguments to Either'); | |
case 1: | |
return function(right) { | |
return right == null ? Either.Left(left) : Either.Right(right); | |
}; | |
default: | |
return right == null ? Either.Left(left) : Either.Right(right); | |
} | |
} | |
Either.prototype.map = util.returnThis; | |
Either.of = Either.prototype.of = function(value) { | |
return Either.Right(value); | |
}; | |
Either.prototype.chain = util.returnThis; // throw? | |
Either.equals = Either.prototype.equals = util.getEquals(Either); | |
// Right | |
function _Right(x) { | |
this.value = x; | |
} | |
util.extend(_Right, Either); | |
_Right.prototype.map = function(fn) { | |
return new _Right(fn(this.value)); | |
}; | |
_Right.prototype.ap = function(that) { | |
return that.map(this.value); | |
}; | |
_Right.prototype.chain = function(f) { | |
return f(this.value); | |
}; | |
_Right.prototype.bimap = function(_, f) { | |
return new _Right(f(this.value)); | |
}; | |
_Right.prototype.extend = function(f) { | |
return new _Right(f(this)); | |
}; | |
_Right.prototype.toString = function() { | |
return 'Either.Right(' + R.toString(this.value) + ')'; | |
}; | |
Either.Right = function(value) { | |
return new _Right(value); | |
}; | |
// Left | |
function _Left(x) { | |
this.value = x; | |
} | |
util.extend(_Left, Either); | |
_Left.prototype.ap = function(that) { return that; }; | |
_Left.prototype.bimap = function(f) { | |
return new _Left(f(this.value)); | |
}; | |
_Left.prototype.extend = util.returnThis; | |
_Left.prototype.toString = function() { | |
return 'Either.Left(' + R.toString(this.value) + ')'; | |
}; | |
Either.Left = function(value) { | |
return new _Left(value); | |
}; | |
module.exports = Either; | |
/***/ }, | |
/* 4 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var R = __webpack_require__(1); | |
// `f` is a function that takes two function arguments: `reject` (failure) and `resolve` (success) | |
function Future(f) { | |
if (!(this instanceof Future)) { | |
return new Future(f); | |
} | |
this.fork = f; | |
} | |
// functor | |
Future.prototype.map = function(f) { | |
return this.chain(function(a) { return Future.of(f(a)); }); | |
}; | |
// apply | |
Future.prototype.ap = function(m) { | |
var self = this; | |
return new Future(function(rej, res) { | |
var applyFn, val; | |
var doReject = R.once(rej); | |
function resolveIfDone() { | |
if (applyFn != null && val != null) { | |
return res(applyFn(val)); | |
} | |
} | |
self.fork(doReject, function(fn) { | |
applyFn = fn; | |
resolveIfDone(); | |
}); | |
m.fork(doReject, function(v) { | |
val = v; | |
resolveIfDone(); | |
}); | |
}); | |
}; | |
// applicative | |
Future.of = function(x) { | |
// should include a default rejection? | |
return new Future(function(_, resolve) { return resolve(x); }); | |
}; | |
Future.prototype.of = Future.of; | |
// chain | |
// f must be a function which returns a value | |
// f must return a value of the same Chain | |
// chain must return a value of the same Chain | |
Future.prototype.chain = function(f) { // Sorella's: | |
return new Future(function(reject, resolve) { | |
return this.fork(function(a) { return reject(a); }, | |
function(b) { return f(b).fork(reject, resolve); }); | |
}.bind(this)); | |
}; | |
// monad | |
// A value that implements the Monad specification must also implement the Applicative and Chain specifications. | |
// see above. | |
Future.prototype.bimap = function(errFn, successFn) { | |
var self = this; | |
return new Future(function(reject, resolve) { | |
self.fork(function(err) { | |
reject(errFn(err)); | |
}, function(val) { | |
resolve(successFn(val)); | |
}); | |
}); | |
}; | |
Future.reject = function(val) { | |
return new Future(function(reject) { | |
reject(val); | |
}); | |
}; | |
Future.prototype.toString = function() { | |
return 'Future(' + R.toString(this.fork) + ')'; | |
}; | |
module.exports = Future; | |
/***/ }, | |
/* 5 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var R = __webpack_require__(1); | |
module.exports = IO; | |
var compose = R.compose; | |
function IO(fn) { | |
if (!(this instanceof IO)) { | |
return new IO(fn); | |
} | |
this.fn = fn; | |
} | |
// `f` must return an IO | |
IO.prototype.chain = function(f) { | |
var io = this; | |
return new IO(function() { | |
return f(io.fn()).fn(); | |
}); | |
}; | |
IO.prototype.map = function(f) { | |
var io = this; | |
return new IO(compose(f, io.fn)); | |
}; | |
// `this` IO must wrap a function `f` that takes an IO (`thatIo`) as input | |
// `f` must return an IO | |
IO.prototype.ap = function(thatIo) { | |
return this.chain(function(f) { | |
return thatIo.map(f); | |
}); | |
}; | |
IO.runIO = function(io) { | |
return io.runIO.apply(io, [].slice.call(arguments, 1)); | |
}; | |
IO.prototype.runIO = function() { | |
return this.fn.apply(this, arguments); | |
}; | |
IO.prototype.of = function(x) { | |
return new IO(function() { return x; }); | |
}; | |
IO.of = IO.prototype.of; | |
// this is really only to accommodate testing .... | |
IO.prototype.equals = function(that) { | |
return this === that || | |
this.fn === that.fn || | |
R.equals(IO.runIO(this), IO.runIO(that)); | |
}; | |
IO.prototype.toString = function() { | |
return 'IO(' + R.toString(this.fn) + ')'; | |
}; | |
/***/ }, | |
/* 6 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var R = __webpack_require__(1); | |
var util = __webpack_require__(2); | |
/** | |
* A data type that holds a value and exposes a monadic api. | |
*/ | |
/** | |
* Constructs a new `Identity[a]` data type that holds a single | |
* value `a`. | |
* @param {*} a Value of any type | |
* @sig a -> Identity[a] | |
*/ | |
function Identity(x) { | |
if (!(this instanceof Identity)) { | |
return new Identity(x); | |
} | |
this.value = x; | |
} | |
/** | |
* Applicative specification. Creates a new `Identity[a]` holding the value `a`. | |
* @param {*} a Value of any type | |
* @returns Identity[a] | |
* @sig a -> Identity[a] | |
*/ | |
Identity.of = function(x) { | |
return new Identity(x); | |
}; | |
Identity.prototype.of = Identity.of; | |
/** | |
* Functor specification. Creates a new `Identity[a]` mapping function `f` onto | |
* `a` returning any value b. | |
* @param {Function} f Maps `a` to any value `b` | |
* @returns Identity[b] | |
* @sig @Identity[a] => (a -> b) -> Identity[b] | |
*/ | |
Identity.prototype.map = function(f) { | |
return new Identity(f(this.value)); | |
}; | |
/** | |
* Apply specification. Applies the function inside the `Identity[a]` | |
* type to another applicative type. | |
* @param {Applicative[a]} app Applicative that will apply its function | |
* @returns Applicative[b] | |
* @sig (Identity[a -> b], f: Applicative[_]) => f[a] -> f[b] | |
*/ | |
Identity.prototype.ap = function(app) { | |
return app.map(this.value); | |
}; | |
/** | |
* Chain specification. Transforms the value of the `Identity[a]` | |
* type using an unary function to monads. The `Identity[a]` type | |
* should contain a function, otherwise an error is thrown. | |
* | |
* @param {Function} fn Transforms `a` into a `Monad[b]` | |
* @returns Monad[b] | |
* @sig (Identity[a], m: Monad[_]) => (a -> m[b]) -> m[b] | |
*/ | |
Identity.prototype.chain = function(fn) { | |
return fn(this.value); | |
}; | |
/** | |
* Returns the value of `Identity[a]` | |
* | |
* @returns a | |
* @sig (Identity[a]) => a | |
*/ | |
Identity.prototype.get = function() { | |
return this.value; | |
}; | |
// equality method to enable testing | |
Identity.prototype.equals = util.getEquals(Identity); | |
Identity.prototype.toString = function() { | |
return 'Identity(' + R.toString(this.value) + ')'; | |
}; | |
module.exports = Identity; | |
/***/ }, | |
/* 7 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var R = __webpack_require__(1); | |
var util = __webpack_require__(2); | |
function Maybe(x) { | |
return x == null ? _nothing : Maybe.Just(x); | |
} | |
function _Just(x) { | |
this.value = x; | |
} | |
util.extend(_Just, Maybe); | |
function _Nothing() {} | |
util.extend(_Nothing, Maybe); | |
var _nothing = new _Nothing(); | |
Maybe.Nothing = function() { | |
return _nothing; | |
}; | |
Maybe.Just = function(x) { | |
return new _Just(x); | |
}; | |
Maybe.of = Maybe.Just; | |
Maybe.prototype.of = Maybe.Just; | |
Maybe.isJust = function(x) { | |
return x instanceof _Just; | |
}; | |
Maybe.isNothing = function(x) { | |
return x === _nothing; | |
}; | |
// functor | |
_Just.prototype.map = function(f) { | |
return this.of(f(this.value)); | |
}; | |
_Nothing.prototype.map = util.returnThis; | |
// apply | |
// takes a Maybe that wraps a function (`app`) and applies its `map` | |
// method to this Maybe's value, which must be a function. | |
_Just.prototype.ap = function(m) { | |
return m.map(this.value); | |
}; | |
_Nothing.prototype.ap = util.returnThis; | |
// applicative | |
// `of` inherited from `Maybe` | |
// chain | |
// f must be a function which returns a value | |
// f must return a value of the same Chain | |
// chain must return a value of the same Chain | |
_Just.prototype.chain = util.baseMap; | |
_Nothing.prototype.chain = util.returnThis; | |
// | |
_Just.prototype.datatype = _Just; | |
_Nothing.prototype.datatype = _Nothing; | |
// monad | |
// A value that implements the Monad specification must also implement the Applicative and Chain specifications. | |
// see above. | |
// equality method to enable testing | |
_Just.prototype.equals = util.getEquals(_Just); | |
_Nothing.prototype.equals = function(that) { | |
return that === _nothing; | |
}; | |
Maybe.prototype.isNothing = function() { | |
return this === _nothing; | |
}; | |
Maybe.prototype.isJust = function() { | |
return this instanceof _Just; | |
}; | |
_Just.prototype.getOrElse = function() { | |
return this.value; | |
}; | |
_Nothing.prototype.getOrElse = function(a) { | |
return a; | |
}; | |
_Just.prototype.toString = function() { | |
return 'Maybe.Just(' + R.toString(this.value) + ')'; | |
}; | |
_Nothing.prototype.toString = function() { | |
return 'Maybe.Nothing()'; | |
}; | |
module.exports = Maybe; | |
/***/ }, | |
/* 8 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var R = __webpack_require__(1); | |
function Reader(run) { | |
if (!(this instanceof Reader)) { | |
return new Reader(run); | |
} | |
this.run = run; | |
} | |
Reader.run = function(reader) { | |
return reader.run.apply(reader, [].slice.call(arguments, 1)); | |
}; | |
Reader.prototype.chain = function(f) { | |
var reader = this; | |
return new Reader(function(r) { | |
return f(reader.run(r)).run(r); | |
}); | |
}; | |
Reader.prototype.ap = function(a) { | |
return this.chain(function(f) { | |
return a.map(f); | |
}); | |
}; | |
Reader.prototype.map = function(f) { | |
return this.chain(function(a) { | |
return Reader.of(f(a)); | |
}); | |
}; | |
Reader.prototype.of = function(a) { | |
return new Reader(function() { | |
return a; | |
}); | |
}; | |
Reader.of = Reader.prototype.of; | |
Reader.ask = Reader(function(a) { | |
return a; | |
}); | |
Reader.prototype.equals = function(that) { | |
return this === that || | |
this.run === that.run || | |
R.equals(Reader.run(this), Reader.run(that)); | |
}; | |
Reader.prototype.toString = function() { | |
return 'Reader(' + R.toString(this.run) + ')'; | |
}; | |
module.exports = Reader; | |
/***/ }, | |
/* 9 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var R = __webpack_require__(1); | |
function Tuple(x, y) { | |
switch (arguments.length) { | |
case 0: | |
throw new TypeError('no arguments to Tuple'); | |
case 1: | |
return function(y) { | |
return new _Tuple(x, y); | |
}; | |
default: | |
return new _Tuple(x, y); | |
} | |
} | |
function _Tuple(x, y) { | |
this[0] = x; | |
this[1] = y; | |
this.length = 2; | |
} | |
function ensureConcat(xs) { | |
xs.forEach(function(x) { | |
if (typeof x.concat != 'function') { | |
throw new TypeError(R.toString(x) + ' must be a semigroup to perform this operation'); | |
} | |
}); | |
} | |
Tuple.of = function(x) { | |
return Tuple(x, x); | |
}; | |
Tuple.fst = function(x) { | |
return x[0]; | |
}; | |
Tuple.snd = function(x) { | |
return x[1]; | |
}; | |
_Tuple.prototype.of = function(x) { | |
return Tuple(this[0], x); | |
}; | |
// semigroup | |
_Tuple.prototype.concat = function(x) { | |
ensureConcat([this[0], this[1]]); | |
return Tuple(this[0].concat(x[0]), this[1].concat(x[1])); | |
}; | |
// functor | |
_Tuple.prototype.map = function(f) { | |
return Tuple(this[0], f(this[1])); | |
}; | |
// apply | |
_Tuple.prototype.ap = function(m) { | |
ensureConcat([this[0]]); | |
return Tuple(this[0].concat(m[0]), this[1](m[1])); | |
}; | |
// setoid | |
_Tuple.prototype.equals = function(that) { | |
return that instanceof _Tuple && R.equals(this[0], that[0]) && R.equals(this[1], that[1]); | |
}; | |
_Tuple.prototype.toString = function() { | |
return 'Tuple(' + R.toString(this[0]) + ', ' + R.toString(this[1]) + ')'; | |
}; | |
module.exports = Tuple; | |
/***/ }, | |
/* 10 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var R = __webpack_require__(1); | |
module.exports = R.curryN(3, function liftA2(f, a1, a2) { | |
return a1.map(f).ap(a2); | |
}); | |
/***/ }, | |
/* 11 */ | |
/***/ function(module, exports, __webpack_require__) { | |
var R = __webpack_require__(1); | |
module.exports = R.curryN(4, function liftA2(f, a1, a2, a3) { | |
return a1.map(f).ap(a2).ap(a3); | |
}); | |
/***/ } | |
/******/ ]) | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment