/**
 * unknown function type.
 * @params args arguments
 * @returns unknown value
 */ export type Function = (...args: unknown[]) => unknown;
/**
 * Do nothing.
 * @param _args arguments (ignored)
 * @example
 * ```javascript
 * xfunction.NOOP(1, 2);
 * // → undefined
 *
 * xfunction.NOOP('a', 'b');
 * // → undefined
 * ```
 */ export declare function NOOP(..._args: unknown[]): void;
/**
 * Return false.
 * @param _args arguments (ignored)
 * @returns false.
 * @example
 * ```javascript
 * xfunction.FALSE();
 * // → false
 * ```
 */ export declare function FALSE(..._args: unknown[]): false;
/**
 * Return true.
 * @param _args arguments (ignored)
 * @returns true.
 * @example
 * ```javascript
 * xfunction.TRUE();
 * // → true
 * ```
 */ export declare function TRUE(..._args: unknown[]): true;
/**
 * Return the same (first) value.
 * @param v a value
 * @returns v
 * @example
 * ```javascript
 * xfunction.IDENTITY(1);
 * // → 1
 *
 * xfunction.IDENTITY('a');
 * // → 'a'
 * ```
 */ export declare function IDENTITY<T>(v: T): T;
/**
 * Compare two values.
 * @param a a value
 * @param b another value
 * @returns a<b: -1, a=b: 0, a>b: 1
 * @example
 * ```javascript
 * xfunction.COMPARE(1, 2);
 * // → -1
 *
 * xfunction.COMPARE(2, 1);
 * // → 1
 *
 * xfunction.COMPARE(1, 1);
 * // → 0
 */ export declare function COMPARE<T>(a: T, b: T): number;
/**
 * Return the arguments passed as a array.
 * @param args arguments
 * @returns [...args]
 * @example
 * ```javascript
 * xfunction.ARGUMENTS(1, 2);
 * // → [1, 2]
 *
 * xfunction.ARGUMENTS('a', 'b');
 * // → ['a', 'b']
 * ```
 */ export declare function ARGUMENTS(...args: unknown[]): unknown[];
/**
 * Get the name of a function.
 * @param x a function
 * @returns name
 * @example
 * ```javascript
 * import {delay, debounce} from "jsr:@nodef/extra-function";
 *
 * xfunction.name(delay);
 * // → 'delay'
 *
 * xfunction.name(debounce);
 * // → 'debounce'
 * ```
 */ export declare function name(x: Function): string;
/**
 * Get the number of parameters of a function.
 * @param x a function
 * @returns |[p, q, ...]| | x(p, q, ...)
 * @example
 * ```javascript
 * xfunction.length(() => 0);
 * // → 0
 *
 * xfunction.length((x, y) => 0);
 * // → 2
 * ```
 */ export declare function length(x: Function): number;
export { length as arity };
/**
 * Bind this-object, and optional prefix arguments to a function.
 * @param x a function
 * @param ths this object to bind
 * @param prefix prefix arguments
 * @returns (...args) => this.x(...prefix, ...args)
 * @example
 * ```javascript
 * var array  = [1];
 * var fn = xfunction.bind(Array.prototype.push, array);
 * fn(2, 3, 4);  // push(2, 3, 4)
 * array;
 * // → [1, 2, 3, 4]
 *
 * var array  = [1, 2, 3, 4];
 * var fn = xfunction.bind(Array.prototype.splice, array, 1);
 * fn(2);  // splice(1, 2)
 * array;
 * // → [1, 4]
 * ```
 */ export declare function bind(x: Function, ths: unknown, ...prefix: unknown[]): Function;
/**
 * Invoke a function with specified this-object, and arguments provided individually.
 * @param x a function
 * @param ths this object to invoke with
 * @param args arguments
 * @returns this.x(...args)
 * @example
 * ```javascript
 * var array = [1];
 * xfunction.call(Array.prototype.push, array, 2, 3, 4);  // push(2, 3, 4)
 * array;
 * // → [1, 2, 3, 4]
 *
 * var array = [1, 2, 3, 4];
 * xfunction.call(Array.prototype.splice, array, 1, 2);  // splice(1, 2)
 * array;
 * // → [1, 4]
 * ```
 */ export declare function call(x: Function, ths?: unknown, ...args: unknown[]): unknown;
