mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-12 14:18:31 +00:00
607 lines
16 KiB
JavaScript
607 lines
16 KiB
JavaScript
function _isPlaceholder(a) {
|
|
return a != null && typeof a === 'object' && a['@@functional/placeholder'] === true;
|
|
}
|
|
|
|
/**
|
|
* Optimized internal one-arity curry function.
|
|
*
|
|
* @private
|
|
* @category Function
|
|
* @param {Function} fn The function to curry.
|
|
* @return {Function} The curried function.
|
|
*/
|
|
|
|
function _curry1(fn) {
|
|
return function f1(a) {
|
|
if (arguments.length === 0 || _isPlaceholder(a)) {
|
|
return f1;
|
|
} else {
|
|
return fn.apply(this, arguments);
|
|
}
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Optimized internal two-arity curry function.
|
|
*
|
|
* @private
|
|
* @category Function
|
|
* @param {Function} fn The function to curry.
|
|
* @return {Function} The curried function.
|
|
*/
|
|
|
|
function _curry2(fn) {
|
|
return function f2(a, b) {
|
|
switch (arguments.length) {
|
|
case 0:
|
|
return f2;
|
|
|
|
case 1:
|
|
return _isPlaceholder(a) ? f2 : _curry1(function (_b) {
|
|
return fn(a, _b);
|
|
});
|
|
|
|
default:
|
|
return _isPlaceholder(a) && _isPlaceholder(b) ? f2 : _isPlaceholder(a) ? _curry1(function (_a) {
|
|
return fn(_a, b);
|
|
}) : _isPlaceholder(b) ? _curry1(function (_b) {
|
|
return fn(a, _b);
|
|
}) : fn(a, b);
|
|
}
|
|
};
|
|
}
|
|
|
|
function _arity(n, fn) {
|
|
/* eslint-disable no-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');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Optimized internal three-arity curry function.
|
|
*
|
|
* @private
|
|
* @category Function
|
|
* @param {Function} fn The function to curry.
|
|
* @return {Function} The curried function.
|
|
*/
|
|
|
|
function _curry3(fn) {
|
|
return function f3(a, b, c) {
|
|
switch (arguments.length) {
|
|
case 0:
|
|
return f3;
|
|
|
|
case 1:
|
|
return _isPlaceholder(a) ? f3 : _curry2(function (_b, _c) {
|
|
return fn(a, _b, _c);
|
|
});
|
|
|
|
case 2:
|
|
return _isPlaceholder(a) && _isPlaceholder(b) ? f3 : _isPlaceholder(a) ? _curry2(function (_a, _c) {
|
|
return fn(_a, b, _c);
|
|
}) : _isPlaceholder(b) ? _curry2(function (_b, _c) {
|
|
return fn(a, _b, _c);
|
|
}) : _curry1(function (_c) {
|
|
return fn(a, b, _c);
|
|
});
|
|
|
|
default:
|
|
return _isPlaceholder(a) && _isPlaceholder(b) && _isPlaceholder(c) ? f3 : _isPlaceholder(a) && _isPlaceholder(b) ? _curry2(function (_a, _b) {
|
|
return fn(_a, _b, c);
|
|
}) : _isPlaceholder(a) && _isPlaceholder(c) ? _curry2(function (_a, _c) {
|
|
return fn(_a, b, _c);
|
|
}) : _isPlaceholder(b) && _isPlaceholder(c) ? _curry2(function (_b, _c) {
|
|
return fn(a, _b, _c);
|
|
}) : _isPlaceholder(a) ? _curry1(function (_a) {
|
|
return fn(_a, b, c);
|
|
}) : _isPlaceholder(b) ? _curry1(function (_b) {
|
|
return fn(a, _b, c);
|
|
}) : _isPlaceholder(c) ? _curry1(function (_c) {
|
|
return fn(a, b, _c);
|
|
}) : fn(a, b, c);
|
|
}
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 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]';
|
|
};
|
|
|
|
function _isString(x) {
|
|
return Object.prototype.toString.call(x) === '[object String]';
|
|
}
|
|
|
|
/**
|
|
* Tests whether or not an object is similar to an array.
|
|
*
|
|
* @private
|
|
* @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
|
|
*
|
|
* _isArrayLike([]); //=> true
|
|
* _isArrayLike(true); //=> false
|
|
* _isArrayLike({}); //=> false
|
|
* _isArrayLike({length: 10}); //=> false
|
|
* _isArrayLike({0: 'zero', 9: 'nine', length: 10}); //=> true
|
|
* _isArrayLike({nodeType: 1, length: 1}) // => false
|
|
*/
|
|
|
|
var _isArrayLike =
|
|
/*#__PURE__*/
|
|
_curry1(function isArrayLike(x) {
|
|
if (_isArray(x)) {
|
|
return true;
|
|
}
|
|
|
|
if (!x) {
|
|
return false;
|
|
}
|
|
|
|
if (typeof x !== 'object') {
|
|
return false;
|
|
}
|
|
|
|
if (_isString(x)) {
|
|
return false;
|
|
}
|
|
|
|
if (x.length === 0) {
|
|
return true;
|
|
}
|
|
|
|
if (x.length > 0) {
|
|
return x.hasOwnProperty(0) && x.hasOwnProperty(x.length - 1);
|
|
}
|
|
|
|
return false;
|
|
});
|
|
|
|
var XWrap =
|
|
/*#__PURE__*/
|
|
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 XWrap;
|
|
}();
|
|
|
|
function _xwrap(fn) {
|
|
return new XWrap(fn);
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
* @since v0.6.0
|
|
* @category Function
|
|
* @category Object
|
|
* @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`.
|
|
* @see R.partial
|
|
* @example
|
|
*
|
|
* const log = R.bind(console.log, console);
|
|
* R.pipe(R.assoc('a', 2), R.tap(log), R.assoc('a', 3))({a: 1}); //=> {a: 3}
|
|
* // logs {a: 2}
|
|
* @symb R.bind(f, o)(a, b) = f.call(o, a, b)
|
|
*/
|
|
|
|
var bind =
|
|
/*#__PURE__*/
|
|
_curry2(function bind(fn, thisObj) {
|
|
return _arity(fn.length, function () {
|
|
return fn.apply(thisObj, arguments);
|
|
});
|
|
});
|
|
|
|
function _arrayReduce(xf, acc, list) {
|
|
var idx = 0;
|
|
var 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, methodName) {
|
|
return xf['@@transducer/result'](obj[methodName](bind(xf['@@transducer/step'], xf), acc));
|
|
}
|
|
|
|
var symIterator = typeof Symbol !== 'undefined' ? Symbol.iterator : '@@iterator';
|
|
function _reduce(fn, acc, list) {
|
|
if (typeof fn === 'function') {
|
|
fn = _xwrap(fn);
|
|
}
|
|
|
|
if (_isArrayLike(list)) {
|
|
return _arrayReduce(fn, acc, list);
|
|
}
|
|
|
|
if (typeof list['fantasy-land/reduce'] === 'function') {
|
|
return _methodReduce(fn, acc, list, 'fantasy-land/reduce');
|
|
}
|
|
|
|
if (list[symIterator] != null) {
|
|
return _iterableReduce(fn, acc, list[symIterator]());
|
|
}
|
|
|
|
if (typeof list.next === 'function') {
|
|
return _iterableReduce(fn, acc, list);
|
|
}
|
|
|
|
if (typeof list.reduce === 'function') {
|
|
return _methodReduce(fn, acc, list, 'reduce');
|
|
}
|
|
|
|
throw new TypeError('reduce: list must be array or iterable');
|
|
}
|
|
|
|
/**
|
|
* 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`](#reduced) to shortcut the iteration.
|
|
*
|
|
* The arguments' order of [`reduceRight`](#reduceRight)'s iterator function
|
|
* is *(value, acc)*.
|
|
*
|
|
* 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
|
|
*
|
|
* Dispatches to the `reduce` method of the third argument, if present. When
|
|
* doing so, it is up to the user to handle the [`R.reduced`](#reduced)
|
|
* shortcuting, as this is not implemented by `reduce`.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @since v0.1.0
|
|
* @category List
|
|
* @sig ((a, b) -> a) -> a -> [b] -> a
|
|
* @param {Function} fn The iterator function. Receives two values, the accumulator and the
|
|
* current element from the array.
|
|
* @param {*} acc The accumulator value.
|
|
* @param {Array} list The list to iterate over.
|
|
* @return {*} The final, accumulated value.
|
|
* @see R.reduced, R.addIndex, R.reduceRight
|
|
* @example
|
|
*
|
|
* R.reduce(R.subtract, 0, [1, 2, 3, 4]) // => ((((0 - 1) - 2) - 3) - 4) = -10
|
|
* // - -10
|
|
* // / \ / \
|
|
* // - 4 -6 4
|
|
* // / \ / \
|
|
* // - 3 ==> -3 3
|
|
* // / \ / \
|
|
* // - 2 -1 2
|
|
* // / \ / \
|
|
* // 0 1 0 1
|
|
*
|
|
* @symb R.reduce(f, a, [b, c, d]) = f(f(f(a, b), c), d)
|
|
*/
|
|
|
|
var reduce =
|
|
/*#__PURE__*/
|
|
_curry3(_reduce);
|
|
|
|
function _pipe(f, g) {
|
|
return function () {
|
|
return g.call(this, f.apply(this, arguments));
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 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 implementation
|
|
* @param {String} methodname property to check for a custom implementation
|
|
* @return {Object} Whatever the return value of the method is.
|
|
*/
|
|
|
|
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, Array.prototype.slice.call(arguments, 0, length - 1));
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Returns the elements of the given list or string (or object with a `slice`
|
|
* method) from `fromIndex` (inclusive) to `toIndex` (exclusive).
|
|
*
|
|
* Dispatches to the `slice` method of the third argument, if present.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @since v0.1.4
|
|
* @category List
|
|
* @sig Number -> Number -> [a] -> [a]
|
|
* @sig Number -> Number -> String -> String
|
|
* @param {Number} fromIndex The start index (inclusive).
|
|
* @param {Number} toIndex The end index (exclusive).
|
|
* @param {*} list
|
|
* @return {*}
|
|
* @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 =
|
|
/*#__PURE__*/
|
|
_curry3(
|
|
/*#__PURE__*/
|
|
_checkForMethod('slice', function slice(fromIndex, toIndex, list) {
|
|
return Array.prototype.slice.call(list, fromIndex, toIndex);
|
|
}));
|
|
|
|
/**
|
|
* Returns all but the first element of the given list or string (or object
|
|
* with a `tail` method).
|
|
*
|
|
* Dispatches to the `slice` method of the first argument, if present.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @since v0.1.0
|
|
* @category List
|
|
* @sig [a] -> [a]
|
|
* @sig String -> String
|
|
* @param {*} list
|
|
* @return {*}
|
|
* @see R.head, R.init, R.last
|
|
* @example
|
|
*
|
|
* R.tail([1, 2, 3]); //=> [2, 3]
|
|
* R.tail([1, 2]); //=> [2]
|
|
* R.tail([1]); //=> []
|
|
* R.tail([]); //=> []
|
|
*
|
|
* R.tail('abc'); //=> 'bc'
|
|
* R.tail('ab'); //=> 'b'
|
|
* R.tail('a'); //=> ''
|
|
* R.tail(''); //=> ''
|
|
*/
|
|
|
|
var tail =
|
|
/*#__PURE__*/
|
|
_curry1(
|
|
/*#__PURE__*/
|
|
_checkForMethod('tail',
|
|
/*#__PURE__*/
|
|
slice(1, Infinity)));
|
|
|
|
/**
|
|
* Performs left-to-right function composition. The first argument may have
|
|
* any arity; the remaining arguments must be unary.
|
|
*
|
|
* In some libraries this function is named `sequence`.
|
|
*
|
|
* **Note:** The result of pipe is not automatically curried.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @since v0.1.0
|
|
* @category Function
|
|
* @sig (((a, b, ..., n) -> o), (o -> p), ..., (x -> y), (y -> z)) -> ((a, b, ..., n) -> z)
|
|
* @param {...Function} functions
|
|
* @return {Function}
|
|
* @see R.compose
|
|
* @example
|
|
*
|
|
* const f = R.pipe(Math.pow, R.negate, R.inc);
|
|
*
|
|
* f(3, 4); // -(3^4) + 1
|
|
* @symb R.pipe(f, g, h)(a, b) = h(g(f(a, b)))
|
|
* @symb R.pipe(f, g, h)(a)(b) = h(g(f(a)))(b)
|
|
*/
|
|
|
|
function pipe() {
|
|
if (arguments.length === 0) {
|
|
throw new Error('pipe requires at least one argument');
|
|
}
|
|
|
|
return _arity(arguments[0].length, reduce(_pipe, arguments[0], tail(arguments)));
|
|
}
|
|
|
|
/**
|
|
* Returns a new list or string with the elements or characters in reverse
|
|
* order.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @since v0.1.0
|
|
* @category List
|
|
* @sig [a] -> [a]
|
|
* @sig String -> String
|
|
* @param {Array|String} list
|
|
* @return {Array|String}
|
|
* @example
|
|
*
|
|
* R.reverse([1, 2, 3]); //=> [3, 2, 1]
|
|
* R.reverse([1, 2]); //=> [2, 1]
|
|
* R.reverse([1]); //=> [1]
|
|
* R.reverse([]); //=> []
|
|
*
|
|
* R.reverse('abc'); //=> 'cba'
|
|
* R.reverse('ab'); //=> 'ba'
|
|
* R.reverse('a'); //=> 'a'
|
|
* R.reverse(''); //=> ''
|
|
*/
|
|
|
|
var reverse =
|
|
/*#__PURE__*/
|
|
_curry1(function reverse(list) {
|
|
return _isString(list) ? list.split('').reverse().join('') : Array.prototype.slice.call(list, 0).reverse();
|
|
});
|
|
|
|
/**
|
|
* Performs right-to-left function composition. The last argument may have
|
|
* any arity; the remaining arguments must be unary.
|
|
*
|
|
* **Note:** The result of compose is not automatically curried.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @since v0.1.0
|
|
* @category Function
|
|
* @sig ((y -> z), (x -> y), ..., (o -> p), ((a, b, ..., n) -> o)) -> ((a, b, ..., n) -> z)
|
|
* @param {...Function} ...functions The functions to compose
|
|
* @return {Function}
|
|
* @see R.pipe
|
|
* @example
|
|
*
|
|
* const classyGreeting = (firstName, lastName) => "The name's " + lastName + ", " + firstName + " " + lastName
|
|
* const yellGreeting = R.compose(R.toUpper, classyGreeting);
|
|
* yellGreeting('James', 'Bond'); //=> "THE NAME'S BOND, JAMES BOND"
|
|
*
|
|
* R.compose(Math.abs, R.add(1), R.multiply(2))(-4) //=> 7
|
|
*
|
|
* @symb R.compose(f, g, h)(a, b) = f(g(h(a, b)))
|
|
* @symb R.compose(f, g, h)(a)(b) = f(g(h(a)))(b)
|
|
*/
|
|
|
|
function compose() {
|
|
if (arguments.length === 0) {
|
|
throw new Error('compose requires at least one argument');
|
|
}
|
|
|
|
return pipe.apply(this, reverse(arguments));
|
|
}
|
|
|
|
export { compose };
|