on master help sign in
Add window prefix to combinators in Fold.Window module (#2517)
96eebafRanjeet Ranjan
benchmark/Streamly/Benchmark/Data/Fold/Window.hs+38−38
@@ -8,8 +8,8 @@ import Streamly.Internal.Data.Stream (Stream)
8import System.Random (randomRIO)
8import System.Random (randomRIO)
9
9
10import qualified Streamly.Data.Fold as Fold
10import qualified Streamly.Data.Fold as Fold
11+import qualified Streamly.Internal.Data.Fold as Window
11import qualified Streamly.Internal.Data.Ring as Ring
12import qualified Streamly.Internal.Data.Ring as Ring
12−import qualified Streamly.Internal.Data.Fold.Window as Window
13import qualified Streamly.Internal.Data.Stream as Stream
13import qualified Streamly.Internal.Data.Stream as Stream
14
14
15import Streamly.Benchmark.Common
15import Streamly.Benchmark.Common
@@ -70,55 +70,55 @@ o_1_space_folds :: Int -> [Benchmark]
70o_1_space_folds numElements =
70o_1_space_folds numElements =
71 [ bgroup "fold"
71 [ bgroup "fold"
72 [ benchWithFold numElements "minimum (window size 100)"
72 [ benchWithFold numElements "minimum (window size 100)"
73− (Window.minimum 100)
73+ (Window.windowMinimum 100)
74 , benchWithFold numElements "minimum (window size 1000)"
74 , benchWithFold numElements "minimum (window size 1000)"
75− (Window.minimum 1000)
75+ (Window.windowMinimum 1000)
76 , benchWith sourceDescendingInt numElements
76 , benchWith sourceDescendingInt numElements
77 "minimum descending (window size 1000)"
77 "minimum descending (window size 1000)"
78− (Window.minimum 1000)
78+ (Window.windowMinimum 1000)
79
79
80 , benchWithFold numElements "maximum (window size 100)"
80 , benchWithFold numElements "maximum (window size 100)"
81− (Window.maximum 100)
81+ (Window.windowMaximum 100)
82 , benchWithFold numElements "maximum (window size 1000)"
82 , benchWithFold numElements "maximum (window size 1000)"
83− (Window.maximum 1000)
83+ (Window.windowMaximum 1000)
84 , benchWith sourceDescendingInt numElements
84 , benchWith sourceDescendingInt numElements
85 "maximum descending (window size 1000)"
85 "maximum descending (window size 1000)"
86− (Window.maximum 1000)
86+ (Window.windowMaximum 1000)
87
87
88 , benchWithFold numElements "range (window size 100)"
88 , benchWithFold numElements "range (window size 100)"
89− (Window.range 100)
89+ (Window.windowRange 100)
90 , benchWithFold numElements "range (window size 1000)"
90 , benchWithFold numElements "range (window size 1000)"
91− (Window.range 1000)
91+ (Window.windowRange 1000)
92 , benchWith sourceDescendingInt numElements
92 , benchWith sourceDescendingInt numElements
93 "range descending (window size 1000)"
93 "range descending (window size 1000)"
94− (Window.range 1000)
94+ (Window.windowRange 1000)
95
95
96 , benchWithFoldInt numElements "sumInt (window size 100)"
96 , benchWithFoldInt numElements "sumInt (window size 100)"
97− (Ring.slidingWindow 100 Window.sumInt)
97+ (Ring.slidingWindow 100 Window.windowSumInt)
98 , benchWithFoldInt numElements "sum for Int (window size 100)"
98 , benchWithFoldInt numElements "sum for Int (window size 100)"
99− (Ring.slidingWindow 100 Window.sum)
99+ (Ring.slidingWindow 100 Window.windowSum)
100 , benchWithFold numElements "sum (window size 100)"
100 , benchWithFold numElements "sum (window size 100)"
101− (Ring.slidingWindow 100 Window.sum)
101+ (Ring.slidingWindow 100 Window.windowSum)
102 , benchWithFold numElements "sum (window size 1000)"
102 , benchWithFold numElements "sum (window size 1000)"
103− (Ring.slidingWindow 1000 Window.sum)
103+ (Ring.slidingWindow 1000 Window.windowSum)
104 , benchWithFold numElements "sum (entire stream)"
104 , benchWithFold numElements "sum (entire stream)"
105− (Window.cumulative Window.sum)
105+ (Window.cumulative Window.windowSum)
106 , benchWithFold numElements "sum (Data.Fold)"
106 , benchWithFold numElements "sum (Data.Fold)"
107 Fold.sum
107 Fold.sum
108
108
109 , benchWithFold numElements "mean (window size 100)"
109 , benchWithFold numElements "mean (window size 100)"
110− (Ring.slidingWindow 100 Window.mean)
110+ (Ring.slidingWindow 100 Window.windowMean)
111 , benchWithFold numElements "mean (window size 1000)"
111 , benchWithFold numElements "mean (window size 1000)"
112− (Ring.slidingWindow 1000 Window.mean)
112+ (Ring.slidingWindow 1000 Window.windowMean)
113 , benchWithFold numElements "mean (entire stream)"
113 , benchWithFold numElements "mean (entire stream)"
114− (Window.cumulative Window.mean)
114+ (Window.cumulative Window.windowMean)
115 , benchWithFold numElements "mean (Data.Fold)"
115 , benchWithFold numElements "mean (Data.Fold)"
116 Fold.mean
116 Fold.mean
117
117
118 , benchWithFold numElements "powerSum 2 (window size 100)"
118 , benchWithFold numElements "powerSum 2 (window size 100)"
119− (Ring.slidingWindow 100 (Window.powerSum 2))
119+ (Ring.slidingWindow 100 (Window.windowPowerSum 2))
120 , benchWithFold numElements "powerSum 2 (entire stream)"
120 , benchWithFold numElements "powerSum 2 (entire stream)"
121− (Window.cumulative (Window.powerSum 2))
121+ (Window.cumulative (Window.windowPowerSum 2))
122
122
123 ]
123 ]
124 ]
124 ]
@@ -127,51 +127,51 @@ o_1_space_scans :: Int -> [Benchmark]
127o_1_space_scans numElements =
127o_1_space_scans numElements =
128 [ bgroup "scan"
128 [ bgroup "scan"
129 [ benchWithPostscan numElements "minimum (window size 10)"
129 [ benchWithPostscan numElements "minimum (window size 10)"
130− (Window.minimum 10)
130+ (Window.windowMinimum 10)
131 -- Below window size 30 the linear search based impl performs better
131 -- Below window size 30 the linear search based impl performs better
132 -- than the dequeue based implementation.
132 -- than the dequeue based implementation.
133 , benchWithPostscan numElements "minimum (window size 30)"
133 , benchWithPostscan numElements "minimum (window size 30)"
134− (Window.minimum 30)
134+ (Window.windowMinimum 30)
135 , benchWithPostscan numElements "minimum (window size 1000)"
135 , benchWithPostscan numElements "minimum (window size 1000)"
136− (Window.minimum 1000)
136+ (Window.windowMinimum 1000)
137 , benchScanWith sourceDescendingInt numElements
137 , benchScanWith sourceDescendingInt numElements
138 "minimum descending (window size 1000)"
138 "minimum descending (window size 1000)"
139− (Window.minimum 1000)
139+ (Window.windowMinimum 1000)
140
140
141 , benchWithPostscan numElements "maximum (window size 10)"
141 , benchWithPostscan numElements "maximum (window size 10)"
142− (Window.maximum 10)
142+ (Window.windowMaximum 10)
143 , benchWithPostscan numElements "maximum (window size 30)"
143 , benchWithPostscan numElements "maximum (window size 30)"
144− (Window.maximum 30)
144+ (Window.windowMaximum 30)
145 , benchWithPostscan numElements "maximum (window size 1000)"
145 , benchWithPostscan numElements "maximum (window size 1000)"
146− (Window.maximum 1000)
146+ (Window.windowMaximum 1000)
147 , benchScanWith sourceDescendingInt numElements
147 , benchScanWith sourceDescendingInt numElements
148 "maximum descending (window size 1000)"
148 "maximum descending (window size 1000)"
149− (Window.maximum 1000)
149+ (Window.windowMaximum 1000)
150
150
151 , benchWithPostscan numElements "range (window size 10)"
151 , benchWithPostscan numElements "range (window size 10)"
152− (Window.range 10)
152+ (Window.windowRange 10)
153 , benchWithPostscan numElements "range (window size 30)"
153 , benchWithPostscan numElements "range (window size 30)"
154− (Window.range 30)
154+ (Window.windowRange 30)
155 , benchWithPostscan numElements "range (window size 1000)"
155 , benchWithPostscan numElements "range (window size 1000)"
156− (Window.range 1000)
156+ (Window.windowRange 1000)
157 , benchScanWith sourceDescendingInt numElements
157 , benchScanWith sourceDescendingInt numElements
158 "range descending (window size 1000)"
158 "range descending (window size 1000)"
159− (Window.range 1000)
159+ (Window.windowRange 1000)
160
160
161 , benchWithPostscan numElements "sum (window size 100)"
161 , benchWithPostscan numElements "sum (window size 100)"
162− (Ring.slidingWindow 100 Window.sum)
162+ (Ring.slidingWindow 100 Window.windowSum)
163 , benchWithPostscan numElements "sum (window size 1000)"
163 , benchWithPostscan numElements "sum (window size 1000)"
164− (Ring.slidingWindow 1000 Window.sum)
164+ (Ring.slidingWindow 1000 Window.windowSum)
165
165
166 , benchWithPostscan numElements "mean (window size 100)"
166 , benchWithPostscan numElements "mean (window size 100)"
167− (Ring.slidingWindow 100 Window.mean)
167+ (Ring.slidingWindow 100 Window.windowMean)
168 , benchWithPostscan numElements "mean (window size 1000)"
168 , benchWithPostscan numElements "mean (window size 1000)"
169− (Ring.slidingWindow 1000 Window.mean)
169+ (Ring.slidingWindow 1000 Window.windowMean)
170
170
171 , benchWithPostscan numElements "powerSum 2 (window size 100)"
171 , benchWithPostscan numElements "powerSum 2 (window size 100)"
172− (Ring.slidingWindow 100 (Window.powerSum 2))
172+ (Ring.slidingWindow 100 (Window.windowPowerSum 2))
173 , benchWithPostscan numElements "powerSum 2 (window size 1000)"
173 , benchWithPostscan numElements "powerSum 2 (window size 1000)"
174− (Ring.slidingWindow 1000 (Window.powerSum 2))
174+ (Ring.slidingWindow 1000 (Window.windowPowerSum 2))
175 ]
175 ]
176 ]
176 ]
177
177
core/src/DocTestDataFold.hs−1
@@ -24,5 +24,4 @@
24For APIs that have not been released yet.
24For APIs that have not been released yet.
25
25
26>>> import qualified Streamly.Internal.Data.Fold as Fold
26>>> import qualified Streamly.Internal.Data.Fold as Fold
27−>>> import qualified Streamly.Internal.Data.Fold.Window as FoldW
28-}
27-}
core/src/DocTestDataStream.hs−1
@@ -30,7 +30,6 @@
30For APIs that have not been released yet.
30For APIs that have not been released yet.
31
31
32>>> import qualified Streamly.Internal.Data.Fold as Fold
32>>> import qualified Streamly.Internal.Data.Fold as Fold
33−>>> import qualified Streamly.Internal.Data.Fold.Window as Window
34>>> import qualified Streamly.Internal.Data.Parser as Parser
33>>> import qualified Streamly.Internal.Data.Parser as Parser
35>>> import qualified Streamly.Internal.Data.Stream as Stream
34>>> import qualified Streamly.Internal.Data.Stream as Stream
36>>> import qualified Streamly.Internal.Data.Unfold as Unfold
35>>> 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
20 , module Streamly.Internal.Data.Fold.Tee
20 , module Streamly.Internal.Data.Fold.Tee
21 , module Streamly.Internal.Data.Fold.Combinators
21 , module Streamly.Internal.Data.Fold.Combinators
22 , module Streamly.Internal.Data.Fold.Container
22 , module Streamly.Internal.Data.Fold.Container
23− -- , module Streamly.Internal.Data.Fold.Window
23+ , module Streamly.Internal.Data.Fold.Window
24 )
24 )
25where
25where
26
26
@@ -28,6 +28,6 @@ import Streamly.Internal.Data.Fold.Combinators
28import Streamly.Internal.Data.Fold.Container
28import Streamly.Internal.Data.Fold.Container
29import Streamly.Internal.Data.Fold.Tee
29import Streamly.Internal.Data.Fold.Tee
30import Streamly.Internal.Data.Fold.Type
30import Streamly.Internal.Data.Fold.Type
31−-- import Streamly.Internal.Data.Fold.Window
31+import Streamly.Internal.Data.Fold.Window
32
32
33#include "DocTestDataFold.hs"
33#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)
245import qualified Prelude
245import qualified Prelude
246import qualified Streamly.Internal.Data.MutArray.Type as MA
246import qualified Streamly.Internal.Data.MutArray.Type as MA
247import qualified Streamly.Internal.Data.Array.Type as Array
247import 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
249import qualified Streamly.Internal.Data.Pipe.Type as Pipe
249import qualified Streamly.Internal.Data.Pipe.Type as Pipe
250import qualified Streamly.Internal.Data.Ring as Ring
250import qualified Streamly.Internal.Data.Ring as Ring
251import qualified Streamly.Internal.Data.Stream.StreamD.Type as StreamD
251import qualified Streamly.Internal.Data.Stream.StreamD.Type as StreamD
@@ -730,7 +730,7 @@ length = lengthGeneric
730-- identity (@0@) when the stream is empty. Note that this is not numerically
730-- identity (@0@) when the stream is empty. Note that this is not numerically
731-- stable for floating point numbers.
731-- stable for floating point numbers.
732--
732--
733−-- >>> sum = FoldW.cumulative FoldW.sum
733+-- >>> sum = Fold.cumulative Fold.windowSum
734--
734--
735-- Same as following but numerically stable:
735-- Same as following but numerically stable:
736--
736--
@@ -739,7 +739,7 @@ length = lengthGeneric
739--
739--
740{-# INLINE sum #-}
740{-# INLINE sum #-}
741sum :: (Monad m, Num a) => Fold m a a
741sum :: (Monad m, Num a) => Fold m a a
742−sum = FoldW.cumulative FoldW.sum
742+sum = Fold.cumulative Fold.windowSum
743
743
744-- | Determine the product of all elements of a stream of numbers. Returns
744-- | Determine the product of all elements of a stream of numbers. Returns
745-- multiplicative identity (@1@) when the stream is empty. The fold terminates
745-- 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
36 -- window folds by keeping the second element of the input tuple as
36 -- window folds by keeping the second element of the input tuple as
37 -- @Nothing@.
37 -- @Nothing@.
38 --
38 --
39− lmap
39+ windowLmap
40 , cumulative
40 , cumulative
41
41
42− , rollingMap
42+ , windowRollingMap
43− , rollingMapM
43+ , windowRollingMapM
44
44
45 -- ** Sums
45 -- ** Sums
46− , length
46+ , windowLength
47− , sum
47+ , windowSum
48− , sumInt
48+ , windowSumInt
49− , powerSum
49+ , windowPowerSum
50− , powerSumFrac
50+ , windowPowerSumFrac
51
51
52 -- ** Location
52 -- ** Location
53− , minimum
53+ , windowMinimum
54− , maximum
54+ , windowMaximum
55− , range
55+ , windowRange
56− , mean
56+ , windowMean
57 )
57 )
58where
58where
59
59
@@ -73,7 +73,7 @@ import Prelude hiding (length, sum, minimum, maximum)
73-- $setup
73-- $setup
74-- >>> import Data.Bifunctor(bimap)
74-- >>> import Data.Bifunctor(bimap)
75-- >>> import qualified Streamly.Data.Fold as Fold
75-- >>> 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
77-- >>> import qualified Streamly.Internal.Data.Ring as Ring
77-- >>> import qualified Streamly.Internal.Data.Ring as Ring
78-- >>> import qualified Streamly.Data.Stream as Stream
78-- >>> import qualified Streamly.Data.Stream as Stream
79-- >>> import Prelude hiding (length, sum, minimum, maximum)
79-- >>> import Prelude hiding (length, sum, minimum, maximum)
@@ -87,9 +87,9 @@ import Prelude hiding (length, sum, minimum, maximum)
87--
87--
88-- >>> lmap f = Fold.lmap (bimap f (f <$>))
88-- >>> lmap f = Fold.lmap (bimap f (f <$>))
89--
89--
90−{-# INLINE lmap #-}
90+{-# INLINE windowLmap #-}
91−lmap :: (c -> a) -> Fold m (a, Maybe a) b -> Fold m (c, Maybe c) b
91+windowLmap :: (c -> a) -> Fold m (a, Maybe a) b -> Fold m (c, Maybe c) b
92−lmap f = Fold.lmap (bimap f (f <$>))
92+windowLmap f = Fold.lmap (bimap f (f <$>))
93
93
94-- | Convert an incremental fold to a cumulative fold using the entire input
94-- | Convert an incremental fold to a cumulative fold using the entire input
95-- stream as a single window.
95-- stream as a single window.
@@ -105,10 +105,10 @@ cumulative = Fold.lmap (, Nothing)
105
105
106-- | Apply an effectful function on the latest and the oldest element of the
106-- | Apply an effectful function on the latest and the oldest element of the
107-- window.
107-- window.
108−{-# INLINE rollingMapM #-}
108+{-# INLINE windowRollingMapM #-}
109−rollingMapM :: Monad m =>
109+windowRollingMapM :: Monad m =>
110 (Maybe a -> a -> m (Maybe b)) -> Fold m (a, Maybe a) (Maybe b)
110 (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
112
112
113 where
113 where
114
114
@@ -118,12 +118,12 @@ rollingMapM f = Fold.foldlM' f1 initial
118
118
119-- | Apply a pure function on the latest and the oldest element of the window.
119-- | Apply a pure function on the latest and the oldest element of the window.
120--
120--
121−-- >>> rollingMap f = FoldW.rollingMapM (\x y -> return $ f x y)
121+-- >>> windowRollingMap f = Fold.windowRollingMapM (\x y -> return $ f x y)
122--
122--
123−{-# INLINE rollingMap #-}
123+{-# INLINE windowRollingMap #-}
124−rollingMap :: Monad m =>
124+windowRollingMap :: Monad m =>
125 (Maybe a -> a -> Maybe b) -> Fold m (a, Maybe a) (Maybe b)
125 (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
127
127
128 where
128 where
129
129
@@ -146,9 +146,9 @@ rollingMap f = Fold.foldl' f1 initial
146--
146--
147-- /Internal/
147-- /Internal/
148--
148--
149−{-# INLINE sumInt #-}
149+{-# INLINE windowSumInt #-}
150−sumInt :: forall m a. (Monad m, Integral a) => Fold m (a, Maybe a) a
150+windowSumInt :: forall m a. (Monad m, Integral a) => Fold m (a, Maybe a) a
151−sumInt = Fold step initial extract
151+windowSumInt = Fold step initial extract
152
152
153 where
153 where
154
154
@@ -180,9 +180,9 @@ sumInt = Fold step initial extract
180--
180--
181-- /Time/: \(\mathcal{O}(n)\)
181-- /Time/: \(\mathcal{O}(n)\)
182--
182--
183−{-# INLINE sum #-}
183+{-# INLINE windowSum #-}
184−sum :: forall m a. (Monad m, Num a) => Fold m (a, Maybe a) a
184+windowSum :: forall m a. (Monad m, Num a) => Fold m (a, Maybe a) a
185−sum = Fold step initial extract
185+windowSum = Fold step initial extract
186
186
187 where
187 where
188
188
@@ -219,9 +219,9 @@ sum = Fold step initial extract
219--
219--
220-- >>> length = powerSum 0
220-- >>> length = powerSum 0
221--
221--
222−{-# INLINE length #-}
222+{-# INLINE windowLength #-}
223−length :: (Monad m, Num b) => Fold m (a, Maybe a) b
223+windowLength :: (Monad m, Num b) => Fold m (a, Maybe a) b
224−length = Fold.foldl' step 0
224+windowLength = Fold.foldl' step 0
225
225
226 where
226 where
227
227
@@ -237,18 +237,18 @@ length = Fold.foldl' step 0
237-- /Space/: \(\mathcal{O}(1)\)
237-- /Space/: \(\mathcal{O}(1)\)
238--
238--
239-- /Time/: \(\mathcal{O}(n)\)
239-- /Time/: \(\mathcal{O}(n)\)
240−{-# INLINE powerSum #-}
240+{-# INLINE windowPowerSum #-}
241−powerSum :: (Monad m, Num a) => Int -> Fold m (a, Maybe a) a
241+windowPowerSum :: (Monad m, Num a) => Int -> Fold m (a, Maybe a) a
242−powerSum k = lmap (^ k) sum
242+windowPowerSum k = windowLmap (^ k) windowSum
243
243
244-- | Like 'powerSum' but powers can be negative or fractional. This is slower
244-- | Like 'powerSum' but powers can be negative or fractional. This is slower
245-- than 'powerSum' for positive intergal powers.
245-- than 'powerSum' for positive intergal powers.
246--
246--
247-- >>> powerSumFrac p = lmap (** p) sum
247-- >>> powerSumFrac p = lmap (** p) sum
248--
248--
249−{-# INLINE powerSumFrac #-}
249+{-# INLINE windowPowerSumFrac #-}
250−powerSumFrac :: (Monad m, Floating a) => a -> Fold m (a, Maybe a) a
250+windowPowerSumFrac :: (Monad m, Floating a) => a -> Fold m (a, Maybe a) a
251−powerSumFrac p = lmap (** p) sum
251+windowPowerSumFrac p = windowLmap (** p) windowSum
252
252
253-------------------------------------------------------------------------------
253-------------------------------------------------------------------------------
254-- Location
254-- Location
@@ -265,9 +265,9 @@ powerSumFrac p = lmap (** p) sum
265--
265--
266-- /Time/: \(\mathcal{O}(n*w)\) where \(w\) is the window size.
266-- /Time/: \(\mathcal{O}(n*w)\) where \(w\) is the window size.
267--
267--
268−{-# INLINE range #-}
268+{-# INLINE windowRange #-}
269−range :: (MonadIO m, Storable a, Ord a) => Int -> Fold m a (Maybe (a, a))
269+windowRange :: (MonadIO m, Storable a, Ord a) => Int -> Fold m a (Maybe (a, a))
270−range n = Fold step initial extract
270+windowRange n = Fold step initial extract
271
271
272 where
272 where
273
273
@@ -316,9 +316,9 @@ range n = Fold step initial extract
316--
316--
317-- /Time/: \(\mathcal{O}(n*w)\) where \(w\) is the window size.
317-- /Time/: \(\mathcal{O}(n*w)\) where \(w\) is the window size.
318--
318--
319−{-# INLINE minimum #-}
319+{-# INLINE windowMinimum #-}
320−minimum :: (MonadIO m, Storable a, Ord a) => Int -> Fold m a (Maybe a)
320+windowMinimum :: (MonadIO m, Storable a, Ord a) => Int -> Fold m a (Maybe a)
321−minimum n = fmap (fmap fst) $ range n
321+windowMinimum n = fmap (fmap fst) $ windowRange n
322
322
323-- | The maximum element in a rolling window.
323-- | The maximum element in a rolling window.
324--
324--
@@ -329,9 +329,9 @@ minimum n = fmap (fmap fst) $ range n
329--
329--
330-- /Time/: \(\mathcal{O}(n*w)\) where \(w\) is the window size.
330-- /Time/: \(\mathcal{O}(n*w)\) where \(w\) is the window size.
331--
331--
332−{-# INLINE maximum #-}
332+{-# INLINE windowMaximum #-}
333−maximum :: (MonadIO m, Storable a, Ord a) => Int -> Fold m a (Maybe a)
333+windowMaximum :: (MonadIO m, Storable a, Ord a) => Int -> Fold m a (Maybe a)
334−maximum n = fmap (fmap snd) $ range n
334+windowMaximum n = fmap (fmap snd) $ windowRange n
335
335
336-- | Arithmetic mean of elements in a sliding window:
336-- | Arithmetic mean of elements in a sliding window:
337--
337--
@@ -346,6 +346,6 @@ maximum n = fmap (fmap snd) $ range n
346-- /Space/: \(\mathcal{O}(1)\)
346-- /Space/: \(\mathcal{O}(1)\)
347--
347--
348-- /Time/: \(\mathcal{O}(n)\)
348-- /Time/: \(\mathcal{O}(n)\)
349−{-# INLINE mean #-}
349+{-# INLINE windowMean #-}
350−mean :: forall m a. (Monad m, Fractional a) => Fold m (a, Maybe a) a
350+windowMean :: forall m a. (Monad m, Fractional a) => Fold m (a, Maybe a) a
351−mean = Fold.teeWith (/) sum length
351+windowMean = Fold.teeWith (/) windowSum windowLength
core/streamly-core.cabal+1−1
@@ -324,7 +324,6 @@ library
324 , Streamly.Internal.Data.Unfold
324 , Streamly.Internal.Data.Unfold
325 , Streamly.Internal.Data.Fold.Tee
325 , Streamly.Internal.Data.Fold.Tee
326 , Streamly.Internal.Data.Fold.Chunked
326 , Streamly.Internal.Data.Fold.Chunked
327− , Streamly.Internal.Data.Fold.Window
328 , Streamly.Internal.Data.Parser
327 , Streamly.Internal.Data.Parser
329 , Streamly.Internal.Data.Pipe
328 , Streamly.Internal.Data.Pipe
330
329
@@ -411,6 +410,7 @@ library
411 , Streamly.Internal.Data.Fold.Type
410 , Streamly.Internal.Data.Fold.Type
412 , Streamly.Internal.Data.Fold.Combinators
411 , Streamly.Internal.Data.Fold.Combinators
413 , Streamly.Internal.Data.Fold.Container
412 , Streamly.Internal.Data.Fold.Container
413+ , Streamly.Internal.Data.Fold.Window
414
414
415 , Streamly.Internal.Data.Stream.StreamD.Container
415 , Streamly.Internal.Data.Stream.StreamD.Container
416 , Streamly.Internal.Data.Stream.StreamD.Eliminate
416 , Streamly.Internal.Data.Stream.StreamD.Eliminate
test/Streamly/Test/Data/Fold/Window.hs+7−8
@@ -1,6 +1,5 @@
1module Streamly.Test.Data.Fold.Window (main) where
1module Streamly.Test.Data.Fold.Window (main) where
2
2
3−import Streamly.Internal.Data.Fold.Window
4import Test.Hspec (hspec, describe, it, runIO)
3import Test.Hspec (hspec, describe, it, runIO)
5import qualified Streamly.Internal.Data.Ring as Ring
4import qualified Streamly.Internal.Data.Ring as Ring
6import qualified Streamly.Internal.Data.Stream as S
5import qualified Streamly.Internal.Data.Stream as S
@@ -29,8 +28,8 @@ main = hspec $ do
29 it ("should not deviate more than " ++ show deviationLimit)
28 it ("should not deviate more than " ++ show deviationLimit)
30 $ c1 >= -1 * deviationLimit && c1 <= deviationLimit
29 $ c1 >= -1 * deviationLimit && c1 <= deviationLimit
31
30
32− describe "Sum" $ testFunc sum
31+ describe "Sum" $ testFunc Fold.windowSum
33− describe "mean" $ testFunc mean
32+ describe "mean" $ testFunc Fold.windowMean
34
33
35 describe "Correctness" $ do
34 describe "Correctness" $ do
36 let winSize = 3
35 let winSize = 3
@@ -53,16 +52,16 @@ main = hspec $ do
53 it (show tc) $ a == expec
52 it (show tc) $ a == expec
54
53
55 describe "minimum" $ do
54 describe "minimum" $ do
56− testFunc2 testCase1 (Just (-2.5)) minimum
55+ testFunc2 testCase1 (Just (-2.5)) Fold.windowMinimum
57 describe "maximum" $ do
56 describe "maximum" $ do
58− testFunc2 testCase1 (Just 7.0) maximum
57+ testFunc2 testCase1 (Just 7.0) Fold.windowMaximum
59 describe "range" $ do
58 describe "range" $ do
60− testFunc2 testCase1 (Just (-2.5, 7.0)) range
59+ testFunc2 testCase1 (Just (-2.5, 7.0)) Fold.windowRange
61 describe "sum" $ do
60 describe "sum" $ do
62 let scanInf = [1, 2, 3, 4, 5, 12] :: [Double]
61 let scanInf = [1, 2, 3, 4, 5, 12] :: [Double]
63 scanWin = [1, 2, 3, 3, 3, 9] :: [Double]
62 scanWin = [1, 2, 3, 3, 3, 9] :: [Double]
64− testFunc testCase2 sum scanInf scanWin
63+ testFunc testCase2 Fold.windowSum scanInf scanWin
65 describe "mean" $ do
64 describe "mean" $ do
66 let scanInf = [1, 1, 1, 1, 1, 2] :: [Double]
65 let scanInf = [1, 1, 1, 1, 1, 2] :: [Double]
67 scanWin = [1, 1, 1, 1, 1, 3] :: [Double]
66 scanWin = [1, 1, 1, 1, 1, 3] :: [Double]
68− testFunc testCase2 mean scanInf scanWin
67+ testFunc testCase2 Fold.windowMean scanInf scanWin