@@ -830,6 +830,8 @@ insert k x Nil = Tip k x
830
830
-- > insertWith (++) 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "xxxa")]
831
831
-- > insertWith (++) 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]
832
832
-- > insertWith (++) 5 "xxx" empty == singleton 5 "xxx"
833
+ --
834
+ -- Also see the performance note on 'fromListWith'.
833
835
834
836
insertWith :: (a -> a -> a ) -> Key -> a -> IntMap a -> IntMap a
835
837
insertWith f k x t
@@ -845,6 +847,8 @@ insertWith f k x t
845
847
-- > insertWithKey f 5 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "5:xxx|a")]
846
848
-- > insertWithKey f 7 "xxx" (fromList [(5,"a"), (3,"b")]) == fromList [(3, "b"), (5, "a"), (7, "xxx")]
847
849
-- > insertWithKey f 5 "xxx" empty == singleton 5 "xxx"
850
+ --
851
+ -- Also see the performance note on 'fromListWith'.
848
852
849
853
insertWithKey :: (Key -> a -> a -> a ) -> Key -> a -> IntMap a -> IntMap a
850
854
insertWithKey f ! k x t@ (Bin p m l r)
@@ -870,6 +874,8 @@ insertWithKey _ k x Nil = Tip k x
870
874
-- > let insertLookup kx x t = insertLookupWithKey (\_ a _ -> a) kx x t
871
875
-- > insertLookup 5 "x" (fromList [(5,"a"), (3,"b")]) == (Just "a", fromList [(3, "b"), (5, "x")])
872
876
-- > insertLookup 7 "x" (fromList [(5,"a"), (3,"b")]) == (Nothing, fromList [(3, "b"), (5, "a"), (7, "x")])
877
+ --
878
+ -- Also see the performance note on 'fromListWith'.
873
879
874
880
insertLookupWithKey :: (Key -> a -> a -> a ) -> Key -> a -> IntMap a -> (Maybe a , IntMap a )
875
881
insertLookupWithKey f ! k x t@ (Bin p m l r)
@@ -1085,6 +1091,8 @@ union m1 m2
1085
1091
-- | \(O(n+m)\). The union with a combining function.
1086
1092
--
1087
1093
-- > unionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "aA"), (7, "C")]
1094
+ --
1095
+ -- Also see the performance note on 'fromListWith'.
1088
1096
1089
1097
unionWith :: (a -> a -> a ) -> IntMap a -> IntMap a -> IntMap a
1090
1098
unionWith f m1 m2
@@ -1094,6 +1102,8 @@ unionWith f m1 m2
1094
1102
--
1095
1103
-- > let f key left_value right_value = (show key) ++ ":" ++ left_value ++ "|" ++ right_value
1096
1104
-- > unionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "5:a|A"), (7, "C")]
1105
+ --
1106
+ -- Also see the performance note on 'fromListWith'.
1097
1107
1098
1108
unionWithKey :: (Key -> a -> a -> a ) -> IntMap a -> IntMap a -> IntMap a
1099
1109
unionWithKey f m1 m2
@@ -2540,6 +2550,8 @@ mapKeys f = fromList . foldrWithKey (\k x xs -> (f k, x) : xs) []
2540
2550
--
2541
2551
-- > mapKeysWith (++) (\ _ -> 1) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 1 "cdab"
2542
2552
-- > mapKeysWith (++) (\ _ -> 3) (fromList [(1,"b"), (2,"a"), (3,"d"), (4,"c")]) == singleton 3 "cdab"
2553
+ --
2554
+ -- Also see the performance note on 'fromListWith'.
2543
2555
2544
2556
mapKeysWith :: (a -> a -> a ) -> (Key -> Key ) -> IntMap a -> IntMap a
2545
2557
mapKeysWith c f
@@ -3195,10 +3207,41 @@ fromList xs
3195
3207
where
3196
3208
ins t (k,x) = insert k x t
3197
3209
3198
- -- | \(O(n \min(n,W))\). Create a map from a list of key\/value pairs with a combining function. See also 'fromAscListWith'.
3210
+ -- | \(O(n \min(n,W))\). Build a map from a list of key\/value pairs with a combining function. See also 'fromAscListWith'.
3199
3211
--
3200
- -- > fromListWith (++) [(5,"a"), (5,"b"), (3,"b "), (3,"a"), ( 5,"c")] == fromList [(3, "ab "), (5, "cba")]
3212
+ -- > fromListWith (++) [(5,"a"), (5,"b"), (3,"x "), (5,"c")] == fromList [(3, "x "), (5, "cba")]
3201
3213
-- > fromListWith (++) [] == empty
3214
+ --
3215
+ -- Note the reverse ordering of @"cba"@ in the example.
3216
+ --
3217
+ -- The symmetric combining function @f@ is applied in a left-fold over the list, as @f new old@.
3218
+ --
3219
+ -- === Performance
3220
+ --
3221
+ -- You should ensure that the given @f@ is fast with this order of arguments.
3222
+ --
3223
+ -- Symmetric functions may be slow in one order, and fast in another.
3224
+ -- For the common case of collecting values of matching keys in a list, as above:
3225
+ --
3226
+ -- The complexity of @(++) a b@ is \(O(a)\), so it is fast when given a short list as its first argument.
3227
+ -- Thus:
3228
+ --
3229
+ -- > fromListWith (++) (replicate 1000000 (3, "x")) -- O(n), fast
3230
+ -- > fromListWith (flip (++)) (replicate 1000000 (3, "x")) -- O(n²), extremely slow
3231
+ --
3232
+ -- because they evaluate as, respectively:
3233
+ --
3234
+ -- > fromList [(3, "x" ++ ("x" ++ "xxxxx..xxxxx"))] -- O(n)
3235
+ -- > fromList [(3, ("xxxxx..xxxxx" ++ "x") ++ "x")] -- O(n²)
3236
+ --
3237
+ -- Thus, to get good performance with an operation like @(++)@ while also preserving
3238
+ -- the same order as in the input list, reverse the input:
3239
+ --
3240
+ -- > fromListWith (++) (reverse [(5,"a"), (5,"b"), (5,"c")]) == fromList [(5, "abc")]
3241
+ --
3242
+ -- and it is always fast to combine singleton-list values @[v]@ with @fromListWith (++)@, as in:
3243
+ --
3244
+ -- > fromListWith (++) $ reverse $ map (\(k, v) -> (k, [v])) someListOfTuples
3202
3245
3203
3246
fromListWith :: (a -> a -> a ) -> [(Key ,a )] -> IntMap a
3204
3247
fromListWith f xs
@@ -3209,6 +3252,8 @@ fromListWith f xs
3209
3252
-- > let f key new_value old_value = show key ++ ":" ++ new_value ++ "|" ++ old_value
3210
3253
-- > fromListWithKey f [(5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"c")] == fromList [(3, "3:a|b"), (5, "5:c|5:b|a")]
3211
3254
-- > fromListWithKey f [] == empty
3255
+ --
3256
+ -- Also see the performance note on 'fromListWith'.
3212
3257
3213
3258
fromListWithKey :: (Key -> a -> a -> a ) -> [(Key ,a )] -> IntMap a
3214
3259
fromListWithKey f xs
@@ -3231,6 +3276,8 @@ fromAscList = fromMonoListWithKey Nondistinct (\_ x _ -> x)
3231
3276
-- /The precondition (input list is ascending) is not checked./
3232
3277
--
3233
3278
-- > fromAscListWith (++) [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "ba")]
3279
+ --
3280
+ -- Also see the performance note on 'fromListWith'.
3234
3281
3235
3282
fromAscListWith :: (a -> a -> a ) -> [(Key ,a )] -> IntMap a
3236
3283
fromAscListWith f = fromMonoListWithKey Nondistinct (\ _ x y -> f x y)
@@ -3242,6 +3289,8 @@ fromAscListWith f = fromMonoListWithKey Nondistinct (\_ x y -> f x y)
3242
3289
--
3243
3290
-- > let f key new_value old_value = (show key) ++ ":" ++ new_value ++ "|" ++ old_value
3244
3291
-- > fromAscListWithKey f [(3,"b"), (5,"a"), (5,"b")] == fromList [(3, "b"), (5, "5:b|a")]
3292
+ --
3293
+ -- Also see the performance note on 'fromListWith'.
3245
3294
3246
3295
fromAscListWithKey :: (Key -> a -> a -> a ) -> [(Key ,a )] -> IntMap a
3247
3296
fromAscListWithKey f = fromMonoListWithKey Nondistinct f
@@ -3263,6 +3312,8 @@ fromDistinctAscList = fromMonoListWithKey Distinct (\_ x _ -> x)
3263
3312
-- The precise conditions under which this function works are subtle:
3264
3313
-- For any branch mask, keys with the same prefix w.r.t. the branch
3265
3314
-- mask must occur consecutively in the list.
3315
+ --
3316
+ -- Also see the performance note on 'fromListWith'.
3266
3317
3267
3318
fromMonoListWithKey :: Distinct -> (Key -> a -> a -> a ) -> [(Key ,a )] -> IntMap a
3268
3319
fromMonoListWithKey distinct f = go
0 commit comments