[EDIT]
This is a follow-up question of How to implement a stack-safe chainRec operator for the continuation monad?
Given is chainRec
's type
chainRec :: ChainRec m => ((a -> c, b -> c, a) -> m c, a) -> m b
Usually, chainRec
is implemented along with a trampoline to allow stack safe recursion within a monad. However, if we drop the trampoline, we can implement chainRec
's type for normal functions as follows:
const chainRec = f => x => join(f(chainRec(f), of, x));
Next, I want to apply it to a recursive action:
const map = f => g => x => f(g(x));
const join = f => x => f(x) (x);
const of = x => y => x;
const chainRec = f => x => join(f(chainRec(f), of, x));
const repeat = n => f => x =>
chainRec((loop, done, args) =>
args[0] === 0
? done(args[1])
: loop([args[0] - 1, map(f) (args[1])])) ([n, of(x)]);
const inc = x => of(x + 1);
repeat(10) (inc) (0) (); // error
I figured that since there is a join
in the definition of chainRec
there must be a map
involved in the implementation of repeat
, so that there are two nested functorial contexts to collapse. Yet it doesn't work and I have no idea how to fix it.