Skip to content

Commit 855d6f8

Browse files
authored
Fix strictness bugs in fromDistinctAscList and fromDistinctDescList (#996)
* Add a counterexample annotation to whnfHasNoThunks * Add NoThunks tests for `fromDistinctAscList` and `fromDistinctDescList` * Fix strictness bugs in `fromDistinctAscList` and `fromDistinctDescList`
1 parent 8f6ef9a commit 855d6f8

File tree

4 files changed

+30
-9
lines changed

4 files changed

+30
-9
lines changed
Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
module Utils.NoThunks (whnfHasNoThunks) where
22

3-
import Data.Maybe (isNothing)
4-
53
import NoThunks.Class (NoThunks, noThunks)
6-
import Test.QuickCheck (Property, ioProperty)
4+
import Test.QuickCheck (Property, counterexample, ioProperty, property)
75

86
-- | Check that after evaluating the argument to weak head normal form there
97
-- are no thunks.
108
--
119
whnfHasNoThunks :: NoThunks a => a -> Property
12-
whnfHasNoThunks a = ioProperty
13-
. fmap isNothing
14-
. noThunks []
15-
$! a
10+
whnfHasNoThunks a = ioProperty $
11+
maybe (property True) ((`counterexample` False) . show)
12+
<$> (noThunks [] $! a)

containers-tests/tests/intmap-strictness.hs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,13 @@ pStrictFoldl' :: IntMap Int -> Property
116116
pStrictFoldl' m = whnfHasNoThunks (M.foldl' (flip (:)) [] m)
117117
#endif
118118

119+
#if __GLASGOW_HASKELL__ >= 806
120+
pStrictFromDistinctAscList :: [Int] -> Property
121+
pStrictFromDistinctAscList = whnfHasNoThunks . evalSpine . M.elems . M.fromDistinctAscList . zip [0::Int ..] . map (Just $!)
122+
where
123+
evalSpine xs = length xs `seq` xs
124+
#endif
125+
119126
------------------------------------------------------------------------
120127
-- check for extra thunks
121128
--
@@ -202,6 +209,7 @@ tests =
202209
#if __GLASGOW_HASKELL__ >= 806
203210
, testProperty "strict foldr'" pStrictFoldr'
204211
, testProperty "strict foldl'" pStrictFoldl'
212+
, testProperty "strict fromDistinctAscList" pStrictFromDistinctAscList
205213
#endif
206214
]
207215
, tExtraThunksM

containers-tests/tests/map-strictness.hs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,20 @@ pStrictFoldlWithKey' :: Map Int Int -> Property
108108
pStrictFoldlWithKey' m = whnfHasNoThunks (M.foldlWithKey' (\as _ a -> a : as) [] m)
109109
#endif
110110

111+
#if __GLASGOW_HASKELL__ >= 806
112+
pStrictFromDistinctAscList :: [Int] -> Property
113+
pStrictFromDistinctAscList = whnfHasNoThunks . evalSpine . M.elems . M.fromDistinctAscList . zip [0::Int ..] . map (Just $!)
114+
where
115+
evalSpine xs = length xs `seq` xs
116+
#endif
117+
118+
#if __GLASGOW_HASKELL__ >= 806
119+
pStrictFromDistinctDescList :: [Int] -> Property
120+
pStrictFromDistinctDescList = whnfHasNoThunks . evalSpine . M.elems . M.fromDistinctDescList . zip [0::Int, -1 ..] . map (Just $!)
121+
where
122+
evalSpine xs = length xs `seq` xs
123+
#endif
124+
111125
------------------------------------------------------------------------
112126
-- check for extra thunks
113127
--
@@ -193,6 +207,8 @@ tests =
193207
, testProperty "strict foldl'" pStrictFoldl'
194208
, testProperty "strict foldrWithKey'" pStrictFoldrWithKey'
195209
, testProperty "strict foldlWithKey'" pStrictFoldlWithKey'
210+
, testProperty "strict fromDistinctAscList" pStrictFromDistinctAscList
211+
, testProperty "strict fromDistinctDescList" pStrictFromDistinctDescList
196212
#endif
197213
]
198214
, tExtraThunksM

containers/src/Data/Map/Strict/Internal.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1762,7 +1762,7 @@ fromDistinctAscList = fromDistinctAscList_linkAll . Foldable.foldl' next (State0
17621762
where
17631763
next :: FromDistinctMonoState k a -> (k,a) -> FromDistinctMonoState k a
17641764
next (State0 stk) (!kx, !x) = fromDistinctAscList_linkTop (Bin 1 kx x Tip Tip) stk
1765-
next (State1 l stk) (kx, x) = State0 (Push kx x l stk)
1765+
next (State1 l stk) (!kx, !x) = State0 (Push kx x l stk)
17661766
{-# INLINE fromDistinctAscList #-} -- INLINE for fusion
17671767

17681768
-- | \(O(n)\). Build a map from a descending list of distinct elements in linear time.
@@ -1781,5 +1781,5 @@ fromDistinctDescList = fromDistinctDescList_linkAll . Foldable.foldl' next (Stat
17811781
where
17821782
next :: FromDistinctMonoState k a -> (k,a) -> FromDistinctMonoState k a
17831783
next (State0 stk) (!kx, !x) = fromDistinctDescList_linkTop (Bin 1 kx x Tip Tip) stk
1784-
next (State1 r stk) (kx, x) = State0 (Push kx x r stk)
1784+
next (State1 r stk) (!kx, !x) = State0 (Push kx x r stk)
17851785
{-# INLINE fromDistinctDescList #-} -- INLINE for fusion

0 commit comments

Comments
 (0)