private transform! — function
transform!(f, [fctx,] tape::Ghost.Tape)
Transform tape by applying f to each entry in the tape.
f(tape.ctx, entry) cannot manipulate tape directly.
Instead, f should return a tuple of the form ([calls...], idx)
where [calls...] is a vector of tape entries that should replace entry.
idx specifies that references to entry in tape should be rebound to
calls[idx].
If calls is empty, then entry is deleted from the tape,
and references to it are rebound to idx.
Note that if entry isa Ghost.Input, then it cannot be deleted from tape.
fctx(tape.ctx, calls) can be used to update tape.ctx.
calls is the same list of entries returned by f except
that the ID for each entry in calls is the ID after being rebound in tape.
If calls was empty, then fctx is not called.
If not specified, fctx is a no-op.