From e3c2b96c52edcc4e1b1b1b1840a8ff5317d2aef0 Mon Sep 17 00:00:00 2001 From: David Feuer Date: Sun, 26 Mar 2023 14:28:05 -0400 Subject: [PATCH] Deprecate seqSpine MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `seqSpine` function was useful back in the day when all sorts of operations were written in a way that allowed thunks to accumulate along the spine. Now, we carefully force as much of the spine as the amortized bounds allow, which eliminates this problem in general. The only operations that still accumulate thunks along the spine are monotonic maps, and forcing the spines of those just leads to the creation of more thunks at the leaves—it's not really useful. --- CHANGELOG.md | 2 ++ src/Data/PQueue/Internals.hs | 7 ++++--- src/Data/PQueue/Max.hs | 7 ++++--- src/Data/PQueue/Prio/Internals.hs | 8 +++++--- src/Data/PQueue/Prio/Max/Internals.hs | 10 ++++++---- 5 files changed, 21 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a247452..bb9ecb1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## 1.5.0 + * Deprecate `seqSpine`. Changes in version 1.4.2.0 made it useless. + * Add pattern synonyms to work with `MinQueue` and `MinPQueue`. ([#92](http://github.com/lspitzner/pqueue/pull/92)) diff --git a/src/Data/PQueue/Internals.hs b/src/Data/PQueue/Internals.hs index f2b742d..0d27807 100644 --- a/src/Data/PQueue/Internals.hs +++ b/src/Data/PQueue/Internals.hs @@ -343,9 +343,10 @@ toListUApp (MinQueue _ x ts) app = x : BQ.foldrU (:) app ts -- -- Note: The spine of a 'MinQueue' is stored somewhat lazily. Most operations -- take great care to prevent chains of thunks from accumulating along the --- spine to the detriment of performance. However, @mapU@ can leave expensive --- thunks in the structure and repeated applications of that function can --- create thunk chains. +-- spine to the detriment of performance. The only one that doesn't, +-- 'mapU', does not benefit from forcing the spine anyway. Forcing the spine +-- of the result just forces the creation of thunks for all the elements. +{-# DEPRECATED seqSpine "This function is no longer useful." #-} seqSpine :: MinQueue a -> b -> b seqSpine Empty z = z seqSpine (MinQueue _ _ ts) z = BQ.seqSpine ts z diff --git a/src/Data/PQueue/Max.hs b/src/Data/PQueue/Max.hs index 6a81739..45b80c8 100644 --- a/src/Data/PQueue/Max.hs +++ b/src/Data/PQueue/Max.hs @@ -371,8 +371,9 @@ keysQueue (Prio.MaxPQ q) = MaxQ (Min.keysQueue q) -- -- Note: The spine of a 'MaxQueue' is stored somewhat lazily. Most operations -- take great care to prevent chains of thunks from accumulating along the --- spine to the detriment of performance. However, 'mapU' can leave expensive --- thunks in the structure and repeated applications of that function can --- create thunk chains. +-- spine to the detriment of performance. The only one that doesn't, +-- 'mapU', does not benefit from forcing the spine anyway. Forcing the spine +-- of the result just forces the creation of thunks for all the elements. +{-# DEPRECATED seqSpine "This function is no longer useful." #-} seqSpine :: MaxQueue a -> b -> b seqSpine (MaxQ q) = Min.seqSpine q diff --git a/src/Data/PQueue/Prio/Internals.hs b/src/Data/PQueue/Prio/Internals.hs index 131ec9d..871a21a 100644 --- a/src/Data/PQueue/Prio/Internals.hs +++ b/src/Data/PQueue/Prio/Internals.hs @@ -758,9 +758,11 @@ mapKeysMonoF f fCh ts0 = case ts0 of -- -- Note: The spine of a 'MinPQueue' is stored somewhat lazily. Most operations -- take great care to prevent chains of thunks from accumulating along the --- spine to the detriment of performance. However, 'mapKeysMonotonic' can leave --- expensive thunks in the structure and repeated applications of that function --- can create thunk chains. +-- spine to the detriment of performance. The only ones that don't, +-- 'mapKeysMonotonic', 'mapWithKey', 'traverseWithKey', etc., do not benefit +-- from forcing the spine anyway. Forcing the spine just forces the creation +-- of thunks for all the elements. +{-# DEPRECATED seqSpine "This function is no longer useful." #-} seqSpine :: MinPQueue k a -> b -> b seqSpine Empty z0 = z0 seqSpine (MinPQ _ _ _ ts0) z0 = ts0 `seqSpineF` z0 where diff --git a/src/Data/PQueue/Prio/Max/Internals.hs b/src/Data/PQueue/Prio/Max/Internals.hs index 701bb28..d7bcc5b 100644 --- a/src/Data/PQueue/Prio/Max/Internals.hs +++ b/src/Data/PQueue/Prio/Max/Internals.hs @@ -577,10 +577,12 @@ toListU (MaxPQ q) = fmap (first' unDown) (Q.toListU q) -- | \(O(\log n)\). @seqSpine q r@ forces the spine of @q@ and returns @r@. -- --- Note: The spine of a 'MaxPQueue' is stored somewhat lazily. Most operations +-- Note: The spine of a 'MinPQueue' is stored somewhat lazily. Most operations -- take great care to prevent chains of thunks from accumulating along the --- spine to the detriment of performance. However, 'mapKeysMonotonic' can leave --- expensive thunks in the structure and repeated applications of that function --- can create thunk chains. +-- spine to the detriment of performance. The only ones that don't, +-- 'mapKeysMonotonic', 'mapWithKey', 'traverseWithKey', etc., do not benefit +-- from forcing the spine anyway. Forcing the spine just forces the creation +-- of thunks for all the elements. +{-# DEPRECATED seqSpine "This function is no longer useful." #-} seqSpine :: MaxPQueue k a -> b -> b seqSpine (MaxPQ q) = Q.seqSpine q