Skip to content

Commit 1757e89

Browse files
authored
Document the behavior of fromListWith with non-associative and non-commutative operations (#237)
Also: - Copy the improvements of #133 from Strict to Lazy - Make the examples more concrete
1 parent 4cea64a commit 1757e89

File tree

2 files changed

+53
-8
lines changed

2 files changed

+53
-8
lines changed

Data/HashMap/Base.hs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1827,7 +1827,35 @@ fromList = L.foldl' (\ m (k, v) -> unsafeInsert k v m) empty
18271827
{-# INLINABLE fromList #-}
18281828

18291829
-- | /O(n*log n)/ Construct a map from a list of elements. Uses
1830-
-- the provided function to merge duplicate entries.
1830+
-- the provided function @f@ to merge duplicate entries with
1831+
-- @(f newVal oldVal)@.
1832+
--
1833+
-- === Examples
1834+
--
1835+
-- Given a list @xs@, create a map with the number of occurrences of each
1836+
-- element in @xs@:
1837+
--
1838+
-- > let xs = ['a', 'b', 'a']
1839+
-- > in fromListWith (+) [ (x, 1) | x <- xs ]
1840+
-- >
1841+
-- > = fromList [('a', 2), ('b', 1)]
1842+
--
1843+
-- Given a list of key-value pairs @xs :: [(k, v)]@, group all values by their
1844+
-- keys and return a @HashMap k [v]@.
1845+
--
1846+
-- > let xs = [('a', 1), ('b', 2), ('a', 3)]
1847+
-- > in fromListWith (++) [ (k, [v]) | (k, v) <- xs ]
1848+
-- >
1849+
-- > = fromList [('a', [3, 1]), ('b', [2])]
1850+
--
1851+
-- Note that the lists in the resulting map contain elements in reverse order
1852+
-- from their occurences in the original list.
1853+
--
1854+
-- More generally, duplicate entries are accumulated as follows;
1855+
-- this matters when @f@ is not commutative or not associative.
1856+
--
1857+
-- > fromListWith f [(k, a), (k, b), (k, c), (k, d)]
1858+
-- > = fromList [(k, f d (f c (f b a)))]
18311859
fromListWith :: (Eq k, Hashable k) => (v -> v -> v) -> [(k, v)] -> HashMap k v
18321860
fromListWith f = L.foldl' (\ m (k, v) -> unsafeInsertWith f k v m) empty
18331861
{-# INLINE fromListWith #-}

Data/HashMap/Strict/Base.hs

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -606,18 +606,35 @@ fromList = L.foldl' (\ m (k, !v) -> HM.unsafeInsert k v m) empty
606606
{-# INLINABLE fromList #-}
607607

608608
-- | /O(n*log n)/ Construct a map from a list of elements. Uses
609-
-- the provided function f to merge duplicate entries (f newVal oldVal).
609+
-- the provided function @f@ to merge duplicate entries with
610+
-- @(f newVal oldVal)@.
610611
--
611-
-- For example:
612+
-- === Examples
612613
--
613-
-- > fromListWith (+) [ (x, 1) | x <- xs ]
614+
-- Given a list @xs@, create a map with the number of occurrences of each
615+
-- element in @xs@:
614616
--
615-
-- will create a map with number of occurrences of each element in xs.
617+
-- > let xs = ['a', 'b', 'a']
618+
-- > in fromListWith (+) [ (x, 1) | x <- xs ]
619+
-- >
620+
-- > = fromList [('a', 2), ('b', 1)]
616621
--
617-
-- > fromListWith (++) [ (k, [v]) | (k, v) <- xs ]
622+
-- Given a list of key-value pairs @xs :: [(k, v)]@, group all values by their
623+
-- keys and return a @HashMap k [v]@.
618624
--
619-
-- will group all values by their keys in a list 'xs :: [(k, v)]' and
620-
-- return a 'HashMap k [v]'.
625+
-- > let xs = ('a', 1), ('b', 2), ('a', 3)]
626+
-- > in fromListWith (++) [ (k, [v]) | (k, v) <- xs ]
627+
-- >
628+
-- > = fromList [('a', [3, 1]), ('b', [2])]
629+
--
630+
-- Note that the lists in the resulting map contain elements in reverse order
631+
-- from their occurences in the original list.
632+
--
633+
-- More generally, duplicate entries are accumulated as follows;
634+
-- this matters when @f@ is not commutative or not associative.
635+
--
636+
-- > fromListWith f [(k, a), (k, b), (k, c), (k, d)]
637+
-- > = fromList [(k, f d (f c (f b a)))]
621638
fromListWith :: (Eq k, Hashable k) => (v -> v -> v) -> [(k, v)] -> HashMap k v
622639
fromListWith f = L.foldl' (\ m (k, v) -> unsafeInsertWith f k v m) empty
623640
{-# INLINE fromListWith #-}

0 commit comments

Comments
 (0)