@thi.ng/compose
Advanced tools
Comparing version 2.1.50 to 2.1.51
# Change Log | ||
- **Last updated**: 2023-12-09T19:12:03Z | ||
- **Last updated**: 2023-12-11T10:07:09Z | ||
- **Generator**: [thi.ng/monopub](https://thi.ng/monopub) | ||
@@ -5,0 +5,0 @@ |
70
comp.js
import { illegalArity } from "@thi.ng/errors/illegal-arity"; | ||
export function comp(...fns) { | ||
let [a, b, c, d, e, f, g, h, i, j] = fns; | ||
switch (fns.length) { | ||
case 0: | ||
illegalArity(0); | ||
case 1: | ||
return a; | ||
case 2: | ||
return (...xs) => a(b(...xs)); | ||
case 3: | ||
return (...xs) => a(b(c(...xs))); | ||
case 4: | ||
return (...xs) => a(b(c(d(...xs)))); | ||
case 5: | ||
return (...xs) => a(b(c(d(e(...xs))))); | ||
case 6: | ||
return (...xs) => a(b(c(d(e(f(...xs)))))); | ||
case 7: | ||
return (...xs) => a(b(c(d(e(f(g(...xs))))))); | ||
case 8: | ||
return (...xs) => a(b(c(d(e(f(g(h(...xs)))))))); | ||
case 9: | ||
return (...xs) => a(b(c(d(e(f(g(h(i(...xs))))))))); | ||
case 10: | ||
default: | ||
const fn = (...xs) => a(b(c(d(e(f(g(h(i(j(...xs)))))))))); | ||
return fns.length === 10 ? fn : comp(fn, ...fns.slice(10)); | ||
} | ||
function comp(...fns) { | ||
let [a, b, c, d, e, f, g, h, i, j] = fns; | ||
switch (fns.length) { | ||
case 0: | ||
illegalArity(0); | ||
case 1: | ||
return a; | ||
case 2: | ||
return (...xs) => a(b(...xs)); | ||
case 3: | ||
return (...xs) => a(b(c(...xs))); | ||
case 4: | ||
return (...xs) => a(b(c(d(...xs)))); | ||
case 5: | ||
return (...xs) => a(b(c(d(e(...xs))))); | ||
case 6: | ||
return (...xs) => a(b(c(d(e(f(...xs)))))); | ||
case 7: | ||
return (...xs) => a(b(c(d(e(f(g(...xs))))))); | ||
case 8: | ||
return (...xs) => a(b(c(d(e(f(g(h(...xs)))))))); | ||
case 9: | ||
return (...xs) => a(b(c(d(e(f(g(h(i(...xs))))))))); | ||
case 10: | ||
default: | ||
const fn = (...xs) => a(b(c(d(e(f(g(h(i(j(...xs)))))))))); | ||
return fns.length === 10 ? fn : comp(fn, ...fns.slice(10)); | ||
} | ||
} | ||
export function compL(...fns) { | ||
return comp.apply(null, fns.reverse()); | ||
function compL(...fns) { | ||
return comp.apply(null, fns.reverse()); | ||
} | ||
/** | ||
* @deprecated renamed to {@link compL} | ||
*/ | ||
export const compI = compL; | ||
const compI = compL; | ||
export { | ||
comp, | ||
compI, | ||
compL | ||
}; |
@@ -1,3 +0,6 @@ | ||
export function complement(f) { | ||
return (...xs) => !f(...xs); | ||
function complement(f) { | ||
return (...xs) => !f(...xs); | ||
} | ||
export { | ||
complement | ||
}; |
@@ -1,1 +0,4 @@ | ||
export const constantly = (x) => () => x; | ||
const constantly = (x) => () => x; | ||
export { | ||
constantly | ||
}; |
40
delay.js
@@ -1,20 +0,24 @@ | ||
export const delay = (body) => new Delay(body); | ||
export class Delay { | ||
value; | ||
body; | ||
realized; | ||
constructor(body) { | ||
this.body = body; | ||
this.realized = false; | ||
const delay = (body) => new Delay(body); | ||
class Delay { | ||
value; | ||
body; | ||
realized; | ||
constructor(body) { | ||
this.body = body; | ||
this.realized = false; | ||
} | ||
deref() { | ||
if (!this.realized) { | ||
this.value = this.body(); | ||
this.realized = true; | ||
} | ||
deref() { | ||
if (!this.realized) { | ||
this.value = this.body(); | ||
this.realized = true; | ||
} | ||
return this.value; | ||
} | ||
isRealized() { | ||
return this.realized; | ||
} | ||
return this.value; | ||
} | ||
isRealized() { | ||
return this.realized; | ||
} | ||
} | ||
export { | ||
Delay, | ||
delay | ||
}; |
@@ -1,1 +0,4 @@ | ||
export const delayed = (x, t) => new Promise((resolve) => setTimeout(() => resolve(x), t)); | ||
const delayed = (x, t) => new Promise((resolve) => setTimeout(() => resolve(x), t)); | ||
export { | ||
delayed | ||
}; |
@@ -1,6 +0,4 @@ | ||
/** | ||
* Same as eponymous function in thi.ng/api. Identity function: `(x) => x`. | ||
* | ||
* @param x | ||
*/ | ||
export const identity = (x) => x; | ||
const identity = (x) => x; | ||
export { | ||
identity | ||
}; |
11
ifdef.js
@@ -1,7 +0,4 @@ | ||
/** | ||
* Returns f(x) iff `x` is not null or undefined. | ||
* | ||
* @param f - function | ||
* @param x - value | ||
*/ | ||
export const ifDef = (f, x) => x != null ? f(x) : undefined; | ||
const ifDef = (f, x) => x != null ? f(x) : void 0; | ||
export { | ||
ifDef | ||
}; |
59
juxt.js
@@ -1,29 +0,32 @@ | ||
export function juxt(...fns) { | ||
const [a, b, c, d, e, f, g, h] = fns; | ||
switch (fns.length) { | ||
case 1: | ||
return (x) => [a(x)]; | ||
case 2: | ||
return (x) => [a(x), b(x)]; | ||
case 3: | ||
return (x) => [a(x), b(x), c(x)]; | ||
case 4: | ||
return (x) => [a(x), b(x), c(x), d(x)]; | ||
case 5: | ||
return (x) => [a(x), b(x), c(x), d(x), e(x)]; | ||
case 6: | ||
return (x) => [a(x), b(x), c(x), d(x), e(x), f(x)]; | ||
case 7: | ||
return (x) => [a(x), b(x), c(x), d(x), e(x), f(x), g(x)]; | ||
case 8: | ||
return (x) => [a(x), b(x), c(x), d(x), e(x), f(x), g(x), h(x)]; | ||
default: | ||
return (x) => { | ||
let res = new Array(fns.length); | ||
for (let i = fns.length; i-- > 0;) { | ||
res[i] = fns[i](x); | ||
} | ||
return res; | ||
}; | ||
} | ||
function juxt(...fns) { | ||
const [a, b, c, d, e, f, g, h] = fns; | ||
switch (fns.length) { | ||
case 1: | ||
return (x) => [a(x)]; | ||
case 2: | ||
return (x) => [a(x), b(x)]; | ||
case 3: | ||
return (x) => [a(x), b(x), c(x)]; | ||
case 4: | ||
return (x) => [a(x), b(x), c(x), d(x)]; | ||
case 5: | ||
return (x) => [a(x), b(x), c(x), d(x), e(x)]; | ||
case 6: | ||
return (x) => [a(x), b(x), c(x), d(x), e(x), f(x)]; | ||
case 7: | ||
return (x) => [a(x), b(x), c(x), d(x), e(x), f(x), g(x)]; | ||
case 8: | ||
return (x) => [a(x), b(x), c(x), d(x), e(x), f(x), g(x), h(x)]; | ||
default: | ||
return (x) => { | ||
let res = new Array(fns.length); | ||
for (let i = fns.length; i-- > 0; ) { | ||
res[i] = fns[i](x); | ||
} | ||
return res; | ||
}; | ||
} | ||
} | ||
export { | ||
juxt | ||
}; |
{ | ||
"name": "@thi.ng/compose", | ||
"version": "2.1.50", | ||
"version": "2.1.51", | ||
"description": "Optimized functional composition helpers", | ||
@@ -27,3 +27,5 @@ "type": "module", | ||
"scripts": { | ||
"build": "yarn clean && tsc --declaration", | ||
"build": "yarn build:esbuild && yarn build:decl", | ||
"build:decl": "tsc --declaration --emitDeclarationOnly", | ||
"build:esbuild": "esbuild --format=esm --platform=neutral --target=es2022 --tsconfig=tsconfig.json --outdir=. src/**/*.ts", | ||
"clean": "rimraf --glob '*.js' '*.d.ts' '*.map' doc", | ||
@@ -37,7 +39,8 @@ "doc": "typedoc --excludePrivate --excludeInternal --out doc src/index.ts", | ||
"dependencies": { | ||
"@thi.ng/api": "^8.9.11", | ||
"@thi.ng/errors": "^2.4.5" | ||
"@thi.ng/api": "^8.9.12", | ||
"@thi.ng/errors": "^2.4.6" | ||
}, | ||
"devDependencies": { | ||
"@microsoft/api-extractor": "^7.38.3", | ||
"esbuild": "^0.19.8", | ||
"rimraf": "^5.0.5", | ||
@@ -108,3 +111,3 @@ "tools": "^0.0.1", | ||
}, | ||
"gitHead": "25f2ac8ff795a432a930119661b364d4d93b59a0\n" | ||
"gitHead": "5e7bafedfc3d53bc131469a28de31dd8e5b4a3ff\n" | ||
} |
import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; | ||
export function partial(fn, ...args) { | ||
let [a, b, c, d, e, f, g, h] = args; | ||
switch (args.length) { | ||
case 1: | ||
return (...xs) => fn(a, ...xs); | ||
case 2: | ||
return (...xs) => fn(a, b, ...xs); | ||
case 3: | ||
return (...xs) => fn(a, b, c, ...xs); | ||
case 4: | ||
return (...xs) => fn(a, b, c, d, ...xs); | ||
case 5: | ||
return (...xs) => fn(a, b, c, d, e, ...xs); | ||
case 6: | ||
return (...xs) => fn(a, b, c, d, e, f, ...xs); | ||
case 7: | ||
return (...xs) => fn(a, b, c, d, e, f, g, ...xs); | ||
case 8: | ||
return (...xs) => fn(a, b, c, d, e, f, g, h, ...xs); | ||
default: | ||
illegalArgs(); | ||
} | ||
function partial(fn, ...args) { | ||
let [a, b, c, d, e, f, g, h] = args; | ||
switch (args.length) { | ||
case 1: | ||
return (...xs) => fn(a, ...xs); | ||
case 2: | ||
return (...xs) => fn(a, b, ...xs); | ||
case 3: | ||
return (...xs) => fn(a, b, c, ...xs); | ||
case 4: | ||
return (...xs) => fn(a, b, c, d, ...xs); | ||
case 5: | ||
return (...xs) => fn(a, b, c, d, e, ...xs); | ||
case 6: | ||
return (...xs) => fn(a, b, c, d, e, f, ...xs); | ||
case 7: | ||
return (...xs) => fn(a, b, c, d, e, f, g, ...xs); | ||
case 8: | ||
return (...xs) => fn(a, b, c, d, e, f, g, h, ...xs); | ||
default: | ||
illegalArgs(); | ||
} | ||
} | ||
export { | ||
partial | ||
}; |
@@ -1,19 +0,6 @@ | ||
/** | ||
* Takes a function accepting a NodeJS-like callback w/ (error, result) | ||
* args and converts it into a Promise, e.g. for use in async contexts. | ||
* | ||
* @remarks | ||
* The constructed promise calls the given function with a custom | ||
* callback, which then either resolves or rejects the promise. | ||
* | ||
* @example | ||
* ```ts | ||
* (async () => { | ||
* const body = await promisify(partial(fs.readFile, "foo.txt")); | ||
* console.log(body.toString()); | ||
* })(); | ||
* ``` | ||
* | ||
* @param fn - function accepting a callback | ||
*/ | ||
export const promisify = (fn) => new Promise((resolve, reject) => fn((err, result) => (err != null ? reject(err) : resolve(result)))); | ||
const promisify = (fn) => new Promise( | ||
(resolve, reject) => fn((err, result) => err != null ? reject(err) : resolve(result)) | ||
); | ||
export { | ||
promisify | ||
}; |
@@ -1,39 +0,7 @@ | ||
/** | ||
* Similar to {@link threadLast}. A dataflow operator to improve the legibility | ||
* of long (or deeply nested) call expressions. Takes an `init` value and a | ||
* number of functions and/or function tuples, consisting of: `[fn, ...args]`. | ||
* Executes each function (or tuple) with the return value of the previous | ||
* step/function inserted as **first** argument, using `init` as the first | ||
* expression. Returns result of last function/step given. | ||
* | ||
* @remarks | ||
* This operator allows the code to be read more easily in the order of | ||
* execution (same as the `->` operator/macro in Clojure). | ||
* | ||
* @example | ||
* ```ts | ||
* const neg = (x) => -x; | ||
* const sub = (a, b) => a - b; | ||
* const div = (a, b) => a / b; | ||
* | ||
* // without operator: (-5 - 10) / 20 | ||
* console.log(div(sub(neg(5), 10), 20)); | ||
* // -0.75 | ||
* | ||
* // rewritten using operator: | ||
* threadFirst( | ||
* 5, | ||
* neg, // -5 | ||
* [sub, 10], // (-5) - 10 | ||
* [div, 20], // (-5 - 10) / 20 | ||
* console.log | ||
* ); | ||
* // -0.75 | ||
* ``` | ||
* | ||
* @param init - start value | ||
* @param fns - functions / S-expressions | ||
*/ | ||
export const threadFirst = (init, ...fns) => fns.reduce((acc, expr) => typeof expr === "function" | ||
? expr(acc) | ||
: expr[0](acc, ...expr.slice(1)), init); | ||
const threadFirst = (init, ...fns) => fns.reduce( | ||
(acc, expr) => typeof expr === "function" ? expr(acc) : expr[0](acc, ...expr.slice(1)), | ||
init | ||
); | ||
export { | ||
threadFirst | ||
}; |
@@ -1,39 +0,7 @@ | ||
/** | ||
* Similar to {@link threadFirst}. A dataflow operator to improve the legibility | ||
* of long (or deeply nested) call expressions. Takes an `init` value and a | ||
* number of functions and/or function tuples, consisting of: `[fn, ...args]`. | ||
* Executes each function (or tuple) with the return value of the previous | ||
* step/function inserted as **last** argument, using `init` as the first | ||
* expression. Returns result of last function/step given. | ||
* | ||
* @remarks | ||
* This operator allows the code to be read more easily in the order of | ||
* execution (same as the `->>` operator/macro in Clojure). | ||
* | ||
* @example | ||
* ```ts | ||
* const neg = (x) => -x; | ||
* const sub = (a, b) => a - b; | ||
* const div = (a, b) => a / b; | ||
* | ||
* // without operator: 20 / (10 - (-5)) | ||
* console.log(div(20, sub(10, neg(5)))); | ||
* // 1.3333333333333333 | ||
* | ||
* // rewritten using operator: | ||
* threadLast( | ||
* 5, | ||
* neg, // -5 | ||
* [sub, 10], // 10 - (-5) | ||
* [div, 20], // 20 / (10 - (-5)) | ||
* console.log | ||
* ); | ||
* // 1.3333333333333333 | ||
* ``` | ||
* | ||
* @param init - start value | ||
* @param fns - functions / S-expressions | ||
*/ | ||
export const threadLast = (init, ...fns) => fns.reduce((acc, expr) => typeof expr === "function" | ||
? expr(acc) | ||
: expr[0](...expr.slice(1), acc), init); | ||
const threadLast = (init, ...fns) => fns.reduce( | ||
(acc, expr) => typeof expr === "function" ? expr(acc) : expr[0](...expr.slice(1), acc), | ||
init | ||
); | ||
export { | ||
threadLast | ||
}; |
@@ -1,36 +0,9 @@ | ||
/** | ||
* Takes a function returning either a no-arg function (thunk) or its | ||
* already realized (non-function) result. Re-executes thunk for as long | ||
* as it returns another function/thunk. Once a non-function result has | ||
* been produced, `trampoline` returns that value itself. | ||
* | ||
* @remarks | ||
* If the final result should be function, it needs to wrapped (e.g. as | ||
* a 1-elem array). | ||
* | ||
* This function should be used for non-stack consuming recursion. I.e. | ||
* a trampoline is a form of continuation passing style and only ever | ||
* consumes max. 2 extra stack frames, independent from recursion depth. | ||
* | ||
* @example | ||
* ```ts | ||
* const countdown = (acc, x) => | ||
* x >= 0 ? | ||
* () => (acc.push(x), countdown(acc, x-1)) : | ||
* acc; | ||
* | ||
* trampoline(countdown([], 4)) | ||
* // [ 4, 3, 2, 1, 0 ] | ||
* | ||
* trampoline(countdown([], -1)) | ||
* // [] | ||
* ``` | ||
* | ||
* @param f - function | ||
*/ | ||
export const trampoline = (f) => { | ||
while (typeof f === "function") { | ||
f = f(); | ||
} | ||
return f; | ||
const trampoline = (f) => { | ||
while (typeof f === "function") { | ||
f = f(); | ||
} | ||
return f; | ||
}; | ||
export { | ||
trampoline | ||
}; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
41923
6
420
Updated@thi.ng/api@^8.9.12
Updated@thi.ng/errors@^2.4.6