Skip to content

Commit 27a1ff4

Browse files
committed
Implement fromAscList independently
Implementing the lazy version of `fromAscList` in terms of `fromAscListWithKey` leaks memory if there are many repeated keys. Inlining `fromAscListWithKey` into `fromAscList` manually should fix this. The same goes for `fromDescList`.
1 parent 8df75c7 commit 27a1ff4

File tree

1 file changed

+26
-3
lines changed

1 file changed

+26
-3
lines changed

Data/Map/Internal.hs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3312,7 +3312,19 @@ foldlFB = foldlWithKey
33123312

33133313
fromAscList :: Eq k => [(k,a)] -> Map k a
33143314
fromAscList xs
3315-
= fromAscListWithKey (\_ x _ -> x) xs
3315+
= fromDistinctAscList (combineEq xs)
3316+
where
3317+
-- [combineEq f xs] combines equal elements with function [f] in an ordered list [xs]
3318+
combineEq _ xs'
3319+
= case xs' of
3320+
[] -> []
3321+
[x] -> [x]
3322+
(x:xx) -> combineEq' x xx
3323+
3324+
combineEq' z [] = [z]
3325+
combineEq' z@(kz,zz) (x@(kx,xx):xs')
3326+
| kx==kz = combineEq' (kx,xx) xs'
3327+
| otherwise = z:combineEq' x xs'
33163328
#if __GLASGOW_HASKELL__
33173329
{-# INLINABLE fromAscList #-}
33183330
#endif
@@ -3326,8 +3338,19 @@ fromAscList xs
33263338
-- > valid (fromDescList [(5,"a"), (3,"b"), (5,"b")]) == False
33273339

33283340
fromDescList :: Eq k => [(k,a)] -> Map k a
3329-
fromDescList xs
3330-
= fromDescListWithKey (\_ x _ -> x) xs
3341+
fromDescList xs = fromDistinctDescList (combineEq xs)
3342+
where
3343+
-- [combineEq f xs] combines equal elements with function [f] in an ordered list [xs]
3344+
combineEq xs'
3345+
= case xs' of
3346+
[] -> []
3347+
[x] -> [x]
3348+
(x:xx) -> combineEq' x xx
3349+
3350+
combineEq' z [] = [z]
3351+
combineEq' z@(kz,zz) (x@(kx,xx):xs')
3352+
| kx==kz = combineEq' (kx,xx) xs'
3353+
| otherwise = z:combineEq' x xs'
33313354
#if __GLASGOW_HASKELL__
33323355
{-# INLINABLE fromDescList #-}
33333356
#endif

0 commit comments

Comments
 (0)