/**
 * Invoke a function with specified this-object, and arguments provided as an array.
 * @param x a function
 * @param ths this object to invoke with
 * @param args arguments array
 * @returns this.x(...args)
 * @example
 * ```javascript
 * var array = [1];
 * xfunction.apply(Array.prototype.push, array, [2, 3, 4]);  // push(2, 3, 4)
 * array;
 * // → [1, 2, 3, 4]
 *
 * var array = [1, 2, 3, 4];
 * xfunction.apply(Array.prototype.splice, array, [1, 2]);  // splice(1, 2)
 * array;
 * // → [1, 4]
 * ```
 */ export declare function apply(x: Function, ths: unknown | undefined, args: unknown[]): unknown;
/**
 * Check if value is a function.
 * @param v a value
 * @returns is function?
 * @example
 * ```javascript
 * xfunction.is(Object.keys);
 * // → true
 *
 * xfunction.is(() => 0);
 * // → true
 *
 * xfunction.is(async () => 0);
 * // → true
 *
 * xfunction.is(0);
 * // → false
 * ```
 */ export declare function is(v: unknown): v is Function;
/**
 * Check if value is an async function.
 * @param v a value
 * @returns is async function?
 * @example
 * ```javascript
 * xfunction.isAsync(async () => 0);
 * // → true
 *
 * xfunction.isAsync(() => 0);
 * // → false
 * ```
 */ export declare function isAsync(v: unknown): boolean;
/**
 * Check if value is a generator function.
 * @param v a value
 * @returns is generator function?
 * @example
 * ```javascript
 * function* naturalNumbers() {
 *   for (var i=0;; ++i)
 *     yield i;
 * }
 *
 * xfunction.isGenerator(naturalNumbers);
 * // → true
 *
 * xfunction.isGenerator(() => 0);
 * // → false
 * ```
 */ export declare function isGenerator(v: unknown): v is GeneratorFunction;
/**
 * Contextify a function by accepting the first parameter as this-object.
 * @param x a function
 * @returns (...args) => x(this, ...args)
 * @example
 * ```javascript
 * function count(x, value) {
 *   var a = 0;
 *   for (var v of x)
 *     if (v===value) ++a;
 *   return a;
 * }
 *
 * var fn = xfunction.contextify(count);
 *
 * fn.call([6, 3, 4, 3], 3);
 * // → 2
 *
 * fn.call([6, 1, 4, 3], 3);
 * // → 1
 * ```
 */ export declare function contextify(x: Function): Function;
/**
 * Decontextify a function by accepting this-object as the first argument.
 * @param x a function
 * @returns (this, ...args) => this.x(...args)
 * @example
 * ```javascript
 * function count(value) {
 *   var a = 0;
 *   for (var v of this)
 *     if (v===value) ++a;
 *   return a;
 * }
 *
 * var fn = xfunction.decontextify(count);
 *
 * fn([6, 3, 4, 3], 3);
 * // → 2
 *
 * fn([6, 1, 4, 3], 3);
 * // → 1
 * ```
 */ export declare function decontextify(x: Function): Function;
/**
 * Generate a result-negated version of a function.
 * @param x a function
 * @returns (...args) => !x(...args)
 * @example
 * ```javascript
 * var fn = xfunction.negate(isFinite);
 * fn(Infinity)
 * // → true
 * fn(1)
 * // → false
 *
 * var fn = xfunction.negate(isNaN);
 * fn(1);
 * // → true
 * fn(NaN);
 * // → false
 * ```
 */ export declare function negate(x: Function): Function;
/**
 * Resolve arguments into a unique key.
 * @param args arguments
 * @returns unique key
 */ export type Resolver = (...args: unknown[]) => unknown;
