"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.memo = exports.MemoArbitrary = void 0;
const Arbitrary_1 = require("./definition/Arbitrary");
class MemoArbitrary extends Arbitrary_1.Arbitrary {
    constructor(underlying) {
        super();
        this.underlying = underlying;
        this.lastFreq = -1;
        this.lastBiased = this;
    }
    generate(mrng) {
        return this.underlying.generate(mrng);
    }
    withBias(freq) {
        if (freq !== this.lastFreq) {
            this.lastFreq = freq;
            this.lastBiased = this.underlying.withBias(freq);
        }
        return this.lastBiased;
    }
}
exports.MemoArbitrary = MemoArbitrary;
let contextRemainingDepth = 10;
function memo(builder) {
    const previous = {};
    return ((maxDepth) => {
        const n = maxDepth !== undefined ? maxDepth : contextRemainingDepth;
        if (!Object.prototype.hasOwnProperty.call(previous, n)) {
            const prev = contextRemainingDepth;
            contextRemainingDepth = n - 1;
            previous[n] = new MemoArbitrary(builder(n));
            contextRemainingDepth = prev;
        }
        return previous[n];
    });
}
exports.memo = memo;
