Skip to content

Instantly share code, notes, and snippets.

@dested
Created August 30, 2017 03:03
Show Gist options
  • Save dested/1e5345e1253a4ad113fecd3b21240120 to your computer and use it in GitHub Desktop.
Save dested/1e5345e1253a4ad113fecd3b21240120 to your computer and use it in GitHub Desktop.
type restParam<R> = ((...a: any[]) => R);
type oneParam<A, R> = ((a: A) => R);
type twoParam<A, B, R> = ((a: A, b: B) => R);
type threeParam<A, B, C, R> = ((a: A, b: B, c: C) => R);
type composeFn = (
(() => () => void) &
//1 param, 5 composes
(<T1, R>(one: oneParam<T1, R>) => oneParam<T1, R>) &
(<T1, A, R>(two: oneParam<A, R>, one: oneParam<T1, A>) => oneParam<T1, R>) &
(<T1, A, B, R>(three: oneParam<B, R>, two: oneParam<A, B>, one: oneParam<T1, A>) => oneParam<T1, R>) &
(<T1, A, B, C, R>(four: oneParam<C, R>, three: oneParam<B, C>, two: oneParam<A, B>, one: oneParam<T1, A>) => oneParam<T1, R>) &
(<T1, A, B, C, D, R>(five: oneParam<D, R>, four: oneParam<C, D>, three: oneParam<B, C>, two: oneParam<A, B>, one: oneParam<T1, A>) => oneParam<T1, R>) &
//2 params, 5 composes
(<T1, T2, R>(one: twoParam<T1, T2, R>) => twoParam<T1, T2, R>) &
(<T1, T2, A, R>(two: oneParam<A, R>, one: twoParam<T1, T2, A>) => twoParam<T1, T2, R>) &
(<T1, T2, A, B, R>(three: oneParam<B, R>, two: oneParam<A, B>, one: twoParam<T1, T2, A>) => twoParam<T1, T2, R>) &
(<T1, T2, A, B, C, R>(four: oneParam<C, R>, three: oneParam<B, C>, two: oneParam<A, B>, one: twoParam<T1, T2, A>) => twoParam<T1, T2, R>) &
(<T1, T2, A, B, C, D, R>(five: oneParam<D, R>, four: oneParam<C, D>, three: oneParam<B, C>, two: oneParam<A, B>, one: twoParam<T1, T2, A>) => twoParam<T1, T2, R>) &
//3 params, 5 composes
(<T1, T2, T3, R>(one: threeParam<T1, T2, T3, R>) => threeParam<T1, T2, T3, R>) &
(<T1, T2, T3, A, R>(two: oneParam<A, R>, one: threeParam<T1, T2, T3, A>) => threeParam<T1, T2, T3, R>) &
(<T1, T2, T3, A, B, R>(three: oneParam<B, R>, two: oneParam<A, B>, one: threeParam<T1, T2, T3, A>) => threeParam<T1, T2, T3, R>) &
(<T1, T2, T3, A, B, C, R>(four: oneParam<C, R>, three: oneParam<B, C>, two: oneParam<A, B>, one: threeParam<T1, T2, T3, A>) => threeParam<T1, T2, T3, R>) &
(<T1, T2, T3, A, B, C, D, R>(five: oneParam<D, R>, four: oneParam<C, D>, three: oneParam<B, C>, two: oneParam<A, B>, one: threeParam<T1, T2, T3, A>) => threeParam<T1, T2, T3, R>) &
//N params (not safe), 5 composes
(<R>(one: restParam<R>) => restParam<R>) &
(<A, R>(two: oneParam<A, R>, one: restParam<A>) => restParam<R>) &
(<A, B, R>(three: oneParam<B, R>, two: oneParam<A, B>, one: restParam<A>) => restParam<R>) &
(<A, B, C, R>(four: oneParam<C, R>, three: oneParam<B, C>, two: oneParam<A, B>, one: restParam<A>) => restParam<R>) &
(<A, B, C, D, R>(five: oneParam<D, R>, four: oneParam<C, D>, three: oneParam<B, C>, two: oneParam<A, B>, one: restParam<A>) => restParam<R>) &
//N params, N composes (not safe)
(<R>(...params: Function[]) => Function)
);
let compose: composeFn =
(() => {
//js function to solve this
}) as any;
const numberToNumber = (a: number): number => a + 2;
const numberToString = (a: number): string => "foo";
const stringToNumber = (a: string): number => 5;
const t1: number = compose(numberToNumber, numberToNumber)(5);
const t2: string = compose(numberToString, numberToNumber)(5);
const t3: string = compose(numberToString, stringToNumber)("f");
const t4: (a: string) => number = compose(
(f: (a: string) => number) => ((p: string) => 5),
(f: (a: number) => string) => ((p: string) => 4)
)(numberToString);
const t5: number = compose(stringToNumber, numberToString, numberToNumber)(5);
const t6: string = compose(numberToString, stringToNumber, numberToString,
numberToNumber)(5);
const t7: string = compose(
numberToString, numberToNumber, stringToNumber, numberToString,
stringToNumber)("fo");
const multiArgFn = (a: string, b: number, c: boolean): string => 'foo';
const t8: string = compose(multiArgFn)('bar', 42, true);
const t9: number = compose(stringToNumber, multiArgFn)('bar', 42, true);
const t10: string = compose(numberToString, stringToNumber,
multiArgFn)('bar', 42, true);
const t11: number = compose(stringToNumber, numberToString, stringToNumber,
multiArgFn)('bar', 42, true);
const fourMultiArgFn = (a: string, b: number, c: boolean, d: number): string => 'foo';
const t12: number = compose(stringToNumber, fourMultiArgFn)('bar', 42, true, 12);
const t13: number = compose(numberToNumber, numberToNumber, numberToNumber, numberToNumber, numberToNumber, numberToNumber)(12);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment