type PipeFn = (input: unknown) => unknown;
/* eslint-disable no-shadow, @typescript-eslint/no-non-null-assertion */
export function pipe(a: A): A;
export function pipe(a: A, ab: (a: A) => B): B;
export function pipe(a: A, ab: (a: A) => B, bc: (b: B) => C): C;
export function pipe(
a: A,
ab: (a: A) => B,
bc: (b: B) => C,
cd: (c: C) => D
): D;
export function pipe(
a: A,
ab: (a: A) => B,
bc: (b: B) => C,
cd: (c: C) => D,
de: (d: D) => E
): E;
export function pipe(
a: unknown,
ab?: PipeFn,
bc?: PipeFn,
cd?: PipeFn,
de?: PipeFn
): unknown {
switch (arguments.length) {
case 1:
return a;
case 2:
return ab!(a);
case 3:
return bc!(ab!(a));
case 4:
return cd!(bc!(ab!(a)));
case 5:
return de!(cd!(bc!(ab!(a))));
}
throw new Error(
`Pipe with ${arguments.length} arguments is not implemented yet!`
);
}
type FlowFn = (...args: Array) => unknown;
export function flow, B>(
ab: (...a: A) => B
): (...a: A) => B;
export function flow, B, C>(
ab: (...a: A) => B,
bc: (b: B) => C
): (...a: A) => C;
export function flow, B, C, D>(
ab: (...a: A) => B,
bc: (b: B) => C,
cd: (c: C) => D
): (...a: A) => D;
export function flow, B, C, D, E>(
ab: (...a: A) => B,
bc: (b: B) => C,
cd: (c: C) => D,
de: (d: D) => E
): (...a: A) => E;
export function flow(
ab: FlowFn,
bc?: FlowFn,
cd?: FlowFn,
de?: FlowFn
): unknown {
switch (arguments.length) {
case 1:
return ab;
case 2:
return (...args: Array) => bc!(ab(...args));
case 3:
return (...args: Array) => cd!(bc!(ab(...args)));
case 4:
return (...args: Array) => de!(cd!(bc!(ab(...args))));
}
throw new Error(
`Flow with ${arguments.length} arguments is not implemented yet!`
);
}
/* eslint-enable no-shadow, @typescript-eslint/no-non-null-assertion */
// eslint-disable-next-line @typescript-eslint/no-empty-function
export const noop = (): void => {};
export const always = (a: A) => (_b: any) => a;
export const invokeWith = (a: A) => (fn: (fa: A) => B) => fn(a);
export const invoke = (fn: (a: A) => B) => (a: A) => fn(a);
export const equal = (a1: A) => (a2: A) => a1 === a2;
export const isDefined = (a: A) => a !== null && a !== undefined;