Skip to content

Commit c03be06

Browse files
authored
Document that the Eq instances cannot guarantee substitutivity (#231)
* Document that the Eq instances cannot guarantee substitutivity * Add sentence regarding other functions that demonstrate the issue …as suggested by @treeowl. * Try to make the hashWithSalt implementations slighty clearer
1 parent fedcbdc commit c03be06

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

Data/HashMap/Base.hs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,24 @@ instance Eq k => Eq1 (HashMap k) where
332332
liftEq = equal1
333333
#endif
334334

335+
-- | Note that, in the presence of hash collisions, equal @HashMap@s may
336+
-- behave differently, i.e. substitutivity may be violated:
337+
--
338+
-- >>> data D = A | B deriving (Eq, Show)
339+
-- >>> instance Hashable D where hashWithSalt salt _d = salt
340+
--
341+
-- >>> x = fromList [(A,1), (B,2)]
342+
-- >>> y = fromList [(B,2), (A,1)]
343+
--
344+
-- >>> x == y
345+
-- True
346+
-- >>> toList x
347+
-- [(A,1),(B,2)]
348+
-- >>> toList y
349+
-- [(B,2),(A,1)]
350+
--
351+
-- In general, the lack of substitutivity can be observed with any function
352+
-- that depends on the key ordering, such as folds and traversals.
335353
instance (Eq k, Eq v) => Eq (HashMap k v) where
336354
(==) = equal1 (==)
337355

Data/HashSet/Base.hs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,24 @@ instance (NFData a) => NFData (HashSet a) where
123123
rnf = rnf . asMap
124124
{-# INLINE rnf #-}
125125

126+
-- | Note that, in the presence of hash collisions, equal @HashSet@s may
127+
-- behave differently, i.e. substitutivity may be violated:
128+
--
129+
-- >>> data D = A | B deriving (Eq, Show)
130+
-- >>> instance Hashable D where hashWithSalt salt _d = salt
131+
--
132+
-- >>> x = fromList [A, B]
133+
-- >>> y = fromList [B, A]
134+
--
135+
-- >>> x == y
136+
-- True
137+
-- >>> toList x
138+
-- [A,B]
139+
-- >>> toList y
140+
-- [B,A]
141+
--
142+
-- In general, the lack of substitutivity can be observed with any function
143+
-- that depends on the key ordering, such as folds and traversals.
126144
instance (Eq a) => Eq (HashSet a) where
127145
HashSet a == HashSet b = equalKeys a b
128146
{-# INLINE (==) #-}

0 commit comments

Comments
 (0)