@@ -254,6 +254,38 @@ data HashMap k v
254254 -- * No two keys stored in a 'Collision' can be equal according to their
255255 -- 'Eq' instance. (INV10)
256256
257+ {-
258+ Note [Canonical form]
259+ ~~~~~~~~~~~~~~~~~~~~~
260+
261+ The invariants above imply that HashMaps have a canonical form: two
262+ HashMaps that contain the same key-value pairs have the same tree
263+ structure, modulo the order of keys within a Collision node -- regardless
264+ of the order in which they were constructed. This is because each key's
265+ hash fully determines the path to its leaf, while the remaining
266+ invariants, in particular INV1, INV3, INV5, INV8 and INV9, rule out
267+ alternative encodings of the same sub-tree (e.g. a redundant
268+ BitmapIndexed node wrapping a single Leaf, a BitmapIndexed node that
269+ could be a Full node, or a single-entry Collision node that could be a
270+ Leaf).
271+
272+ Several functions rely on this, in two ways:
273+
274+ * equal1 and equalKeys compare two trees structurally, node by node.
275+ Canonical form makes this complete: maps with equal contents have
276+ identical structure, except within Collision nodes, which these
277+ functions compare as unordered collections.
278+
279+ * equal2, cmp, equalKeys1 and the Hashable instances flatten a tree with
280+ leavesAndCollisions. Canonical form guarantees that maps with equal
281+ contents produce the same sequence of leaves, again modulo the order
282+ within Collision nodes, which these functions handle
283+ order-insensitively.
284+
285+ Without a canonical form these functions could give inconsistent results
286+ for maps with equal contents.
287+ -}
288+
257289type role HashMap nominal representational
258290
259291-- | @since 0.2.17.0
0 commit comments