on master help sign in
Add composed benches for streamd/k and compare them
commit172efa65824ebf26f3f1cf8b026f1079522bbc83 authorHarendra Kumar <harendra.kumar@gmail.com> dateMon 29 Oct 2018, 19:02 (8 years ago) parent615197d
5 files changed+246−168
benchmark/BaseStreams.hs+74−49 benchmark/Chart.hs+30−11 benchmark/StreamDOps.hs+68−53 benchmark/StreamKOps.hs+69−55 src/Streamly/Streams/StreamD.hs+5
benchmark/BaseStreams.hs+74−49
@@ -43,41 +43,52 @@ main =
4343 -- , benchIO "fromFoldableM" D.sourceFromFoldableM
4444 ]
4545 , bgroup "elimination"
46− [ benchIO "toNull" D.toNull D.sourceUnfoldrM
47− , benchIO "uncons" D.uncons D.sourceUnfoldrM
48− , benchFold "tail" D.tail D.sourceUnfoldrM
46+ [ benchIO "toNull" D.toNull D.sourceUnfoldrM
47+ , benchIO "uncons" D.uncons D.sourceUnfoldrM
48+ , benchFold "tail" D.tail D.sourceUnfoldrM
4949 , benchIO "nullTail" D.nullTail D.sourceUnfoldrM
5050 , benchIO "headTail" D.headTail D.sourceUnfoldrM
5151 ]
5252 , bgroup "transformation"
53− [ benchIO "scanlM'" D.scan D.sourceUnfoldrM
54− , benchIO "map" D.map D.sourceUnfoldrM
55− , benchIO "mapM" D.mapM D.sourceUnfoldrM
53+ [ benchIO "scan" (D.scan 1) D.sourceUnfoldrM
54+ , benchIO "map" (D.map 1) D.sourceUnfoldrM
55+ , benchIO "mapM" (D.mapM 1) D.sourceUnfoldrM
56+ ]
57+ , bgroup "transformationN"
58+ [ benchIO "scan" (D.scan 4) D.sourceUnfoldrM
59+ , benchIO "map" (D.map 4) D.sourceUnfoldrM
60+ , benchIO "mapM" (D.mapM 4) D.sourceUnfoldrM
5661 ]
5762 , bgroup "filtering"
58− [ benchIO "filter-even" D.filterEven D.sourceUnfoldrM
59− , benchIO "filter-all-out" D.filterAllOut D.sourceUnfoldrM
60− , benchIO "filter-all-in" D.filterAllIn D.sourceUnfoldrM
61− , benchIO "take-all" D.takeAll D.sourceUnfoldrM
62− , benchIO "takeWhile-true" D.takeWhileTrue D.sourceUnfoldrM
63− , benchIO "drop-all" D.dropAll D.sourceUnfoldrM
64− , benchIO "dropWhile-true" D.dropWhileTrue D.sourceUnfoldrM
63+ [ benchIO "filter-even" (D.filterEven 1) D.sourceUnfoldrM
64+ , benchIO "filter-all-out" (D.filterAllOut 1) D.sourceUnfoldrM
65+ , benchIO "filter-all-in" (D.filterAllIn 1) D.sourceUnfoldrM
66+ , benchIO "take-all" (D.takeAll 1) D.sourceUnfoldrM
67+ , benchIO "takeWhile-true" (D.takeWhileTrue 1) D.sourceUnfoldrM
68+ , benchIO "drop-all" (D.dropAll 1) D.sourceUnfoldrM
69+ , benchIO "dropWhile-true" (D.dropWhileTrue 1) D.sourceUnfoldrM
6570 ]
66− , benchIO "zip" D.zip D.sourceUnfoldrM
67− , bgroup "compose"
68− [ benchIO "mapM" D.composeMapM D.sourceUnfoldrM
69−#if __GLASGOW_HASKELL__ != 802
70− , benchIO "map-with-all-in-filter" D.composeMapAllInFilter D.sourceUnfoldrM
71− , benchIO "all-in-filters" D.composeAllInFilters D.sourceUnfoldrM
72− , benchIO "all-out-filters" D.composeAllOutFilters D.sourceUnfoldrM
73−#endif
71+ , bgroup "filteringN"
72+ [ benchIO "filter-even" (D.filterEven 4) D.sourceUnfoldrM
73+ , benchIO "filter-all-out" (D.filterAllOut 4) D.sourceUnfoldrM
74+ , benchIO "filter-all-in" (D.filterAllIn 4) D.sourceUnfoldrM
75+ , benchIO "take-all" (D.takeAll 4) D.sourceUnfoldrM
76+ , benchIO "takeWhile-true" (D.takeWhileTrue 4) D.sourceUnfoldrM
77+ , benchIO "drop-all" (D.dropAll 4) D.sourceUnfoldrM
78+ , benchIO "dropWhile-true" (D.dropWhileTrue 4) D.sourceUnfoldrM
7479 ]
75− -- Scaling with same operation in sequence
76− , bgroup "compose-scaling"
77− [ benchIO "1" (D.composeScaling 1) D.sourceUnfoldrM
78− , benchIO "2" (D.composeScaling 2) D.sourceUnfoldrM
79− , benchIO "3" (D.composeScaling 3) D.sourceUnfoldrM
80− , benchIO "4" (D.composeScaling 4) D.sourceUnfoldrM
80+ , benchIO "zip" D.zip D.sourceUnfoldrM
81+ , bgroup "composed"
82+ [ benchIO "scan-map" (D.scanMap 4) D.sourceUnfoldrM
83+ , benchIO "drop-map" (D.dropMap 4) D.sourceUnfoldrM
84+ , benchIO "drop-scan" (D.dropScan 4) D.sourceUnfoldrM
85+ , benchIO "take-drop" (D.takeDrop 4) D.sourceUnfoldrM
86+ , benchIO "take-scan" (D.takeScan 4) D.sourceUnfoldrM
87+ , benchIO "take-map" (D.takeMap 4) D.sourceUnfoldrM
88+ , benchIO "filter-drop" (D.filterDrop 4) D.sourceUnfoldrM
89+ , benchIO "filter-take" (D.filterTake 4) D.sourceUnfoldrM
90+ , benchIO "filter-scan" (D.filterScan 4) D.sourceUnfoldrM
91+ , benchIO "filter-map" (D.filterMap 4) D.sourceUnfoldrM
8192 ]
8293 ]
8394 , bgroup "streamK"
@@ -105,33 +116,47 @@ main =
105116 , benchFold "last" K.last K.sourceUnfoldrM
106117 ]
107118 , bgroup "transformation"
108− [ benchIO "scan" K.scan K.sourceUnfoldrM
109− , benchIO "map" K.map K.sourceUnfoldrM
110− , benchIO "mapM" K.mapM K.sourceUnfoldrM
119+ [ benchIO "scan" (K.scan 1) K.sourceUnfoldrM
120+ , benchIO "map" (K.map 1) K.sourceUnfoldrM
121+ , benchIO "mapM" (K.mapM 1) K.sourceUnfoldrM
122+ -- , benchIO "concat" K.concat K.sourceUnfoldrM
123+ ]
124+ , bgroup "transformationN"
125+ [ benchIO "scan" (K.scan 4) K.sourceUnfoldrM
126+ , benchIO "map" (K.map 4) K.sourceUnfoldrM
127+ , benchIO "mapM" (K.mapM 4) K.sourceUnfoldrM
111128 -- , benchIO "concat" K.concat K.sourceUnfoldrM
112129 ]
113130 , bgroup "filtering"
114− [ benchIO "filter-even" K.filterEven K.sourceUnfoldrM
115− , benchIO "filter-all-out" K.filterAllOut K.sourceUnfoldrM
116− , benchIO "filter-all-in" K.filterAllIn K.sourceUnfoldrM
117− , benchIO "take-all" K.takeAll K.sourceUnfoldrM
118− , benchIO "takeWhile-true" K.takeWhileTrue K.sourceUnfoldrM
119− , benchIO "drop-all" K.dropAll K.sourceUnfoldrM
120− , benchIO "dropWhile-true" K.dropWhileTrue K.sourceUnfoldrM
131+ [ benchIO "filter-even" (K.filterEven 1) K.sourceUnfoldrM
132+ , benchIO "filter-all-out" (K.filterAllOut 1) K.sourceUnfoldrM
133+ , benchIO "filter-all-in" (K.filterAllIn 1) K.sourceUnfoldrM
134+ , benchIO "take-all" (K.takeAll 1) K.sourceUnfoldrM
135+ , benchIO "takeWhile-true" (K.takeWhileTrue 1) K.sourceUnfoldrM
136+ , benchIO "drop-all" (K.dropAll 1) K.sourceUnfoldrM
137+ , benchIO "dropWhile-true" (K.dropWhileTrue 1) K.sourceUnfoldrM
121138 ]
122− , benchIO "zip" K.zip K.sourceUnfoldrM
123− , bgroup "compose"
124− [ benchIO "mapM" K.composeMapM K.sourceUnfoldrM
125− , benchIO "map-with-all-in-filter" K.composeMapAllInFilter K.sourceUnfoldrM
126− , benchIO "all-in-filters" K.composeAllInFilters K.sourceUnfoldrM
127− , benchIO "all-out-filters" K.composeAllOutFilters K.sourceUnfoldrM
139+ , bgroup "filteringN"
140+ [ benchIO "filter-even" (K.filterEven 4) K.sourceUnfoldrM
141+ , benchIO "filter-all-out" (K.filterAllOut 4) K.sourceUnfoldrM
142+ , benchIO "filter-all-in" (K.filterAllIn 4) K.sourceUnfoldrM
143+ , benchIO "take-all" (K.takeAll 4) K.sourceUnfoldrM
144+ , benchIO "takeWhile-true" (K.takeWhileTrue 4) K.sourceUnfoldrM
145+ , benchIO "drop-all" (K.dropAll 4) K.sourceUnfoldrM
146+ , benchIO "dropWhile-true" (K.dropWhileTrue 4) K.sourceUnfoldrM
128147 ]
129− -- Scaling with same operation in sequence
130− , bgroup "compose-scaling"
131− [ benchIO "1" (K.composeScaling 1) K.sourceUnfoldrM
132− , benchIO "2" (K.composeScaling 2) K.sourceUnfoldrM
133− , benchIO "3" (K.composeScaling 3) K.sourceUnfoldrM
134− , benchIO "4" (K.composeScaling 4) K.sourceUnfoldrM
148+ , benchIO "zip" K.zip K.sourceUnfoldrM
149+ , bgroup "composed"
150+ [ benchIO "scan-map" (K.scanMap 4) K.sourceUnfoldrM
151+ , benchIO "drop-map" (K.dropMap 4) K.sourceUnfoldrM
152+ , benchIO "drop-scan" (K.dropScan 4) K.sourceUnfoldrM
153+ , benchIO "take-drop" (K.takeDrop 4) K.sourceUnfoldrM
154+ , benchIO "take-scan" (K.takeScan 4) K.sourceUnfoldrM
155+ , benchIO "take-map" (K.takeMap 4) K.sourceUnfoldrM
156+ , benchIO "filter-drop" (K.filterDrop 4) K.sourceUnfoldrM
157+ , benchIO "filter-take" (K.filterTake 4) K.sourceUnfoldrM
158+ , benchIO "filter-scan" (K.filterScan 4) K.sourceUnfoldrM
159+ , benchIO "filter-map" (K.filterMap 4) K.sourceUnfoldrM
135160 ]
136161 ]
137162 ]
benchmark/Chart.hs+30−11
@@ -174,20 +174,39 @@ makeBaseGraphs cfg inputFile = do
174174-- text reports
175175------------------------------------------------------------------------------
176176
177+selectBench :: (SortColumn -> Either String [(String, Double)]) -> [String]
178+selectBench f =
179+ reverse
180+ $ fmap fst
181+ $ either
182+ (const $ either error id $ f $ ColumnIndex 0)
183+ (sortOn snd)
184+ $ f $ ColumnIndex 1
185+
177186benchShow Options{..} cfg func inp out =
178187 if genGraphs
179188 then func cfg {outputDir = Just out} inp
180− else
181− ignoringErr $ report inp Nothing $ cfg
182− { selectBenchmarks =
183− \f ->
184− reverse
185− $ fmap fst
186− $ either
187− (const $ either error id $ f $ ColumnIndex 0)
188− (sortOn snd)
189− $ f $ ColumnIndex 1
189+ else ignoringErr $ report inp Nothing $ cfg
190+ { selectBenchmarks = selectBench }
191+
192+showStreamDVsK Options{..} cfg func inp out =
193+ let cfg' = cfg
194+ { classifyBenchmark = classify
195+ , selectBenchmarks = selectBench
190196 }
197+ in if genGraphs
198+ then ignoringErr $ graph inp "streamD-vs-streamK"
199+ cfg' {outputDir = Just out}
200+ else ignoringErr $ report inp Nothing cfg'
201+
202+ where
203+ classify b =
204+ if "streamD/" `isPrefixOf` b
205+ then fmap ("streamD",) $ stripPrefix "streamD/" b
206+ else
207+ if "streamK/" `isPrefixOf` b
208+ then fmap ("streamK",) $ stripPrefix "streamK/" b
209+ else Nothing
191210
192211main :: IO ()
193212main = do
@@ -212,6 +231,6 @@ main = do
212231 Nested -> benchShow opts cfg makeNestedGraphs
213232 "charts/nested/results.csv"
214233 "charts/nested"
215− Base -> benchShow opts cfg makeBaseGraphs
234+ Base -> showStreamDVsK opts cfg makeBaseGraphs
216235 "charts/base/results.csv"
217236 "charts/base"
benchmark/StreamDOps.hs+68−53
@@ -13,7 +13,8 @@ import Control.Monad (when)
1313import Data.Maybe (isJust)
1414import Prelude
1515 (Monad, Int, (+), ($), (.), return, (>), even, (<=),
16− subtract, undefined, Maybe(..), not, mapM_, (>>=))
16+ subtract, undefined, Maybe(..), not, mapM_, (>>=),
17+ maxBound)
1718
1819import qualified Streamly.Streams.StreamD as S
1920
@@ -28,33 +29,15 @@ maxValue = value + 1000
2829{-# INLINE uncons #-}
2930{-# INLINE nullTail #-}
3031{-# INLINE headTail #-}
31−{-# INLINE scan #-}
32−{-# INLINE map #-}
33−{-# INLINE filterEven #-}
34−{-# INLINE filterAllOut #-}
35−{-# INLINE filterAllIn #-}
36−{-# INLINE takeOne #-}
37−{-# INLINE takeAll #-}
38−{-# INLINE takeWhileTrue #-}
39−{-# INLINE dropAll #-}
40−{-# INLINE dropWhileTrue #-}
4132{-# INLINE zip #-}
4233{-
4334{-# INLINE concat #-}
4435-}
45−{-# INLINE composeAllInFilters #-}
46−{-# INLINE composeAllOutFilters #-}
47−{-# INLINE composeMapAllInFilter #-}
48−uncons, nullTail, headTail, map, scan, filterEven, filterAllOut,
49− filterAllIn, takeOne, takeAll, takeWhileTrue, dropAll, dropWhileTrue, zip,
36+uncons, nullTail, headTail, zip
5037 -- concat,
51− composeAllInFilters, composeAllOutFilters, composeMapAllInFilter
5238 :: Monad m
5339 => Stream m Int -> m ()
5440
55−{-# INLINE composeMapM #-}
56−composeMapM :: Monad m => Stream m Int -> m ()
57−
5841{-# INLINE toList #-}
5942toList :: Monad m => Stream m Int -> m [Int]
6043{-# INLINE foldl #-}
@@ -63,8 +46,7 @@ foldl :: Monad m => Stream m Int -> m Int
6346last :: Monad m => Stream m Int -> m (Maybe Int)
6447
6548{-# INLINE toNull #-}
66−{-# INLINE mapM #-}
67−toNull, mapM :: Monad m => Stream m Int -> m ()
49+toNull :: Monad m => Stream m Int -> m ()
6850
6951-------------------------------------------------------------------------------
7052-- Stream generation and elimination
@@ -144,17 +126,45 @@ last = S.last
144126transform :: Monad m => Stream m a -> m ()
145127transform = runStream
146128
147−scan = transform . S.scanlM' (\a b -> return (a + b)) 0
148−map = transform . S.map (+1)
149−mapM = transform . S.mapM return
150−filterEven = transform . S.filter even
151−filterAllOut = transform . S.filter (> maxValue)
152−filterAllIn = transform . S.filter (<= maxValue)
153−takeOne = transform . S.take 1
154−takeAll = transform . S.take maxValue
155−takeWhileTrue = transform . S.takeWhile (<= maxValue)
156−dropAll = transform . S.drop maxValue
157−dropWhileTrue = transform . S.dropWhile (<= maxValue)
129+{-# INLINE composeN #-}
130+composeN
131+ :: Monad m
132+ => Int -> (Stream m Int -> Stream m Int) -> Stream m Int -> m ()
133+composeN n f =
134+ case n of
135+ 1 -> transform . f
136+ 2 -> transform . f . f
137+ 3 -> transform . f . f . f
138+ 4 -> transform . f . f . f . f
139+ _ -> undefined
140+
141+{-# INLINE scan #-}
142+{-# INLINE map #-}
143+{-# INLINE mapM #-}
144+{-# INLINE filterEven #-}
145+{-# INLINE filterAllOut #-}
146+{-# INLINE filterAllIn #-}
147+{-# INLINE takeOne #-}
148+{-# INLINE takeAll #-}
149+{-# INLINE takeWhileTrue #-}
150+{-# INLINE dropAll #-}
151+{-# INLINE dropWhileTrue #-}
152+scan, map, mapM, filterEven, filterAllOut,
153+ filterAllIn, takeOne, takeAll, takeWhileTrue, dropAll, dropWhileTrue
154+ :: Monad m
155+ => Int -> Stream m Int -> m ()
156+
157+scan n = composeN n $ S.scanl' (+) 0
158+map n = composeN n $ S.map (+1)
159+mapM n = composeN n $ S.mapM return
160+filterEven n = composeN n $ S.filter even
161+filterAllOut n = composeN n $ S.filter (> maxValue)
162+filterAllIn n = composeN n $ S.filter (<= maxValue)
163+takeOne n = composeN n $ S.take 1
164+takeAll n = composeN n $ S.take maxValue
165+takeWhileTrue n = composeN n $ S.takeWhile (<= maxValue)
166+dropAll n = composeN n $ S.drop maxValue
167+dropWhileTrue n = composeN n $ S.dropWhile (<= maxValue)
158168
159169-------------------------------------------------------------------------------
160170-- Zipping and concat
@@ -164,25 +174,30 @@ zip src = transform $ S.zipWith (,) src src
164174-- concat _n = return ()
165175
166176-------------------------------------------------------------------------------
167−-- Composition
177+-- Mixed Composition
168178-------------------------------------------------------------------------------
169179
170−{-# INLINE compose #-}
171−compose :: Monad m => (Stream m Int -> Stream m Int) -> Stream m Int -> m ()
172−compose f = transform . f . f . f . f
173−
174−composeMapM = compose (S.mapM return)
175−composeAllInFilters = compose (S.filter (<= maxValue))
176−composeAllOutFilters = compose (S.filter (> maxValue))
177−composeMapAllInFilter = compose (S.filter (<= maxValue) . S.map (subtract 1))
178−
179−{-# INLINE composeScaling #-}
180−composeScaling :: Monad m => Int -> Stream m Int -> m ()
181−composeScaling m =
182− case m of
183− 1 -> transform . f
184− 2 -> transform . f . f
185− 3 -> transform . f . f . f
186− 4 -> transform . f . f . f . f
187− _ -> undefined
188− where f = S.filter (<= maxValue)
180+{-# INLINE scanMap #-}
181+{-# INLINE dropMap #-}
182+{-# INLINE dropScan #-}
183+{-# INLINE takeDrop #-}
184+{-# INLINE takeScan #-}
185+{-# INLINE takeMap #-}
186+{-# INLINE filterDrop #-}
187+{-# INLINE filterTake #-}
188+{-# INLINE filterScan #-}
189+{-# INLINE filterMap #-}
190+scanMap, dropMap, dropScan, takeDrop, takeScan, takeMap, filterDrop,
191+ filterTake, filterScan, filterMap
192+ :: Monad m => Int -> Stream m Int -> m ()
193+
194+scanMap n = composeN n $ S.map (subtract 1) . S.scanl' (+) 0
195+dropMap n = composeN n $ S.map (subtract 1) . S.drop 1
196+dropScan n = composeN n $ S.scanl' (+) 0 . S.drop 1
197+takeDrop n = composeN n $ S.drop 1 . S.take maxValue
198+takeScan n = composeN n $ S.scanl' (+) 0 . S.take maxValue
199+takeMap n = composeN n $ S.map (subtract 1) . S.take maxValue
200+filterDrop n = composeN n $ S.drop 1 . S.filter (<= maxValue)
201+filterTake n = composeN n $ S.take maxValue . S.filter (<= maxValue)
202+filterScan n = composeN n $ S.scanl' (+) 0 . S.filter (<= maxBound)
203+filterMap n = composeN n $ S.map (subtract 1) . S.filter (<= maxValue)
benchmark/StreamKOps.hs+69−55
@@ -13,7 +13,8 @@ import Control.Monad (when)
1313import Data.Maybe (isJust)
1414import Prelude
1515 (Monad, Int, (+), ($), (.), return, fmap, even, (>), (<=),
16− subtract, undefined, Maybe(..), not, mapM_, (>>=))
16+ subtract, undefined, Maybe(..), not, mapM_, (>>=),
17+ maxBound)
1718
1819import qualified Streamly.Streams.StreamK as S
1920import qualified Streamly.Streams.Prelude as S
@@ -31,31 +32,12 @@ maxValue = value + 1000
3132{-# INLINE uncons #-}
3233{-# INLINE nullTail #-}
3334{-# INLINE headTail #-}
34−{-# INLINE scan #-}
35−{-# INLINE map #-}
36−{-# INLINE filterEven #-}
37−{-# INLINE filterAllOut #-}
38−{-# INLINE filterAllIn #-}
39−{-# INLINE takeOne #-}
40−{-# INLINE takeAll #-}
41−{-# INLINE takeWhileTrue #-}
42−{-# INLINE dropAll #-}
43−{-# INLINE dropWhileTrue #-}
4435{-# INLINE zip #-}
4536{-# INLINE concat #-}
46−{-# INLINE composeAllInFilters #-}
47−{-# INLINE composeAllOutFilters #-}
48−{-# INLINE composeMapAllInFilter #-}
49−toNull, uncons, nullTail, headTail, scan, map, filterEven, filterAllOut,
50− filterAllIn, takeOne, takeAll, takeWhileTrue, dropAll, dropWhileTrue, zip,
51− concat, composeAllInFilters, composeAllOutFilters,
52− composeMapAllInFilter
37+toNull, uncons, nullTail, headTail, zip, concat
5338 :: Monad m
5439 => Stream m Int -> m ()
5540
56−{-# INLINE composeMapM #-}
57−composeMapM :: S.MonadAsync m => Stream m Int -> m ()
58−
5941{-# INLINE toList #-}
6042toList :: Monad m => Stream m Int -> m [Int]
6143{-# INLINE foldl #-}
@@ -63,9 +45,6 @@ foldl :: Monad m => Stream m Int -> m Int
6345{-# INLINE last #-}
6446last :: Monad m => Stream m Int -> m (Maybe Int)
6547
66−{-# INLINE mapM #-}
67−mapM :: S.MonadAsync m => Stream m Int -> m ()
68−
6948-------------------------------------------------------------------------------
7049-- Stream generation and elimination
7150-------------------------------------------------------------------------------
@@ -165,17 +144,47 @@ last = S.last
165144transform :: Monad m => Stream m a -> m ()
166145transform = runStream
167146
168−scan = transform . S.scanl' (+) 0
169−map = transform . fmap (+1)
170−mapM = transform . S.mapM return
171−filterEven = transform . S.filter even
172−filterAllOut = transform . S.filter (> maxValue)
173−filterAllIn = transform . S.filter (<= maxValue)
174−takeOne = transform . S.take 1
175−takeAll = transform . S.take maxValue
176−takeWhileTrue = transform . S.takeWhile (<= maxValue)
177−dropAll = transform . S.drop maxValue
178−dropWhileTrue = transform . S.dropWhile (<= maxValue)
147+{-# INLINE composeN #-}
148+composeN
149+ :: Monad m
150+ => Int -> (Stream m Int -> Stream m Int) -> Stream m Int -> m ()
151+composeN n f =
152+ case n of
153+ 1 -> transform . f
154+ 2 -> transform . f . f
155+ 3 -> transform . f . f . f
156+ 4 -> transform . f . f . f . f
157+ _ -> undefined
158+
159+{-# INLINE scan #-}
160+{-# INLINE map #-}
161+{-# INLINE filterEven #-}
162+{-# INLINE filterAllOut #-}
163+{-# INLINE filterAllIn #-}
164+{-# INLINE takeOne #-}
165+{-# INLINE takeAll #-}
166+{-# INLINE takeWhileTrue #-}
167+{-# INLINE dropAll #-}
168+{-# INLINE dropWhileTrue #-}
169+scan, map, filterEven, filterAllOut,
170+ filterAllIn, takeOne, takeAll, takeWhileTrue, dropAll, dropWhileTrue
171+ :: Monad m
172+ => Int -> Stream m Int -> m ()
173+
174+{-# INLINE mapM #-}
175+mapM :: S.MonadAsync m => Int -> Stream m Int -> m ()
176+
177+scan n = composeN n $ S.scanl' (+) 0
178+map n = composeN n $ fmap (+1)
179+mapM n = composeN n $ S.mapM return
180+filterEven n = composeN n $ S.filter even
181+filterAllOut n = composeN n $ S.filter (> maxValue)
182+filterAllIn n = composeN n $ S.filter (<= maxValue)
183+takeOne n = composeN n $ S.take 1
184+takeAll n = composeN n $ S.take maxValue
185+takeWhileTrue n = composeN n $ S.takeWhile (<= maxValue)
186+dropAll n = composeN n $ S.drop maxValue
187+dropWhileTrue n = composeN n $ S.dropWhile (<= maxValue)
179188
180189-------------------------------------------------------------------------------
181190-- Zipping and concat
@@ -185,25 +194,30 @@ zip src = transform $ S.zipWith (,) src src
185194concat _n = return ()
186195
187196-------------------------------------------------------------------------------
188−-- Composition
197+-- Mixed Composition
189198-------------------------------------------------------------------------------
190199
191−{-# INLINE compose #-}
192−compose :: Monad m => (Stream m Int -> Stream m Int) -> Stream m Int -> m ()
193−compose f = transform . f . f . f . f
194−
195−composeMapM = compose (S.mapM return)
196−composeAllInFilters = compose (S.filter (<= maxValue))
197−composeAllOutFilters = compose (S.filter (> maxValue))
198−composeMapAllInFilter = compose (S.filter (<= maxValue) . fmap (subtract 1))
199−
200−{-# INLINABLE composeScaling #-}
201−composeScaling :: Monad m => Int -> Stream m Int -> m ()
202−composeScaling m =
203− case m of
204− 1 -> transform . f
205− 2 -> transform . f . f
206− 3 -> transform . f . f . f
207− 4 -> transform . f . f . f . f
208− _ -> undefined
209− where f = S.filter (<= maxValue)
200+{-# INLINE scanMap #-}
201+{-# INLINE dropMap #-}
202+{-# INLINE dropScan #-}
203+{-# INLINE takeDrop #-}
204+{-# INLINE takeScan #-}
205+{-# INLINE takeMap #-}
206+{-# INLINE filterDrop #-}
207+{-# INLINE filterTake #-}
208+{-# INLINE filterScan #-}
209+{-# INLINE filterMap #-}
210+scanMap, dropMap, dropScan, takeDrop, takeScan, takeMap, filterDrop,
211+ filterTake, filterScan, filterMap
212+ :: Monad m => Int -> Stream m Int -> m ()
213+
214+scanMap n = composeN n $ S.map (subtract 1) . S.scanl' (+) 0
215+dropMap n = composeN n $ S.map (subtract 1) . S.drop 1
216+dropScan n = composeN n $ S.scanl' (+) 0 . S.drop 1
217+takeDrop n = composeN n $ S.drop 1 . S.take maxValue
218+takeScan n = composeN n $ S.scanl' (+) 0 . S.take maxValue
219+takeMap n = composeN n $ S.map (subtract 1) . S.take maxValue
220+filterDrop n = composeN n $ S.drop 1 . S.filter (<= maxValue)
221+filterTake n = composeN n $ S.take maxValue . S.filter (<= maxValue)
222+filterScan n = composeN n $ S.scanl' (+) 0 . S.filter (<= maxBound)
223+filterMap n = composeN n $ S.map (subtract 1) . S.filter (<= maxValue)
src/Streamly/Streams/StreamD.hs+5
@@ -93,6 +93,7 @@ module Streamly.Streams.StreamD
9393 -- * Transformation
9494 -- ** By folding (scans)
9595 , scanlM'
96+ , scanl'
9697
9798 -- * Filtering
9899 , filter
@@ -500,6 +501,10 @@ postscanlM' fstep begin (Stream step state) =
500501scanlM' :: Monad m => (b -> a -> m b) -> b -> Stream m a -> Stream m b
501502scanlM' fstep begin s = begin `seq` (begin `cons` postscanlM' fstep begin s)
502503
504+{-# INLINE scanl' #-}
505+scanl' :: Monad m => (b -> a -> b) -> b -> Stream m a -> Stream m b
506+scanl' f = scanlM' (\a b -> return (f a b))
507+
503508-------------------------------------------------------------------------------
504509-- Filtering
505510-------------------------------------------------------------------------------