/**
 * Generate result-cached version of a function.
 * @param x a function
 * @param fr resolver ((...args) => unique key) [IDENTITY]
 * @param cache result cache [Map()]
 * @example
 * ```javascript
 * var calls = 0;
 *
 * function factorialRec(n: number) {
 *   if (n<=1) return 1;
 *   return n * factorialRec(n-1);
 * }
 *
 * function factorial(n: number) {
 *   ++calls;
 *   return factorialRec(n);
 * }
 *
 * var fn = xfunction.memoize(factorial);
 * fn(3);
 * // → 6
 * fn(4);
 * // → 24
 * fn(5);
 * // → 120
 * fn(3);
 * // → 6
 * fn(4);
 * // → 24
 * fn(5);
 * // → 120
 * calls;
 * // → 3
 *
 *
 * var calls = 0;
 *
 * function hypot(x: number, y: number) {
 *   ++calls;
 *   return Math.hypot(x, y);
 * }
 *
 * function resolver(x: number, y: number) {
 *   return 4093*y + x;  // a hash
 * }
 *
 * var fn = xfunction.memoize(hypot, resolver);
 * fn(3,  4);
 * // → 5
 * fn(6,  8);
 * // → 10
 * fn(5, 12);
 * // → 13
 * fn(3,  4);
 * // → 5
 * fn(6,  8);
 * // → 10
 * fn(5, 12);
 * // → 13
 * calls;
 * // → 3
 * ```
 */ export declare function memoize(x: Function, fr?: Resolver | null, cache?: Map<unknown, unknown> | null): Function;
/**
 * Generate a parameter-reversed version of a function.
 * @param x a function
 * @returns (p, q, ...) => x(..., q, p)
 * @example
 * ```javascript
 * function divide(x, y) {
 *   return x/y;
 * }
 *
 * var fn = xfunction.reverse(divide);
 * fn(2, 4);
 * // → 2
 * fn(2, 6);
 * // → 3
 * fn(2, 8);
 * // → 4
 *
 *
 * var array = [1];
 *
 * function push(...args) {
 *   array.push(...args);
 * }
 *
 * var fn = xfunction.reverse(push);
 * fn(2, 3, 4);  // push(2, 3, 4) in reverse order
 * array;
 * // → [1, 4, 3, 2]
 * ```
 */ export declare function reverse(x: Function): Function;
export { reverse as flip };
/**
 * Generate a (first) parameter-spreaded version of a function.
 * @param x a function
 * @returns (p, q, ...) => x([p, q, ...])
 * @example
 * ```javascript
 * function sum(x: number[]) {
 *   var a = 0;
 *   for (var v of x)
 *     a += v;
 *   return a;
 * }
 *
 * var fn = xfunction.spread(sum);
 * fn(1, 2, 3);  // sum([1, 2, 3])
 * // → 6
 *
 *
 * var array = [1];
 *
 * function concat(x: number[]) {
 *   return array.concat(x);
 * }
 *
 * var fn = xfunction.spread(concat);
 * fn(2, 3, 4);  // concat([2, 3, 4])
 * // → [1, 2, 3, 4]
 * ```
 */ export declare function spread(x: Function): Function;
/**
 * Generate a (first) parameter-collapsed version of a function.
 * @param x a function
 * @returns ([p, q, ...]) => x(p, q, ...)
 * @example
 * ```javascript
 * var fn = xfunction.unspread(Math.min);
 * fn([7, 4, 9]);  // Math.min(7, 4, 9)
 * // → 4
 *
 * var fn = xfunction.unspread((x, i, I) => x.slice(i, I));
 * fn([[1, 2, 3, 4], 2]);  // [1, 2, 3, 4].slice(2)
 * // → [3, 4]
 * ```
 */ export declare function unspread(x: Function): Function;
/**
 * Attach prefix arguments to leftmost parameters of a function.
 * @param x a function
 * @param prefix prefix arguments
 * @returns (...args) => x(...prefix, ...args)
 * @example
 * ```javascript
 * var fn = xfunction.attach(Math.min, 100);
 * fn(180, 130);  // Math.min(100, 180, 130)
 * // → 100
 *
 * var array = [1];
 * var fn = xfunction.attach((...vs) => array.push(...vs), 10, 10);
 * fn(1, 2, 3);  // array.push(10, 10, 1, 2, 3)
 * array;
 * // → [1, 10, 10, 1, 2, 3]
 * ```
 */ export declare function attach(x: Function, ...prefix: unknown[]): Function;
