A Cookbook for writing FP in JavaScript using ES6
Translations
Returns the same result given same parameters. It's execution doesn't depend on the state of the system.
- Impure
let number = 1;
const increment = () => number += 1;
increment();
// 2
- Pure
const increment = n => n + 1;
increment(1);
// 2
Functions that operate on other functions, either by taking them as arguments or by returning them.
- Sum
const sum = (x, y) => x + y;
const calculate = (fn, x, y) => fn(x, y);
calculate(sum, 1, 2);
// 3
- Filter
let students = [
{name: 'Anna', grade: 6},
{name: 'John', grade: 4},
{name: 'Maria', grade: 9}
];
const isApproved = student => student.grade >= 6;
students.filter(isApproved);
// [ { name: 'Anna', grade: 6 }, { name: 'Maria', grade: 9 } ]
- Map
const byName = obj => obj.name;
students.map(byName);
// [ 'Anna', 'John', 'Maria' ]
- Chaining
let students = [
{name: 'Anna', grade: 6},
{name: 'John', grade: 4},
{name: 'Maria', grade: 9}
];
const isApproved = student => student.grade >= 6;
const byName = obj => obj.name;
students.filter(isApproved).map(byName);
// ['Anna', 'Maria']
- Reduce
const totalGrades = students.reduce((sum, student) => sum + student.grade, 0);
totalGrades
// 19
Whenever a function calls itself, creating a loop.
- Countdown
const countdown = num => {
console.log(num)
num < 1
? num
: countdown(num - 1)
}
countdown(5);
/*
5
4
3
2
1
0
*/
- Factorial
const factorial = (num) =>
num <= 0
? 1
: n * factorial(num - 1)
factorial(5);
//120
An object that has a map method. The map method of the functor takes it’s own contents and transforms each of them using the transformation callback passed to map, and returns a new functor, which contains the structure as the first functor, but with the transformed values.
- Adding a value to all the elements in a array
const plus1 = num => num + 1;
let numbers = [1, 2, 3];
numbers.map(plus1);
// [2, 3, 4]
The composition of two or more functions returns a new function.
- Combining two functions to generate another one
const compose = (f,g) => x => f(g(x));
const toUpperCase = x => x.toUpperCase();
const exclaim = x => `${x}!`;
const angry = compose(exclaim, toUpperCase);
angry("stop this");
// STOP THIS!
- Combining three functions to generate another one
const compose = (f,g) => x => f(g(x));
const toUpperCase = x => x.toUpperCase();
const exclaim = x => `${x}!`;
const moreExclaim = x => `${x}!!!!!`;
const reallyAngry = compose(exclaim, compose(toUpperCase, moreExclaim));
reallyAngry("stop this");
// STOP THIS!!!!!!
Extract data from arrays or objects using a syntax that mirrors the construction of array and object literals. Or "Pattern Matching".
- Select from pattern
const foo = () => [1, 2, 3];
const [a, b] = foo();
console.log(a, b);
// 1 2
- Accumulates the rest values
const [a, ...b] = [1, 2, 3];
console.log(a, b);
// 1 [2, 3]
- Optional parameters
const ajax = ({ url = "localhost", port: p = 80}, ...data) =>
console.log("Url:", url, "Port:", p, "Rest:", data);
ajax({ url: "someHost" }, "additional", "data", "hello");
// Url: someHost Port: 80 Rest: [ 'additional', 'data', 'hello' ]
ajax({ }, "additional", "data", "hello");
// Url: localhost Port: 80 Rest: [ 'additional', 'data', 'hello' ]
Taking a function that takes multiple arguments and turning it into a chain of functions each taking one argument and returning the next function, until the last returns the result.
- Currying an Object
const student = name => grade => `Name: ${name} | Grade: ${grade}`;
student("Matt")(8);
// Name: Matt | Grade: 8
- Currying a Sum
const add = x => y => x + y;
const increment = add(1);
const addFive = add(5);
increment(3);
//4
addFive(10);
// 15