Last active
April 17, 2022 05:39
-
-
Save simlrh/f8405a4879c2153fa8a3f4c7fd4cdb8f to your computer and use it in GitHub Desktop.
Typescript compose and pipe "infix operators"
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface Composable<B,C> { | |
(b: B): C; | |
I: <D>(f: (c: C) => D) => Composable<B,D>; | |
o: <A>(f: (a: A) => B) => Composable<A,C>; | |
} | |
/* | |
* Non-type safe internal function - type safety of result is guaranteed by | |
* allowing creation only through `I` and `o` functions and methods | |
*/ | |
function makeComposable<B,C>(fs: Array<(arg: any) => any>): Composable<B,C> { | |
const apply = (b: B) => fs.reduce((acc: any, f: (arg: any) => any) => f(acc), b); | |
apply.I = <D>(f: (c: C) => D) => makeComposable<B,D>([...fs, f]); | |
apply.o = <A>(f: (a: A) => B) => makeComposable<A,C>([f, ...fs]); | |
return apply; | |
} | |
export function I<A,B>(f: (a: A) => B): Composable<A,B> { | |
return makeComposable<A,B>([f]); | |
}; | |
export const o = I; | |
// Usage | |
const double = (x: number) => x * 2; | |
const numToString = (x: number) => `${x}`; | |
const toCharacterArray = (x: string) => x.split(''); | |
const joinWithDashes = (x: string[]) => x.join('-'); | |
const myPipe = ( | |
I (double) | |
.I (numToString) | |
.I (toCharacterArray) | |
.I (joinWithDashes) | |
.I (console.log) | |
); | |
myPipe(12345); // 2-4-6-9-0 | |
const myComposition: (a: number) => void = | |
o(console.log). o (joinWithDashes). o (toCharacterArray). o (numToString). o (double); | |
myComposition(12345); // 2-4-6-9-0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I found this tremendously helpful. Thank you!