/* type Fun = { (input:a) : b then(input2: Fun) : Fun; } const Functie = function(lambda: ((_:a) => b)) : Fun { const fun = lambda as Fun fun.then = function(this: Fun, otherFunc: Fun) : Fun { return Functie(x => otherFunc(this(x))) } return fun } // fun as monad // fun functor type Fun_n = Fun let map_Fun_n = (f: Fun, p: Fun_n) : Fun_n => p.then(f) // fun monoid let unit_Fun_n = () => Fun>(x => Functie(i => x)) let join_Fun_n = () => Fun>, Fun_n> (nestedFun_N => Functie(numberInput => nestedFun_N(numberInput)(numberInput))) let join_Fun_beter: Fun>, Fun_n> = Functie((nestedFun_N: Fun_n>) => { return Functie((numberInput: number) => { let tmp1 = nestedFun_N(numberInput); console.log(tmp1); let tmp2 = tmp1(numberInput); console.log(tmp2); return tmp2; }); }); let incrDounbleFun: Fun_n> = Functie((numberInput: number) => { return Functie((numberInput2: number) => { return numberInput + numberInput2; }); });