Skip to content

Commit e51597b

Browse files
authored
Document general behavior on equal keys (#1168)
1 parent 7cd38d1 commit e51597b

File tree

5 files changed

+28
-31
lines changed

5 files changed

+28
-31
lines changed

containers/src/Data/Map.hs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
-- This module re-exports the value lazy "Data.Map.Lazy" API.
2121
--
2222
-- The @'Map' k v@ type represents a finite map (sometimes called a dictionary)
23-
-- from keys of type @k@ to values of type @v@. A 'Map' is strict in its keys but lazy
23+
-- from keys of type @k@ to values of type @v@. Most operations require that @k@
24+
-- have an instance of the 'Ord' class. A 'Map' is strict in its keys but lazy
2425
-- in its values.
2526
--
2627
-- The functions in "Data.Map.Strict" are careful to force values before
@@ -45,9 +46,11 @@
4546
-- > import Data.Map (Map)
4647
-- > import qualified Data.Map as Map
4748
--
48-
-- Note that the implementation is generally /left-biased/. Functions that take
49-
-- two maps as arguments and combine them, such as `union` and `intersection`,
50-
-- prefer the values in the first argument to those in the second.
49+
-- The @'Ord' k@ instance is expected to be lawful and define a total order.
50+
-- Unless otherwise specified, operations expect equality on keys to be
51+
-- extensional: if keys @k1@ and @k2@ satisfy @k1 == k2@, they are considered
52+
-- identical. For instance, if only one key must be retained by an operation, it
53+
-- is free to select either.
5154
--
5255
--
5356
-- == Warning

containers/src/Data/Map/Lazy.hs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
-- = Finite Maps (lazy interface)
1919
--
2020
-- The @'Map' k v@ type represents a finite map (sometimes called a dictionary)
21-
-- from keys of type @k@ to values of type @v@. A 'Map' is strict in its keys but lazy
21+
-- from keys of type @k@ to values of type @v@. Most operations require that @k@
22+
-- have an instance of the 'Ord' class. A 'Map' is strict in its keys but lazy
2223
-- in its values.
2324
--
2425
-- The functions in "Data.Map.Strict" are careful to force values before
@@ -43,9 +44,11 @@
4344
-- > import Data.Map.Lazy (Map)
4445
-- > import qualified Data.Map.Lazy as Map
4546
--
46-
-- Note that the implementation is generally /left-biased/. Functions that take
47-
-- two maps as arguments and combine them, such as `union` and `intersection`,
48-
-- prefer the values in the first argument to those in the second.
47+
-- The @'Ord' k@ instance is expected to be lawful and define a total order.
48+
-- Unless otherwise specified, operations expect equality on keys to be
49+
-- extensional: if keys @k1@ and @k2@ satisfy @k1 == k2@, they are considered
50+
-- identical. For instance, if only one key must be retained by an operation, it
51+
-- is free to select either.
4952
--
5053
--
5154
-- == Warning

containers/src/Data/Map/Strict.hs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
-- = Finite Maps (strict interface)
1919
--
2020
-- The @'Map' k v@ type represents a finite map (sometimes called a dictionary)
21-
-- from keys of type @k@ to values of type @v@.
21+
-- from keys of type @k@ to values of type @v@. Most operations require that @k@
22+
-- have an instance of the 'Ord' class.
2223
--
2324
-- Each function in this module is careful to force values before installing
2425
-- them in a 'Map'. This is usually more efficient when laziness is not
@@ -48,9 +49,11 @@
4849
-- > import Data.Map.Strict (Map)
4950
-- > import qualified Data.Map.Strict as Map
5051
--
51-
-- Note that the implementation is generally /left-biased/. Functions that take
52-
-- two maps as arguments and combine them, such as `union` and `intersection`,
53-
-- prefer the values in the first argument to those in the second.
52+
-- The @'Ord' k@ instance is expected to be lawful and define a total order.
53+
-- Unless otherwise specified, operations expect equality on keys to be
54+
-- extensional: if keys @k1@ and @k2@ satisfy @k1 == k2@, they are considered
55+
-- identical. For instance, if only one key must be retained by an operation, it
56+
-- is free to select either.
5457
--
5558
--
5659
-- == Warning

containers/src/Data/Set.hs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
-- = Finite Sets
1818
--
1919
-- The @'Set' e@ type represents a set of elements of type @e@. Most operations
20-
-- require that @e@ be an instance of the 'Ord' class. A 'Set' is strict in its
21-
-- elements.
20+
-- require that @e@ have an instance of the 'Ord' class. A 'Set' is strict in
21+
-- its elements.
2222
--
2323
-- For a walkthrough of the most commonly used functions see the
2424
-- <https://haskell-containers.readthedocs.io/en/latest/set.html sets introduction>.
@@ -29,11 +29,11 @@
2929
-- > import Data.Set (Set)
3030
-- > import qualified Data.Set as Set
3131
--
32-
-- Note that the implementation is generally /left-biased/. Functions that take
33-
-- two sets as arguments and combine them, such as `union` and `intersection`,
34-
-- prefer the entries in the first argument to those in the second. Of course,
35-
-- this bias can only be observed when equality is an equivalence relation
36-
-- instead of structural equality.
32+
-- The @'Ord' e@ instance is expected to be lawful and define a total order.
33+
-- Unless otherwise specified, operations expect equality to be extensional: if
34+
-- elements @x1@ and @x2@ satisfy @x1 == x2@, they are considered identical. For
35+
-- instance, if only one element must be retained by an operation, it is free to
36+
-- select either.
3737
--
3838
--
3939
-- == Warning

containers/src/Data/Set/Internal.hs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,9 +1022,6 @@ mapMaybe f t = finishB (foldl' go emptyB t)
10221022
--
10231023
-- It's worth noting that the size of the result may be smaller if,
10241024
-- for some @(x,y)@, @x \/= y && f x == f y@
1025-
--
1026-
-- If the function produces duplicate values, only one will be retained. No
1027-
-- guarantee is made as to which.
10281025

10291026
map :: Ord b => (a->b) -> Set a -> Set b
10301027
map f t = finishB (foldl' (\b x -> insertB (f x) b) emptyB t)
@@ -1173,9 +1170,6 @@ foldlFB = foldl
11731170
--
11741171
-- If the elements are in non-decreasing order, this function takes \(O(n)\)
11751172
-- time.
1176-
--
1177-
-- If the list contains duplicate elements, only one will be retained. No
1178-
-- guarantee is made as to which.
11791173
fromList :: Ord a => [a] -> Set a
11801174
fromList xs = finishB (Foldable.foldl' (flip insertB) emptyB xs)
11811175
{-# INLINE fromList #-} -- INLINE for fusion
@@ -1188,9 +1182,6 @@ fromList xs = finishB (Foldable.foldl' (flip insertB) emptyB xs)
11881182
--------------------------------------------------------------------}
11891183
-- | \(O(n)\). Build a set from an ascending list in linear time.
11901184
--
1191-
-- If the list contains duplicate elements, only one will be retained. No
1192-
-- guarantee is made as to which.
1193-
--
11941185
-- __Warning__: This function should be used only if the elements are in
11951186
-- non-decreasing order. This precondition is not checked. Use 'fromList' if the
11961187
-- precondition may not hold.
@@ -1207,9 +1198,6 @@ fromAscList xs = ascLinkAll (Foldable.foldl' next Nada xs)
12071198

12081199
-- | \(O(n)\). Build a set from a descending list in linear time.
12091200
--
1210-
-- If the list contains duplicate elements, only one will be retained. No
1211-
-- guarantee is made as to which.
1212-
--
12131201
-- __Warning__: This function should be used only if the elements are in
12141202
-- non-increasing order. This precondition is not checked. Use 'fromList' if the
12151203
-- precondition may not hold.

0 commit comments

Comments
 (0)