looking for some solutions? You are welcome.

SOLVED: How to incorporate a trampoline in my chainRec implementation?

bob:

I am transferring some purescript code of the paper Stack Safety for Free to Javascript, namely the section "Tail Recursive Monads" on page 7 et seq.:

// auxiliary function to construct product types

const structure = type => cons => {
  const f = (f, args) =>
   ({["run" + type]: f, [Symbol.toStringTag]: type, [Symbol("args")]: args});

  return cons(f);
};

// Pair Tuple

const Pair = structure("Pair") (Pair => (x, y) =>
  Pair(k => k(x, y), [x, y]));

const pairOf = empty => x =>
  Pair(empty, x);

const pairChain = concat => fm => mx =>
  mx.runPair((x, y) =>
    fm(y).runPair((x_, y_) => Pair(concat(x) (x_), y_)));

// product monoid

const prodConcat = x => y => x * y;
const prodEmpty = 1;

// auxiliary function to construct union types

const union = type => (tag, f, args) =>
   ({["run" + type]: f, tag, [Symbol.toStringTag]: type, [Symbol("args")]: args});

// Either

const Either = union("Either");

const Left = x =>
  Either("Left", k => k(x), x);

const Right = x =>
  Either("Right", k => k(x), x);

// generic chain recursive function

const chainRec = (chain, of) => fm => x => {
  const go = tx =>
    tx.runEither(x_ =>
      tx.tag === "Left"
        ? chain(go) (fm(x_))
        : of(x_));

  return chain(go) (fm(x));
};

// a rather contrived example

const powPair = b =>
  chainRec(pairChain(prodConcat), pairOf(prodEmpty)) (p =>
    p === 0
      ? pairOf(prodEmpty) (Right(null))
      : pairChain(prodConcat)
          (q => pairOf(prodEmpty) (Left(q - 1)))
            (Pair(b, p)));
      
console.log(
  powPair(2) (8).runPair(x => x));
  
console.log(
  powPair(1) (1e5).runPair(x => x));

This works but doesn't solve the underlying issue of exhausting the stack, because no trampoline is incorporated.

In purescript the compiler transforms this into a loop, so I guess everything is in tail position. But since we deal with Javascript, I don't know how to transform chainRec into a loop. What is to replace the go auxiliary function?



Posted in S.E.F
via StackOverflow & StackExchange Atomic Web Robots
Share:

No comments:

Recent