first commit
This commit is contained in:
169
javascript/examples/1_4_functions-hi.js
Normal file
169
javascript/examples/1_4_functions-hi.js
Normal file
@@ -0,0 +1,169 @@
|
||||
"use strict"; 4
|
||||
|
||||
chapter("Hi-order functions");
|
||||
section("Minimum by absolute value");
|
||||
|
||||
let minimumByAbs = function(...args) {
|
||||
let result = Infinity;
|
||||
for (const arg of args) {
|
||||
if (Math.abs(result) > Math.abs(arg)) {
|
||||
result = arg;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
println("minimumByAbs =", minimumByAbs);
|
||||
example("minimumByAbs(1, -2, 3)");
|
||||
|
||||
|
||||
section("Unify minimum and minimumByAbs");
|
||||
|
||||
subsection("High-order functions");
|
||||
function minimumBy(comparator, init = Infinity) {
|
||||
return (...args) => {
|
||||
let result = init;
|
||||
for (const arg of args) {
|
||||
if (comparator(result, arg) > 0) {
|
||||
result = arg;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
println(minimumBy);
|
||||
|
||||
function comparing(f) {
|
||||
return (a, b) => f(a) - f(b);
|
||||
}
|
||||
println(comparing);
|
||||
|
||||
const identity = a => a;
|
||||
println("const identity =", identity);
|
||||
|
||||
function maximumBy(comparator, init = -Infinity) {
|
||||
return minimumBy((a, b) => -comparator(a, b), init);
|
||||
}
|
||||
println(maximumBy);
|
||||
|
||||
|
||||
subsection("Definitions");
|
||||
|
||||
let minimumByV = minimumBy(comparing(identity));
|
||||
minimumByAbs = minimumBy(comparing(Math.abs));
|
||||
let maximumByLength = maximumBy(comparing(s => s.length), "");
|
||||
|
||||
example("minimumByV");
|
||||
example("minimumByAbs");
|
||||
example("maximumByLength");
|
||||
example("minimumByV(1, -2, 3)");
|
||||
example("minimumByAbs(1, -2, 3)");
|
||||
example("maximumByLength('aa', 'bbb', 'c')");
|
||||
|
||||
|
||||
section("Unify minimumBy and sum");
|
||||
|
||||
subsection("High-order functions");
|
||||
function foldLeft(f, zero) {
|
||||
return (...args) => {
|
||||
let result = zero;
|
||||
for (const arg of args) {
|
||||
result = f(result, arg);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
println(foldLeft);
|
||||
|
||||
function minBy(f) {
|
||||
return (a, b) => f(a) < f(b) ? a : b;
|
||||
}
|
||||
println(minBy);
|
||||
|
||||
subsection("Definitions");
|
||||
const sum2 = foldLeft((a, b) => a + b, 0);
|
||||
const product = foldLeft((a, b) => a * b, 1);
|
||||
minimumByAbs = foldLeft(minBy(comparing(Math.abs)), Infinity);
|
||||
example("sum2(1, -2, 3)");
|
||||
example("product(1, -2, 3)");
|
||||
example("minimumByAbs(1, -2, 3)");
|
||||
|
||||
|
||||
section("sumSquares and sumAbs");
|
||||
|
||||
let square = x => x * x;
|
||||
let sumSquares = foldLeft((a, b) => a + square(b), 0);
|
||||
let sumAbs = foldLeft((a, b) => a + Math.abs(b), 0);
|
||||
example("sumSquares(1, -2, 3)");
|
||||
example("sumAbs(1, -2, 3)");
|
||||
|
||||
|
||||
subsection("High-order functions");
|
||||
function map(f) {
|
||||
return (...args) => {
|
||||
const result = [];
|
||||
for (const arg of args) {
|
||||
result.push(f(arg));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
println(map);
|
||||
|
||||
function compose(f, g) {
|
||||
return (...args) => f(g(...args));
|
||||
}
|
||||
println(compose);
|
||||
|
||||
function unspread(f) {
|
||||
return args => f(...args);
|
||||
}
|
||||
println(unspread);
|
||||
|
||||
subsection("Definitions");
|
||||
sumSquares = compose(unspread(sum2), map(square));
|
||||
sumAbs = compose(unspread(sum2), map(Math.abs));
|
||||
example("sumSquares(1, -2, 3)");
|
||||
example("sumAbs(1, -2, 3)");
|
||||
|
||||
|
||||
section("diff");
|
||||
|
||||
let diff = dx => f => x => (f(x + dx) - f(x - dx)) / 2 / dx;
|
||||
|
||||
let dsin = diff(1e-7)(Math.sin);
|
||||
for (let i = 0; i < 10; i++) {
|
||||
println(i + " " + Math.cos(i) + " " + dsin(i) + " " + Math.abs(Math.cos(i) - dsin(i)));
|
||||
}
|
||||
|
||||
|
||||
section("Currying");
|
||||
subsection("curry");
|
||||
|
||||
const curry = f => a => b => f(a, b);
|
||||
|
||||
const addC = curry((a, b) => a + b);
|
||||
const add10 = addC(10);
|
||||
example("addC(10)(20)");
|
||||
example("add10(20)");
|
||||
|
||||
|
||||
subsection("uncurry");
|
||||
|
||||
const uncurry = f => (a, b) => f(a)(b);
|
||||
const addU = uncurry(a => b => a + b);
|
||||
example("addU(10, 20)");
|
||||
|
||||
|
||||
subsection("mCurry");
|
||||
|
||||
println("bind");
|
||||
let bind = (f, ...as) => (...args) => f(...[...as, ...args]);
|
||||
let add100 = bind((a, b) => a + b, 100);
|
||||
example(" add100(200)");
|
||||
|
||||
println("mCurry");
|
||||
let mCurry = curry(bind);
|
||||
let sub = mCurry((a, b, c) => a - b - c);
|
||||
let sub10 = sub(10);
|
||||
example(" sub(10)(20, 30)");
|
||||
example(" sub10(20, 30)");
|
||||
Reference in New Issue
Block a user