const compose = (...fns) => arg => fns.reduceRight((value, fn) => fn(value), arg)
const curry = (fn, ...partials) => (...args) => {
const params = [...partials, ...args]
return params.length >= fn.length ?
fn(...params) :
curry(fn, ...params)
}
// Examples
const point = (x, y) => [x, y]
const addPoint = curry((pointA, pointB) => [pointA[0] + pointB[0], pointA[1] + pointB[1]])
const pivot = point(0, 0)
const moveXFive = addPoint(point(5, 0))
const moveYFive = addPoint(point(0, 5))
const walkFive = compose(moveXFive, moveYFive)
const walkTen = compose(walkFive, walkFive)
console.log(walkTen(point(3, 6)))
// Functor
class Point2D {
constructor(x, y) {
this.__value = [x, y]
}
map(fn) {
return fn(this.__value)
}
}
// All purpose
const add = curry((x, y) => x + y)
const map = fn => value => fn(value)
// const join = curry((glue, prefix, suffix) => add(suffix, add(prefix, glue))
const join = curry((glue, prefix, suffix) => prefix + glue + suffix)
const placar = (a, b) => join(' X ', a, b)
const score = curry((time, gols) => add(time, add(' ', gols)))
const vasco = score('Vasco')
const flamengo = score('Flamengo')
console.log(placar(vasco(5), flamengo(1)))
// String Functions
const replace = curry((pattern, newValue, oldValue) => oldValue.replace(pattern, newValue))
const replaceWords = replace(/\w+/ig)
const replaceSpaces = replace(/\s+/ig)
const toLowerCase = value => value.toLowerCase()
const toUpperCase = value => value.toUpperCase()
const lowerFirst = value => toLowerCase(value.charAt(0)) + value.substring(1)
const upperFirst = value => toUpperCase(value.charAt(0)) + value.substring(1)
const removeSpaces = replaceSpaces('')
const upperWords = replaceWords(toUpperCase)
const lowerWords = replaceWords(toLowerCase)
const camelCase = compose(lowerFirst, removeSpaces, replaceWords(upperFirst), toLowerCase)
console.log(camelCase('VINICIUS de castro vinhas'))
const spaceToUnderscore = replaceSpaces('_')
const snakeCase = compose(toLowerCase, spaceToUnderscore)
console.log(snakeCase('My personal toolbelt'))