Created
October 14, 2019 19:08
-
-
Save BretCameron/0630bbdc332ed128de6c702efea47ccc to your computer and use it in GitHub Desktop.
An example of functional programming in JavaScript, featuring compose, pipe, tap and trace functions
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
/** | |
* Performs right-to-left composition, combining multiple functions into a single function. | |
* @function compose | |
* @param {...Function} args | |
* @returns {Function} | |
*/ | |
const compose = (...fns) => x => fns.reduceRight((output, fn) => fn(output), x, fns); | |
/** | |
* Performs left-to-right composition, combining multiple functions into a single function. Sometimes called `sequence`. Right-to-left composition is typically known as `compose`. | |
* @function pipe | |
* @param {...Function} args | |
* @returns {Function} | |
*/ | |
const pipe = (...fns) => x => fns.reduce((output, fn) => fn(output), x); | |
/** Runs the given function with the supplied object, then returns the object. | |
* @function tap | |
* @param {Function} f | |
* @returns {*} | |
*/ | |
const tap = f => x => { | |
f(x); | |
return x; | |
}; | |
/** Logs the given label and a provided object to the console, the returns the object. | |
* @function trace | |
* @param {String} label | |
* @returns {Function} | |
*/ | |
const trace = label => tap(console.log.bind(console, label + ':' || '')); | |
/** | |
* Divides a number by 100. | |
* @function divideBy100 | |
* @param {Number} num | |
* @returns {Number} | |
*/ | |
const divideBy100 = num => num / 100; | |
/** | |
* Returns a number to 2 decimal places. | |
* @function roundTo2dp | |
* @param {Number} num | |
* @returns {String} | |
*/ | |
const roundTo2dp = num => num.toFixed(2); | |
/** | |
* Adds a dollar sign in front of a number or string. | |
* @function addDollarSign | |
* @param {Number|String} str | |
* @returns {String} | |
*/ | |
const addDollarSign = str => '$' + String(str); | |
/** | |
* Add commas every three digits. | |
* @function addSeparators | |
* @param {Number|String} str | |
* @returns {String} | |
*/ | |
const addSeparators = str => { | |
// Insert commas before the decimal point | |
str = str.replace(/(?<!\.\d+)\B(?=(\d{3})+\b)/g, `,`); | |
// Insert commas after the decimal point | |
str = str.replace(/(?<=\.(\d{3})+)\B/g, `,`); | |
return str; | |
} | |
/** | |
* Convert cents to dollars. | |
* @function centsToDollars | |
* @param {Number} num - The value in cents. | |
* @returns {String} - The value in dollars, with a currency symbol and separators. | |
*/ | |
const centsToDollars = compose( | |
trace('addSeparators'), | |
addSeparators, | |
trace('addDollarSign'), | |
addDollarSign, | |
trace('roundTo2dp'), | |
roundTo2dp, | |
trace('divideBy100'), | |
divideBy100, | |
trace('argument'), | |
); | |
centsToDollars(100000000); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment