on master help sign in
Add window prefix to combinators in Fold.Window module (#2517)
commit96eebafafea2c71458a5e75a4ad38e41c31996c4 authorRanjeet Ranjan <ranjeetr@composewell.com> dateFri 11 Aug 2023, 01:15 (3 years ago) parent8b55b1a
8 files changed+101−104
benchmark/Streamly/Benchmark/Data/Fold/Window.hs+38−38 core/src/DocTestDataFold.hs−1 core/src/DocTestDataStream.hs−1 core/src/Streamly/Internal/Data/Fold.hs+2−2 core/src/Streamly/Internal/Data/Fold/Combinators.hs+3−3 core/src/Streamly/Internal/Data/Fold/Window.hs+50−50 core/streamly-core.cabal+1−1 test/Streamly/Test/Data/Fold/Window.hs+7−8
benchmark/Streamly/Benchmark/Data/Fold/Window.hs+38−38
@@ -8,8 +8,8 @@ import Streamly.Internal.Data.Stream (Stream)
88import System.Random (randomRIO)
99
1010import qualified Streamly.Data.Fold as Fold
11+import qualified Streamly.Internal.Data.Fold as Window
1112import qualified Streamly.Internal.Data.Ring as Ring
12−import qualified Streamly.Internal.Data.Fold.Window as Window
1313import qualified Streamly.Internal.Data.Stream as Stream
1414
1515import Streamly.Benchmark.Common
@@ -70,55 +70,55 @@ o_1_space_folds :: Int -> [Benchmark]
7070o_1_space_folds numElements =
7171 [ bgroup "fold"
7272 [ benchWithFold numElements "minimum (window size 100)"
73− (Window.minimum 100)
73+ (Window.windowMinimum 100)
7474 , benchWithFold numElements "minimum (window size 1000)"
75− (Window.minimum 1000)
75+ (Window.windowMinimum 1000)
7676 , benchWith sourceDescendingInt numElements
7777 "minimum descending (window size 1000)"
78− (Window.minimum 1000)
78+ (Window.windowMinimum 1000)
7979
8080 , benchWithFold numElements "maximum (window size 100)"
81− (Window.maximum 100)
81+ (Window.windowMaximum 100)
8282 , benchWithFold numElements "maximum (window size 1000)"
83− (Window.maximum 1000)
83+ (Window.windowMaximum 1000)
8484 , benchWith sourceDescendingInt numElements
8585 "maximum descending (window size 1000)"
86− (Window.maximum 1000)
86+ (Window.windowMaximum 1000)
8787
8888 , benchWithFold numElements "range (window size 100)"
89− (Window.range 100)
89+ (Window.windowRange 100)
9090 , benchWithFold numElements "range (window size 1000)"
91− (Window.range 1000)
91+ (Window.windowRange 1000)
9292 , benchWith sourceDescendingInt numElements
9393 "range descending (window size 1000)"
94− (Window.range 1000)
94+ (Window.windowRange 1000)
9595
9696 , benchWithFoldInt numElements "sumInt (window size 100)"
97− (Ring.slidingWindow 100 Window.sumInt)
97+ (Ring.slidingWindow 100 Window.windowSumInt)
9898 , benchWithFoldInt numElements "sum for Int (window size 100)"
99− (Ring.slidingWindow 100 Window.sum)
99+ (Ring.slidingWindow 100 Window.windowSum)
100100 , benchWithFold numElements "sum (window size 100)"
101− (Ring.slidingWindow 100 Window.sum)
101+ (Ring.slidingWindow 100 Window.windowSum)
102102 , benchWithFold numElements "sum (window size 1000)"
103− (Ring.slidingWindow 1000 Window.sum)
103+ (Ring.slidingWindow 1000 Window.windowSum)
104104 , benchWithFold numElements "sum (entire stream)"
105− (Window.cumulative Window.sum)
105+ (Window.cumulative Window.windowSum)
106106 , benchWithFold numElements "sum (Data.Fold)"
107107 Fold.sum
108108
109109 , benchWithFold numElements "mean (window size 100)"
110− (Ring.slidingWindow 100 Window.mean)
110+ (Ring.slidingWindow 100 Window.windowMean)
111111 , benchWithFold numElements "mean (window size 1000)"
112− (Ring.slidingWindow 1000 Window.mean)
112+ (Ring.slidingWindow 1000 Window.windowMean)
113113 , benchWithFold numElements "mean (entire stream)"
114− (Window.cumulative Window.mean)
114+ (Window.cumulative Window.windowMean)
115115 , benchWithFold numElements "mean (Data.Fold)"
116116 Fold.mean
117117
118118 , benchWithFold numElements "powerSum 2 (window size 100)"
119− (Ring.slidingWindow 100 (Window.powerSum 2))
119+ (Ring.slidingWindow 100 (Window.windowPowerSum 2))
120120 , benchWithFold numElements "powerSum 2 (entire stream)"
121− (Window.cumulative (Window.powerSum 2))
121+ (Window.cumulative (Window.windowPowerSum 2))
122122
123123 ]
124124 ]
@@ -127,51 +127,51 @@ o_1_space_scans :: Int -> [Benchmark]
127127o_1_space_scans numElements =
128128 [ bgroup "scan"
129129 [ benchWithPostscan numElements "minimum (window size 10)"
130− (Window.minimum 10)
130+ (Window.windowMinimum 10)
131131 -- Below window size 30 the linear search based impl performs better
132132 -- than the dequeue based implementation.
133133 , benchWithPostscan numElements "minimum (window size 30)"
134− (Window.minimum 30)
134+ (Window.windowMinimum 30)
135135 , benchWithPostscan numElements "minimum (window size 1000)"
136− (Window.minimum 1000)
136+ (Window.windowMinimum 1000)
137137 , benchScanWith sourceDescendingInt numElements
138138 "minimum descending (window size 1000)"
139− (Window.minimum 1000)
139+ (Window.windowMinimum 1000)
140140
141141 , benchWithPostscan numElements "maximum (window size 10)"
142− (Window.maximum 10)
142+ (Window.windowMaximum 10)
143143 , benchWithPostscan numElements "maximum (window size 30)"
144− (Window.maximum 30)
144+ (Window.windowMaximum 30)
145145 , benchWithPostscan numElements "maximum (window size 1000)"
146− (Window.maximum 1000)
146+ (Window.windowMaximum 1000)
147147 , benchScanWith sourceDescendingInt numElements
148148 "maximum descending (window size 1000)"
149− (Window.maximum 1000)
149+ (Window.windowMaximum 1000)
150150
151151 , benchWithPostscan numElements "range (window size 10)"
152− (Window.range 10)
152+ (Window.windowRange 10)
153153 , benchWithPostscan numElements "range (window size 30)"
154− (Window.range 30)
154+ (Window.windowRange 30)
155155 , benchWithPostscan numElements "range (window size 1000)"
156− (Window.range 1000)
156+ (Window.windowRange 1000)
157157 , benchScanWith sourceDescendingInt numElements
158158 "range descending (window size 1000)"
159− (Window.range 1000)
159+ (Window.windowRange 1000)
160160
161161 , benchWithPostscan numElements "sum (window size 100)"
162− (Ring.slidingWindow 100 Window.sum)
162+ (Ring.slidingWindow 100 Window.windowSum)
163163 , benchWithPostscan numElements "sum (window size 1000)"
164− (Ring.slidingWindow 1000 Window.sum)
164+ (Ring.slidingWindow 1000 Window.windowSum)
165165
166166 , benchWithPostscan numElements "mean (window size 100)"
167− (Ring.slidingWindow 100 Window.mean)
167+ (Ring.slidingWindow 100 Window.windowMean)
168168 , benchWithPostscan numElements "mean (window size 1000)"
169− (Ring.slidingWindow 1000 Window.mean)
169+ (Ring.slidingWindow 1000 Window.windowMean)
170170
171171 , benchWithPostscan numElements "powerSum 2 (window size 100)"
172− (Ring.slidingWindow 100 (Window.powerSum 2))
172+ (Ring.slidingWindow 100 (Window.windowPowerSum 2))
173173 , benchWithPostscan numElements "powerSum 2 (window size 1000)"
174− (Ring.slidingWindow 1000 (Window.powerSum 2))
174+ (Ring.slidingWindow 1000 (Window.windowPowerSum 2))
175175 ]
176176 ]
177177
core/src/DocTestDataFold.hs−1
@@ -24,5 +24,4 @@
2424For APIs that have not been released yet.
2525
2626>>> import qualified Streamly.Internal.Data.Fold as Fold
27−>>> import qualified Streamly.Internal.Data.Fold.Window as FoldW
2827-}
core/src/DocTestDataStream.hs−1
@@ -30,7 +30,6 @@
3030For APIs that have not been released yet.
3131
3232>>> import qualified Streamly.Internal.Data.Fold as Fold
33−>>> import qualified Streamly.Internal.Data.Fold.Window as Window
3433>>> import qualified Streamly.Internal.Data.Parser as Parser
3534>>> import qualified Streamly.Internal.Data.Stream as Stream
3635>>> import qualified Streamly.Internal.Data.Unfold as Unfold
core/src/Streamly/Internal/Data/Fold.hs+2−2
@@ -20,7 +20,7 @@ module Streamly.Internal.Data.Fold
2020 , module Streamly.Internal.Data.Fold.Tee
2121 , module Streamly.Internal.Data.Fold.Combinators
2222 , module Streamly.Internal.Data.Fold.Container
23− -- , module Streamly.Internal.Data.Fold.Window
23+ , module Streamly.Internal.Data.Fold.Window
2424 )
2525where
2626
@@ -28,6 +28,6 @@ import Streamly.Internal.Data.Fold.Combinators
2828import Streamly.Internal.Data.Fold.Container
2929import Streamly.Internal.Data.Fold.Tee
3030import Streamly.Internal.Data.Fold.Type
31−-- import Streamly.Internal.Data.Fold.Window
31+import Streamly.Internal.Data.Fold.Window
3232
3333#include "DocTestDataFold.hs"
core/src/Streamly/Internal/Data/Fold/Combinators.hs+3−3
@@ -245,7 +245,7 @@ import Streamly.Internal.Data.Stream.StreamD.Type (Stream)
245245import qualified Prelude
246246import qualified Streamly.Internal.Data.MutArray.Type as MA
247247import qualified Streamly.Internal.Data.Array.Type as Array
248−import qualified Streamly.Internal.Data.Fold.Window as FoldW
248+import qualified Streamly.Internal.Data.Fold.Window as Fold
249249import qualified Streamly.Internal.Data.Pipe.Type as Pipe
250250import qualified Streamly.Internal.Data.Ring as Ring
251251import qualified Streamly.Internal.Data.Stream.StreamD.Type as StreamD
@@ -730,7 +730,7 @@ length = lengthGeneric
730730-- identity (@0@) when the stream is empty. Note that this is not numerically
731731-- stable for floating point numbers.
732732--
733−-- >>> sum = FoldW.cumulative FoldW.sum
733+-- >>> sum = Fold.cumulative Fold.windowSum
734734--
735735-- Same as following but numerically stable:
736736--
@@ -739,7 +739,7 @@ length = lengthGeneric
739739--
740740{-# INLINE sum #-}
741741sum :: (Monad m, Num a) => Fold m a a
742−sum = FoldW.cumulative FoldW.sum
742+sum = Fold.cumulative Fold.windowSum
743743
744744-- | Determine the product of all elements of a stream of numbers. Returns
745745-- multiplicative identity (@1@) when the stream is empty. The fold terminates
core/src/Streamly/Internal/Data/Fold/Window.hs+50−50
@@ -36,24 +36,24 @@ module Streamly.Internal.Data.Fold.Window
3636 -- window folds by keeping the second element of the input tuple as
3737 -- @Nothing@.
3838 --
39− lmap
39+ windowLmap
4040 , cumulative
4141
42− , rollingMap
43− , rollingMapM
42+ , windowRollingMap
43+ , windowRollingMapM
4444
4545 -- ** Sums
46− , length
47− , sum
48− , sumInt
49− , powerSum
50− , powerSumFrac
46+ , windowLength
47+ , windowSum
48+ , windowSumInt
49+ , windowPowerSum
50+ , windowPowerSumFrac
5151
5252 -- ** Location
53− , minimum
54− , maximum
55− , range
56− , mean
53+ , windowMinimum
54+ , windowMaximum
55+ , windowRange
56+ , windowMean
5757 )
5858where
5959
@@ -73,7 +73,7 @@ import Prelude hiding (length, sum, minimum, maximum)
7373-- $setup
7474-- >>> import Data.Bifunctor(bimap)
7575-- >>> import qualified Streamly.Data.Fold as Fold
76−-- >>> import qualified Streamly.Internal.Data.Fold.Window as FoldW
76+-- >>> import qualified Streamly.Internal.Data.Fold.Window as Fold
7777-- >>> import qualified Streamly.Internal.Data.Ring as Ring
7878-- >>> import qualified Streamly.Data.Stream as Stream
7979-- >>> import Prelude hiding (length, sum, minimum, maximum)
@@ -87,9 +87,9 @@ import Prelude hiding (length, sum, minimum, maximum)
8787--
8888-- >>> lmap f = Fold.lmap (bimap f (f <$>))
8989--
90−{-# INLINE lmap #-}
91−lmap :: (c -> a) -> Fold m (a, Maybe a) b -> Fold m (c, Maybe c) b
92−lmap f = Fold.lmap (bimap f (f <$>))
90+{-# INLINE windowLmap #-}
91+windowLmap :: (c -> a) -> Fold m (a, Maybe a) b -> Fold m (c, Maybe c) b
92+windowLmap f = Fold.lmap (bimap f (f <$>))
9393
9494-- | Convert an incremental fold to a cumulative fold using the entire input
9595-- stream as a single window.
@@ -105,10 +105,10 @@ cumulative = Fold.lmap (, Nothing)
105105
106106-- | Apply an effectful function on the latest and the oldest element of the
107107-- window.
108−{-# INLINE rollingMapM #-}
109−rollingMapM :: Monad m =>
108+{-# INLINE windowRollingMapM #-}
109+windowRollingMapM :: Monad m =>
110110 (Maybe a -> a -> m (Maybe b)) -> Fold m (a, Maybe a) (Maybe b)
111−rollingMapM f = Fold.foldlM' f1 initial
111+windowRollingMapM f = Fold.foldlM' f1 initial
112112
113113 where
114114
@@ -118,12 +118,12 @@ rollingMapM f = Fold.foldlM' f1 initial
118118
119119-- | Apply a pure function on the latest and the oldest element of the window.
120120--
121−-- >>> rollingMap f = FoldW.rollingMapM (\x y -> return $ f x y)
121+-- >>> windowRollingMap f = Fold.windowRollingMapM (\x y -> return $ f x y)
122122--
123−{-# INLINE rollingMap #-}
124−rollingMap :: Monad m =>
123+{-# INLINE windowRollingMap #-}
124+windowRollingMap :: Monad m =>
125125 (Maybe a -> a -> Maybe b) -> Fold m (a, Maybe a) (Maybe b)
126−rollingMap f = Fold.foldl' f1 initial
126+windowRollingMap f = Fold.foldl' f1 initial
127127
128128 where
129129
@@ -146,9 +146,9 @@ rollingMap f = Fold.foldl' f1 initial
146146--
147147-- /Internal/
148148--
149−{-# INLINE sumInt #-}
150−sumInt :: forall m a. (Monad m, Integral a) => Fold m (a, Maybe a) a
151−sumInt = Fold step initial extract
149+{-# INLINE windowSumInt #-}
150+windowSumInt :: forall m a. (Monad m, Integral a) => Fold m (a, Maybe a) a
151+windowSumInt = Fold step initial extract
152152
153153 where
154154
@@ -180,9 +180,9 @@ sumInt = Fold step initial extract
180180--
181181-- /Time/: \(\mathcal{O}(n)\)
182182--
183−{-# INLINE sum #-}
184−sum :: forall m a. (Monad m, Num a) => Fold m (a, Maybe a) a
185−sum = Fold step initial extract
183+{-# INLINE windowSum #-}
184+windowSum :: forall m a. (Monad m, Num a) => Fold m (a, Maybe a) a
185+windowSum = Fold step initial extract
186186
187187 where
188188
@@ -219,9 +219,9 @@ sum = Fold step initial extract
219219--
220220-- >>> length = powerSum 0
221221--
222−{-# INLINE length #-}
223−length :: (Monad m, Num b) => Fold m (a, Maybe a) b
224−length = Fold.foldl' step 0
222+{-# INLINE windowLength #-}
223+windowLength :: (Monad m, Num b) => Fold m (a, Maybe a) b
224+windowLength = Fold.foldl' step 0
225225
226226 where
227227
@@ -237,18 +237,18 @@ length = Fold.foldl' step 0
237237-- /Space/: \(\mathcal{O}(1)\)
238238--
239239-- /Time/: \(\mathcal{O}(n)\)
240−{-# INLINE powerSum #-}
241−powerSum :: (Monad m, Num a) => Int -> Fold m (a, Maybe a) a
242−powerSum k = lmap (^ k) sum
240+{-# INLINE windowPowerSum #-}
241+windowPowerSum :: (Monad m, Num a) => Int -> Fold m (a, Maybe a) a
242+windowPowerSum k = windowLmap (^ k) windowSum
243243
244244-- | Like 'powerSum' but powers can be negative or fractional. This is slower
245245-- than 'powerSum' for positive intergal powers.
246246--
247247-- >>> powerSumFrac p = lmap (** p) sum
248248--
249−{-# INLINE powerSumFrac #-}
250−powerSumFrac :: (Monad m, Floating a) => a -> Fold m (a, Maybe a) a
251−powerSumFrac p = lmap (** p) sum
249+{-# INLINE windowPowerSumFrac #-}
250+windowPowerSumFrac :: (Monad m, Floating a) => a -> Fold m (a, Maybe a) a
251+windowPowerSumFrac p = windowLmap (** p) windowSum
252252
253253-------------------------------------------------------------------------------
254254-- Location
@@ -265,9 +265,9 @@ powerSumFrac p = lmap (** p) sum
265265--
266266-- /Time/: \(\mathcal{O}(n*w)\) where \(w\) is the window size.
267267--
268−{-# INLINE range #-}
269−range :: (MonadIO m, Storable a, Ord a) => Int -> Fold m a (Maybe (a, a))
270−range n = Fold step initial extract
268+{-# INLINE windowRange #-}
269+windowRange :: (MonadIO m, Storable a, Ord a) => Int -> Fold m a (Maybe (a, a))
270+windowRange n = Fold step initial extract
271271
272272 where
273273
@@ -316,9 +316,9 @@ range n = Fold step initial extract
316316--
317317-- /Time/: \(\mathcal{O}(n*w)\) where \(w\) is the window size.
318318--
319−{-# INLINE minimum #-}
320−minimum :: (MonadIO m, Storable a, Ord a) => Int -> Fold m a (Maybe a)
321−minimum n = fmap (fmap fst) $ range n
319+{-# INLINE windowMinimum #-}
320+windowMinimum :: (MonadIO m, Storable a, Ord a) => Int -> Fold m a (Maybe a)
321+windowMinimum n = fmap (fmap fst) $ windowRange n
322322
323323-- | The maximum element in a rolling window.
324324--
@@ -329,9 +329,9 @@ minimum n = fmap (fmap fst) $ range n
329329--
330330-- /Time/: \(\mathcal{O}(n*w)\) where \(w\) is the window size.
331331--
332−{-# INLINE maximum #-}
333−maximum :: (MonadIO m, Storable a, Ord a) => Int -> Fold m a (Maybe a)
334−maximum n = fmap (fmap snd) $ range n
332+{-# INLINE windowMaximum #-}
333+windowMaximum :: (MonadIO m, Storable a, Ord a) => Int -> Fold m a (Maybe a)
334+windowMaximum n = fmap (fmap snd) $ windowRange n
335335
336336-- | Arithmetic mean of elements in a sliding window:
337337--
@@ -346,6 +346,6 @@ maximum n = fmap (fmap snd) $ range n
346346-- /Space/: \(\mathcal{O}(1)\)
347347--
348348-- /Time/: \(\mathcal{O}(n)\)
349−{-# INLINE mean #-}
350−mean :: forall m a. (Monad m, Fractional a) => Fold m (a, Maybe a) a
351−mean = Fold.teeWith (/) sum length
349+{-# INLINE windowMean #-}
350+windowMean :: forall m a. (Monad m, Fractional a) => Fold m (a, Maybe a) a
351+windowMean = Fold.teeWith (/) windowSum windowLength
core/streamly-core.cabal+1−1
@@ -324,7 +324,6 @@ library
324324 , Streamly.Internal.Data.Unfold
325325 , Streamly.Internal.Data.Fold.Tee
326326 , Streamly.Internal.Data.Fold.Chunked
327− , Streamly.Internal.Data.Fold.Window
328327 , Streamly.Internal.Data.Parser
329328 , Streamly.Internal.Data.Pipe
330329
@@ -411,6 +410,7 @@ library
411410 , Streamly.Internal.Data.Fold.Type
412411 , Streamly.Internal.Data.Fold.Combinators
413412 , Streamly.Internal.Data.Fold.Container
413+ , Streamly.Internal.Data.Fold.Window
414414
415415 , Streamly.Internal.Data.Stream.StreamD.Container
416416 , Streamly.Internal.Data.Stream.StreamD.Eliminate
test/Streamly/Test/Data/Fold/Window.hs+7−8
@@ -1,6 +1,5 @@
11module Streamly.Test.Data.Fold.Window (main) where
22
3−import Streamly.Internal.Data.Fold.Window
43import Test.Hspec (hspec, describe, it, runIO)
54import qualified Streamly.Internal.Data.Ring as Ring
65import qualified Streamly.Internal.Data.Stream as S
@@ -29,8 +28,8 @@ main = hspec $ do
2928 it ("should not deviate more than " ++ show deviationLimit)
3029 $ c1 >= -1 * deviationLimit && c1 <= deviationLimit
3130
32− describe "Sum" $ testFunc sum
33− describe "mean" $ testFunc mean
31+ describe "Sum" $ testFunc Fold.windowSum
32+ describe "mean" $ testFunc Fold.windowMean
3433
3534 describe "Correctness" $ do
3635 let winSize = 3
@@ -53,16 +52,16 @@ main = hspec $ do
5352 it (show tc) $ a == expec
5453
5554 describe "minimum" $ do
56− testFunc2 testCase1 (Just (-2.5)) minimum
55+ testFunc2 testCase1 (Just (-2.5)) Fold.windowMinimum
5756 describe "maximum" $ do
58− testFunc2 testCase1 (Just 7.0) maximum
57+ testFunc2 testCase1 (Just 7.0) Fold.windowMaximum
5958 describe "range" $ do
60− testFunc2 testCase1 (Just (-2.5, 7.0)) range
59+ testFunc2 testCase1 (Just (-2.5, 7.0)) Fold.windowRange
6160 describe "sum" $ do
6261 let scanInf = [1, 2, 3, 4, 5, 12] :: [Double]
6362 scanWin = [1, 2, 3, 3, 3, 9] :: [Double]
64− testFunc testCase2 sum scanInf scanWin
63+ testFunc testCase2 Fold.windowSum scanInf scanWin
6564 describe "mean" $ do
6665 let scanInf = [1, 1, 1, 1, 1, 2] :: [Double]
6766 scanWin = [1, 1, 1, 1, 1, 3] :: [Double]
68− testFunc testCase2 mean scanInf scanWin
67+ testFunc testCase2 Fold.windowMean scanInf scanWin