/* // // # The Witch in the Glass // // My mother says I must not pass // Too near that glass; // She is afraid that I will see // A little witch that looks like me, // With a red, red mouth to whisper low // The very thing I should not know! // // Alack for all your mother's care! // A bird of the air, // A wistful wind, or (I suppose // Sent by some hapless boy) a rose, // With breath too sweet, will whisper low // The very thing you should not know! // // - Sarah Morgan Bryan Piatt // */ // b is for useful stuff // curry: Converts a function to its curried form, allowing for partial application. // pipe: Runs functions from left to right, passing the result of one to the next. // compose: Runs functions from right to left, passing the result of one to the next. // identity: Returns whatever you give it as is. Useful for composition...sometimes. // match: Creates a curried function to match a regular expression in a string. // replace: Creates a curried function to replace parts of a string, based on a regex or substring. // filter: Curried array filtering by a predicate function. // map: Curried array mapping. // deepMap: Curried recursive mapping for nested arrays or matrices, of any shape. 'use strict' const b = { /** * Converts a function into a curried function, allowing for partial application. * A curried function can be partially applied and will return a new function until all arguments are provided. * @param {Function} fn - The function to curry. * @returns {Function} - The curried function. */ curry: function (fn) { const curried = (...args) => { if (args.length >= fn.length) return fn(...args) else return (...rest) => curried(...args, ...rest) } return curried }, /** * Composes functions from left to right. * Takes any number of functions as arguments and returns a function that applies them in sequence to a supplied value. * @param {...Function} fns - The functions to be composed. * @returns {Function} - A function that takes an initial value and applies the composed functions from left to right. */ pipe: (...fns) => (value) => fns.reduce((acc, fn) => fn(acc), value), /** * Composes functions from right to left. * Takes any number of functions as arguments and returns a function that applies them in sequence from right to left. * @param {...Function} fns - The functions to be composed. * @returns {Function} - A function that applies the composed functions from right to left. */ compose: (...fns) => (...args) => fns.reduceRight((res, fn) => fn(...[].concat(res)), args), /** * A function that returns its input totally and completely unchanged. * @param {*} x - The input value. * @returns {*} - The same input value. */ identity: x => x, /** * Curried function that matches a regular expression against a string. * @returns {Function} - A curried function that takes a regex and a string and returns the match result. */ match: function () { return this.curry((what, s) => s.match(what)); }, /** * Curried function that replaces parts of a string based on a regex or substring. * @returns {Function} - A curried function that takes a regex or substring, a replacement, and a string, and returns the replaced string. */ replace: function () { return this.curry((what, replacement, s) => s.replace(what, replacement)); }, /** * Curried function that filters an array based on a predicate function. * @returns {Function} - A curried function that takes a predicate function and an array, and returns the filtered array. */ filter: function () { return this.curry((f, xs) => xs.filter(f)); }, /** * Curried function that maps a function over an array. * @returns {Function} - A curried function that takes a mapping function and an array, and returns the mapped array. */ map: function () { return this.curry((f, xs) => xs.map(f)); }, /** * Curried function that recursively maps a function over an array or matrix of any shape. * @returns {Function} - A curried function that takes a mapping function and a nested array, and returns the deeply mapped array. */ deepMap: function () { return this.curry(function deepMap(f, xs) { return Array.isArray(xs) ? xs.map((x) => deepMap(f, x)) : f(xs); }); }, }; if (typeof module !== 'undefined' && module.exports) { module.exports = b; }