export type BasicFun = (_: a) => b; export type Fun = BasicFun & { then(other: BasicFun): Fun; }; export const Fun = (_: BasicFun): Fun => Object.assign(_, { then: function (this: Fun, other: BasicFun): Fun { return Fun((_) => other(this(_))); }, }); export type BasicFun2 = (_: a, __: b) => c; export type Fun2 = BasicFun2 & { then(other: BasicFun): Fun2; }; export const Fun2 = (_: BasicFun2): Fun2 => Object.assign(_, { then: function ( this: Fun2, other: BasicFun, ): Fun2 { return Fun2((a, b) => other(this(a, b))); }, }); /* // samples const incr: Fun = Fun(_ => _ + 1) const decr: Fun = Fun(_ => _ - 1) const doub: Fun = Fun(_ => _ * 2) const halv: Fun = Fun(_ => _ / 2) const f = incr.then(doub).then(decr) console.log(f(5)) // prints 11 */