docs: function structureEquals(structure1, structure2, keys1, keys2, getter,
      traversedValues) {
    if (keys1.length !== keys2.length) {
      return false
    }
    
    traversedValues.set(structure1, structure2)
        
    for (let i = keys1.length; i--;) {
      let key1 = keys1[i]
      let key2 = keys2[i]
      
      if ((key1 instanceof Object) && traversedValues.has(key1)) {
        if (traversedValues.get(key1) !== key2) {
          return false
        } else {
          continue
        }
      }
      
      if (!equals(key1, key2, traversedValues)) {
        return false
      }
      
      if (key1 instanceof Object) {
        traversedValues.set(key1, key2)
      }
      
      let value1 = getter(structure1, key1)
      let value2 = getter(structure2, key2)
      
      if ((value1 instanceof Object) && traversedValues.has(value1)) {
        if (traversedValues.get(value1) !== value2) {
          return false
        } else {
          continue
        }
      }
      
      if (!equals(value1, value2, traversedValues)) {
        return false
      }
      
      if (value1 instanceof Object) {
        traversedValues.set(value1, value2)
      }
    }
    
    return true
  }