export { attach as partial };
/**
 * Attach suffix arguments to rightmost parameters of a function.
 * @param x a function
 * @param suffix suffix arguments
 * @returns (...args) => x(...args, ...suffix)
 * @example
 * ```javascript
 * var fn = xfunction.attachRight(Math.min, 100);
 * fn(180, 130);  // Math.min(180, 130, 100)
 * // → 100
 *
 * var array = [1];
 * var fn = xfunction.attachRight((...vs) => array.push(...vs), 10, 10);
 * fn(1, 2, 3);  // array.push(1, 2, 3, 10, 10)
 * array;
 * // → [1, 1, 2, 3, 10, 10]
 * ```
 */ export declare function attachRight(x: Function, ...suffix: unknown[]): Function;
export { attachRight as partialRight };
/**
 * Compose functions together, in applicative order.
 * @param xs functions (f, g)
 * @returns (f o g), or f(g(x))
 * @example
 * ```javascript
 * var fn = xfunction.compose(Math.sqrt, Math.abs);
 * fn(-64);  // Math.sqrt(Math.abs(-64))
 * // → 8
 *
 * var fn = xfunction.compose(Math.sqrt, Math.min);
 * fn(22, 9);  // Math.sqrt(Math.min(22, 9))
 * // → 3
 * ```
 */ export declare function compose(...xs: Function[]): Function;
/**
 * Compose functions together, such that result is piped forward.
 * @param xs functions (f, g)
 * @returns (f ▷ g), or g(f(x))
 * @example
 * ```javascript
 * var fn = xfunction.composeRight(Math.abs, Math.sqrt);
 * fn(-64);  // Math.sqrt(Math.abs(-64))
 * // → 8
 *
 * var fn = xfunction.composeRight(Math.min, Math.sqrt);
 * fn(22, 9);  // Math.sqrt(Math.min(22, 9))
 * // → 3
 * ```
 */ export declare function composeRight(...xs: Function[]): Function;
/**
 * Generate curried version of a function.
 * @param x a function
 * @param n number of parameters [all]
 * @returns (p)(q)(...) => x(p, q, ...)
 * @example
 * ```javascript
 * var sub = (x: number, y: number) => x - y;
 * var fn  = xfunction.curry(sub);
 * fn(2)(3);  // sub(2, 3)
 * // → -1
 *
 * var fn  = xfunction.curry(Math.min, 3);
 * fn(5)(8)(3);  // Math.min(5, 8, 3)
 * // → 3
 * ```
 */ export declare function curry(x: Function, n?: number): Function;
/**
 * Generate right-curried version of a function.
 * @param x a function
 * @param n number of parameters [all]
 * @returns (p)(q)(...) => x(..., q, p)
 * @example
 * ```javascript
 * var sub = (x: number, y: number) => x - y;
 * var fn  = xfunction.curryRight(sub);
 * fn(2)(3);  // sub(3, 2)
 * // → 1
 *
 * var array = [1];
 * var push2 = (x: number, y: number) => array.push(x, y);
 * var fn  = xfunction.curryRight(push2, 2);
 * fn(2)(3);  // push2(3, 2)
 * array;
 * // → [1, 3, 2]
 * ```
 */ export declare function curryRight(x: Function, n?: number): Function;
/** Invocation control for time/rate-controlled functions. */ export interface InvocationControl {
  /** Disable invoking of target function. */ clear: () => void;
  /** Immediately invoke target function. */ flush: () => void;
}
/**
 * Generate deferred version of a function, that executes after the current stack has cleared.
 * @param x a function
 * @returns (...args) => invocation control
 * @example
 * ```javascript
 * var count = 0;
 * var fn = xfunction.defer(() => ++count);
 * fn();
 * fn();
 * // `count` incremented after 0s
 * // `count` incremented after 0s
 * ```
 */ export declare function defer(x: Function): Function;
