makeCompareCollection = (getEntries, absentValue, compareValues) =>
  harden((left, right) => {
    const merged = generateCollectionPairEntries(
      left,
      right,
      getEntries,
      absentValue,
    );
    let leftIsBigger = false;
    let rightIsBigger = false;
    for (const [_key, leftValue, rightValue] of merged) {
      const comp = compareValues(leftValue, rightValue);
      if (comp === 0) {
        // eslint-disable-next-line no-continue
        continue;
      } else if (comp < 0) {
        // Based on this key, left < right.
        rightIsBigger = true;
      } else if (comp > 0) {
        // Based on this key, left > right.
        leftIsBigger = true;
      } else {
        Number.isNaN(comp) ||
          // prettier-ignore
          Fail`Unexpected value comparison ${q(comp)} for ${leftValue} vs ${rightValue}`;
        return NaN;
      }
      if (leftIsBigger && rightIsBigger) {
        return NaN;
      }
    }
    // eslint-disable-next-line no-nested-ternary
    return leftIsBigger ? 1 : rightIsBigger ? -1 : 0;
  })
Returns a function for comparing two KeyCollections of the same type using
the provided entries factory and same-key entry value comparator (where the
value for an absent entry in one collection is `absentValue`).

If the corresponding entries for any single key are incomparable or the
comparison result has the opposite sign of the result for a different key,
then the KeyCollections are incomparable. Otherwise, the collections compare
by the result of any non-equal entry comparison, or compare equal if there is
no non-equal entry comparison result.
For example, given CopyBags X and Y and a value comparator that goes by count
(defaulting absent keys to a count of 0), X is smaller than Y (`result < 0`)
iff there are no keys in X that are either absent from Y
(`compareValues(xCount, absentValue) > 0`) or present in Y with a lower count
(`compareValues(xCount, yCount) > 0`) AND there is at least one key in Y that
is either absent from X (`compareValues(absentValue, yCount) < 0`) or present
with a lower count (`compareValues(xCount, yCount) < 0`).

This can be generalized to virtual collections in the future by replacing
`getEntries => Array` with `generateEntries => IterableIterator`.

@template [C=KeyCollection]
@template [V=unknown]
@param {(collection: C) => Array<[Key, V]>} getEntries
@param {V} absentValue
@param {KeyCompare} compareValues
@returns {(left: C, right: C) => KeyComparison}