repeat.ts•853 B
/* eslint-disable @typescript-eslint/no-unsafe-argument */
import type { F, L } from 'ts-toolbelt'
/**
* An accumulable function can be passed its output as input
*/
export type Accumulable<P, R> = (arg0: R, ...rest: P[]) => R
/**
* Repeat an {@link Accumulable} function.
*
* @param f to be repeated until...
* @param again return false to exit
* @returns
* @example
* ```ts
* // concats `[2]` 10 times on `[1]`
* repeat(concat, times(10))([1], [2])
* ```
*/
function repeat<P extends L.Update<P, 0, R>, R>(f: (...p: P) => R, again: (...p: F.NoInfer<P>) => boolean) {
return (...p: P) => {
// ts does not understand
const pClone: any = [...p]
while (again(...pClone)) {
pClone[0] = f(...pClone)
}
return pClone[0] as R
}
}
function times(n: number) {
return () => --n > -1
}
export { repeat, times }