let xs = ['a', 'b', 'a'] in fromListWith (+) [ (x, 1) | x <- xs ] = fromList [('a', 2), ('b', 1)]Given a list of key-value pairs xs :: [(k, v)], group all values by their keys and return a HashMap k [v].
let xs = [('a', 1), ('b', 2), ('a', 3)] in fromListWith (++) [ (k, [v]) | (k, v) <- xs ] = fromList [('a', [3, 1]), ('b', [2])]Note that the lists in the resulting map contain elements in reverse order from their occurrences in the original list. More generally, duplicate entries are accumulated as follows; this matters when f is not commutative or not associative.
fromListWith f [(k, a), (k, b), (k, c), (k, d)] = fromList [(k, f d (f c (f b a)))]
data Key = Div | Suband the values need to be combined differently when there are duplicates, depending on the key:
combine Div = div combine Sub = (-)then fromListWithKey can be used as follows:
fromListWithKey combine [(Div, 2), (Div, 6), (Sub, 2), (Sub, 3)] = fromList [(Div, 3), (Sub, 1)]More generally, duplicate entries are accumulated as follows;
fromListWith f [(k, a), (k, b), (k, c), (k, d)] = fromList [(k, f k d (f k c (f k b a)))]
let xs = ['a', 'b', 'a'] in fromListWith (+) [ (x, 1) | x <- xs ] = fromList [('a', 2), ('b', 1)]Given a list of key-value pairs xs :: [(k, v)], group all values by their keys and return a HashMap k [v].
let xs = ('a', 1), ('b', 2), ('a', 3)] in fromListWith (++) [ (k, [v]) | (k, v) <- xs ] = fromList [('a', [3, 1]), ('b', [2])]Note that the lists in the resulting map contain elements in reverse order from their occurrences in the original list. More generally, duplicate entries are accumulated as follows; this matters when f is not commutative or not associative.
fromListWith f [(k, a), (k, b), (k, c), (k, d)] = fromList [(k, f d (f c (f b a)))]