/**
 * Generate delayed version of a function.
 * @param x a function
 * @param t delay time (ms)
 * @returns (...args) => invocation control
 * @example
 * ```javascript
 * var count = 0;
 * var fn = xfunction.delay(() => ++count, 500);
 * setTimeout(fn, 0);
 * setTimeout(fn, 1000);
 * // `count` incremented after 0.5s
 * // `count` incremented after 1.5s
 *
 *
 * var count = 0;
 * var fn = xfunction.delay(() => ++count, 500);
 * setTimeout(fn, 0);
 * setTimeout(fn, 1000);
 * setTimeout(fn, 2000);
 * setTimeout(fn, 3000);
 * // `count` incremented after 0.5s
 * // `count` incremented after 1.5s
 * // `count` incremented after 2.5s
 * // `count` incremented after 3.5s
 * ```
 */ export declare function delay(x: Function, t: number): Function;
/**
 * Generate restricted-use version of a function.
 * @param x a function
 * @param start usable from
 * @param end usable till (excluding) [-1 ⇒ end]
 * @returns (...args) => x(...args) from [start:end] calls
 * @example
 * ```javascript
 * var sum = 0;
 * var add = (x: number) => sum += x;
 * var fn  = xfunction.restrict(add, 0, 4);
 * for (var i=0; i<10; ++i)
 *   fn(i);
 * sum;  // 0 + 1 + 2 + 3
 * // → 6
 *
 *
 * var sum = 0;
 * var add = (x: number) => sum += x;
 * var fn  = xfunction.restrict(add, 4, 8);
 * for (var i=0; i<10; ++i)
 *   fn(i);
 * sum;  // 4 + 5 + 6 + 7
 * // → 22
 * ```
 */ export declare function restrict(x: Function, start: number, end?: number): Function;
/**
 * Restrict a function to be used only once.
 * @param x a function
 * @returns (...args) => x(...args) from [0:1] calls
 * @example
 * ```javascript
 * var count = 0;
 * var fn = xfunction.restrictOnce(x => ++count);
 * for (var i=0; i<10; ++i)
 *   fn(i);
 * count;
 * // → 1
 * ```
 */ export declare function restrictOnce(x: Function): Function;
export { restrictOnce as once };
/**
 * Restrict a function to be used only upto a certain number of calls.
 * @param x a function
 * @param n number of calls upto which it is usable
 * @returns (...args) => x(...args) from [0:n] calls
 * @example
 * ```javascript
 * var count = 0;
 * var fn = xfunction.restrictBefore(x => ++count, 3);
 * for (var i=0; i<10; ++i)
 *   fn(i);
 * count;
 * // → 3
 * ```
 */ export declare function restrictBefore(x: Function, n: number): Function;
export { restrictBefore as before };
/**
 * Restrict a function to be used only after a certain number of calls.
 * @param x a function
 * @param n number of calls after which it is usable
 * @returns (...args) => x(...args) from [n:end] calls
 * @example
 * ```javascript
 * var count = 0;
 * var fn = xfunction.restrictAfter(x => ++count, 3);
 * for (var i=0; i<10; ++i)
 *   fn(i);
 * count;
 * // → 7
 * ```
 */ export declare function restrictAfter(x: Function, n: number): Function;
export { restrictAfter as after };
/**
 * Generate debounced version of a function.
 * @param x a function
 * @param t delay time (ms)
 * @param T max delay time [-1 ⇒ none]
 * @returns (...args) => invocation control
 * @example
 * ```javascript
 * var count = 0;
 * var fn = xfunction.debounce(() => ++count, 1500);
 * setTimeout(fn, 0);
 * setTimeout(fn, 1000);
 * setTimeout(fn, 2000);
 * setTimeout(fn, 4000);
 * setTimeout(fn, 5000);
 * // `count` incremented after 3.5s
 * // `count` incremented after 6.5s
 *
 *
 * var count = 0;
 * var fn = xfunction.debounce(() => ++count, 1500);
 * setTimeout(fn, 0);
 * setTimeout(fn, 500);
 * setTimeout(fn, 1000);
 * setTimeout(fn, 1500);
 * setTimeout(fn, 2000);
 * setTimeout(fn, 4000);
 * setTimeout(fn, 4500);
 * setTimeout(fn, 5000);
 * // `count` incremented after 3.5s
 * // `count` incremented after 6.5s
 *
 *
 * var count = 0;
 * var fn = xfunction.debounce(() => ++count, 1500, 3500);
 * setTimeout(fn, 0);
 * setTimeout(fn, 1000);
 * setTimeout(fn, 2000);
 * setTimeout(fn, 3000);
 * setTimeout(fn, 4000);
 * setTimeout(fn, 6000);
 * // `count` incremented after 3.5s
 * // `count` incremented after 5.5s
 * // `count` incremented after 7.5s
 * ```
 */ export declare function debounce(x: Function, t: number, T?: number): Function;
