pure functions
define
1. same input, same output.
2. there will be no side effects during execution.
const letters = ['a', 'b', 'c'];
// pure function
letters.slice(1);
console.log(letters); // [ 'a', 'b', 'c' ]
// produce side effects, impure functions
letters.splice(1);
console.log(letters); // [ 'a' ]
currieization
defining a function that passes
only a subset of the arguments to the function and returns a function that receives the remaining arguments is curriization
let the function have a single responsibility
function add(x, y, z) {
x = x + 2;
y = y * 2;
z = z * z;
return x + y + z;
}
console.log(add(10, 20, 30));
// Currying
function sum(x) {
x = x + 2;
return function (y) {
y = y * 2;
return function (z) {
z = z * z;
return x + y + z;
};
};
}
console.log(sum(10)(20)(30));
reuse of code
const makeAdder = count => {
return num => {
return count + num;
};
};
const adder5 = makeAdder(5);
console.log(adder5(10)); // 15
console.log(adder5(20)); // 25
implementation of the currie-ization function
// Takes a function and returns a curried function
function myCurrying(fn) {
function curried(...args) {
// When the incoming parameters are less than the original function parameters
if (args.length < fn.length) {
// Returns a function to handle the remaining arguments
return function (...args2) {
// Remaining parameters, splicing existing parameters for recursion
return curried.apply(this, args.concat(args2));
};
} else {
// Call directly and bind this
return fn.apply(this, args);
}
}
return curried;
}
function add(num1, num2, num3) {
console.log(this);
return num1 + num2 + num3;
}
const newFn = myCurrying(add);
console.log(newFn.call('abc', 10, 20, 30));
console.log(newFn(10, 20)(30));
console.log(newFn(10)(20)(30));
combinatorial functions
definition multiple
functions need to be executed sequentially. combining these functions and executing them in turn is a combination of functions.
function double(num) {
return num * 2;
}
function square(num) {
return num ** 2;
}
// Suppose you need to execute double first
const res = square(double(10));
console.log(res);
// Simple implementation of composition function
function composeFn(fn1, fn2) {
return function (count) {
return fn2(fn1(count));
};
}
const newFn = composeFn(double, square);
const res2 = newFn(20);
console.log(res2);
implementation of a universal combinatorial function
function add(num1, num2) {
console.log(this);
return num1 + num2;
}
function double(num) {
console.log(this);
return num * 2;
}
function square(num) {
console.log(this);
return num ** 2;
}
// Generic composition function implementation
function myCompose(...fns) {
if (!fns.length) {
throw new TypeError('The function type must be passed in');
}
for (let fn of fns) {
if (typeof fn !== 'function') {
throw new TypeError('The function type must be passed in');
}
}
// Returns a function that is automatically executed sequentially
function composeFn(...args) {
// do it once
let index = 0;
let res = fns[index].apply(this, args);
// Get the previous result and call the next function to get the new result
while (++index < fns.length) {
res = fns[index].call(this, res);
}
return res;
}
return composeFn;
}
const newFn = myCompose(add, double, square);
const res = newFn.call('call', 10, 20);
console.log(res);