/**
 * Generate leading-edge debounced version of a function.
 * @param x a function
 * @param t delay time (ms)
 * @param T max delay time [-1 ⇒ none]
 * @returns (...args) => invocation control
 * @example
 * ```javascript
 * var count = 0;
 * var fn = xfunction.debounceEarly(() => ++count, 1500);
 * setTimeout(fn, 0);
 * setTimeout(fn, 1000);
 * setTimeout(fn, 2000);
 * setTimeout(fn, 4000);
 * setTimeout(fn, 5000);
 * // `count` incremented after 0s
 * // `count` incremented after 4s
 *
 *
 * var count = 0;
 * var fn = xfunction.debounceEarly(() => ++count, 1500);
 * setTimeout(fn, 0);
 * setTimeout(fn, 500);
 * setTimeout(fn, 1000);
 * setTimeout(fn, 1500);
 * setTimeout(fn, 2000);
 * setTimeout(fn, 4000);
 * setTimeout(fn, 4500);
 * setTimeout(fn, 5000);
 * // `count` incremented after 0s
 * // `count` incremented after 4s
 *
 *
 * var count = 0;
 * var fn = xfunction.debounceEarly(() => ++count, 1500, 3500);
 * setTimeout(fn, 0);
 * setTimeout(fn, 1000);
 * setTimeout(fn, 2000);
 * setTimeout(fn, 3000);
 * setTimeout(fn, 4000);
 * setTimeout(fn, 6000);
 * // `count` incremented after 0s
 * // `count` incremented after 4s
 * // `count` incremented after 6s
 * ```
 */ export declare function debounceEarly(x: Function, t: number, T?: number): Function;
/**
 * Generate throttled version of a function.
 * @param x a function
 * @param t wait time (ms)
 * @returns (...args) => invocation control
 * @example
 * ```javascript
 * var count = 0;
 * var fn = xfunction.throttle(() => ++count, 2500);
 * setTimeout(fn, 0);
 * setTimeout(fn, 1000);
 * setTimeout(fn, 2000);
 * // `count` incremented after 2.5s
 *
 *
 * var count = 0;
 * var fn = xfunction.throttle(() => ++count, 2500);
 * setTimeout(fn, 0);
 * setTimeout(fn, 1000);
 * setTimeout(fn, 2000);
 * setTimeout(fn, 3000);
 * setTimeout(fn, 4000);
 * // `count` incremented after 2.5s
 * // `count` incremented after 5.5s
 * ```
 */ export declare function throttle(x: Function, t: number): Function;
/**
 * Generate leading-edge throttled version of a function.
 * @param x a function
 * @param t wait time (ms)
 * @returns (...args) => invocation control
 * @example
 * ```javascript
 * var count = 0;
 * var fn = xfunction.throttleEarly(() => ++count, 2500);
 * setTimeout(fn, 0);
 * setTimeout(fn, 1000);
 * setTimeout(fn, 2000);
 * // `count` incremented after 0s
 *
 *
 * var count = 0;
 * var fn = xfunction.throttleEarly(() => ++count, 2500);
 * setTimeout(fn, 0);
 * setTimeout(fn, 1000);
 * setTimeout(fn, 2000);
 * setTimeout(fn, 3000);
 * setTimeout(fn, 4000);
 * // `count` incremented after 0s
 * // `count` incremented after 3s
 * ```
 */ export declare function throttleEarly(x: Function, t: number): Function;
