@@ -0,0 +1,178 @@
1+-- |
2+-- Module : StreamKOps
3+-- Copyright : (c) 2018 Harendra Kumar
4+--
5+-- License : BSD3
6+-- Maintainer : harendra.kumar@gmail.com
7+
8+{-# LANGUAGE FlexibleContexts #-}
9+
10+module StreamKOps where
11+
12+import Prelude
13+ (Monad, Int, (+), ($), (.), return, fmap, even, (>), (<=),
14+ subtract, undefined, Maybe(..))
15+
16+import qualified Streamly.Streams.StreamK as S hiding (runStream)
17+-- import qualified Streamly.Streams.Serial as S
18+import qualified Streamly as S
19+import qualified Streamly.Prelude as S
20+
21+value, maxValue :: Int
22+value = 1000000
23+maxValue = value + 1000
24+
25+-------------------------------------------------------------------------------
26+-- Benchmark ops
27+-------------------------------------------------------------------------------
28+
29+{-# INLINE scan #-}
30+{-# INLINE map #-}
31+{-# INLINE filterEven #-}
32+{-# INLINE filterAllOut #-}
33+{-# INLINE filterAllIn #-}
34+{-# INLINE takeOne #-}
35+{-# INLINE takeAll #-}
36+{-# INLINE takeWhileTrue #-}
37+{-# INLINE dropAll #-}
38+{-# INLINE dropWhileTrue #-}
39+{-# INLINE zip #-}
40+{-# INLINE concat #-}
41+{-# INLINE composeAllInFilters #-}
42+{-# INLINE composeAllOutFilters #-}
43+{-# INLINE composeMapAllInFilter #-}
44+scan, map, filterEven, filterAllOut,
45+ filterAllIn, takeOne, takeAll, takeWhileTrue, dropAll, dropWhileTrue, zip,
46+ concat, composeAllInFilters, composeAllOutFilters,
47+ composeMapAllInFilter
48+ :: Monad m
49+ => Stream m Int -> m ()
50+
51+{-# INLINE composeMapM #-}
52+composeMapM :: S.MonadAsync m => Stream m Int -> m ()
53+
54+{-# INLINE toList #-}
55+toList :: Monad m => Stream m Int -> m [Int]
56+{-# INLINE foldl #-}
57+foldl :: Monad m => Stream m Int -> m Int
58+{-# INLINE last #-}
59+last :: Monad m => Stream m Int -> m (Maybe Int)
60+
61+{-# INLINE toNull #-}
62+{-# INLINE mapM #-}
63+toNull :: Monad m => Stream m Int -> m ()
64+mapM :: S.MonadAsync m => Stream m Int -> m ()
65+
66+-------------------------------------------------------------------------------
67+-- Stream generation and elimination
68+-------------------------------------------------------------------------------
69+
70+type Stream m a = S.SerialT m a
71+
72+{-# INLINE sourceUnfoldr #-}
73+sourceUnfoldr :: Int -> Stream m Int
74+sourceUnfoldr n = S.unfoldr step n
75+ where
76+ step cnt =
77+ if cnt > n + value
78+ then Nothing
79+ else (Just (cnt, cnt + 1))
80+
81+{-# INLINE sourceUnfoldrM #-}
82+sourceUnfoldrM :: S.MonadAsync m => Int -> Stream m Int
83+sourceUnfoldrM n = S.unfoldrM step n
84+ where
85+ step cnt =
86+ if cnt > n + value
87+ then return Nothing
88+ else return (Just (cnt, cnt + 1))
89+
90+{-
91+{-# INLINE sourceFromEnum #-}
92+sourceFromEnum :: Monad m => Int -> Stream m Int
93+sourceFromEnum n = S.enumFromStepN n 1 value
94+-}
95+
96+{-# INLINE sourceFromFoldable #-}
97+sourceFromFoldable :: Int -> Stream m Int
98+sourceFromFoldable n = S.fromFoldable [n..n+value]
99+
100+{-# INLINE sourceFromFoldableM #-}
101+sourceFromFoldableM :: S.MonadAsync m => Int -> Stream m Int
102+sourceFromFoldableM n = S.fromFoldableM (Prelude.fmap return [n..n+value])
103+
104+{-# INLINE sourceFoldMapWith #-}
105+sourceFoldMapWith :: Monad m => Int -> Stream m Int
106+sourceFoldMapWith n = S.foldMapWith (S.<>) return [n..n+value]
107+
108+{-# INLINE sourceFoldMapWithM #-}
109+sourceFoldMapWithM :: Monad m => Int -> Stream m Int
110+sourceFoldMapWithM n = S.foldMapWith (S.<>) (S.yieldM . return) [n..n+value]
111+
112+{-# INLINE source #-}
113+source :: S.MonadAsync m => Int -> Stream m Int
114+source n = sourceUnfoldrM n
115+
116+-------------------------------------------------------------------------------
117+-- Elimination
118+-------------------------------------------------------------------------------
119+
120+{-# INLINE runStream #-}
121+runStream :: Monad m => Stream m a -> m ()
122+runStream = S.runStream
123+
124+toNull = runStream
125+toList = S.toList
126+foldl = S.foldl' (+) 0
127+last = S.last
128+
129+-------------------------------------------------------------------------------
130+-- Transformation
131+-------------------------------------------------------------------------------
132+
133+{-# INLINE transform #-}
134+transform :: Monad m => Stream m a -> m ()
135+transform = runStream
136+
137+scan = transform . S.scanl' (+) 0
138+map = transform . fmap (+1)
139+mapM = transform . S.mapM return
140+filterEven = transform . S.filter even
141+filterAllOut = transform . S.filter (> maxValue)
142+filterAllIn = transform . S.filter (<= maxValue)
143+takeOne = transform . S.take 1
144+takeAll = transform . S.take maxValue
145+takeWhileTrue = transform . S.takeWhile (<= maxValue)
146+dropAll = transform . S.drop maxValue
147+dropWhileTrue = transform . S.dropWhile (<= maxValue)
148+
149+-------------------------------------------------------------------------------
150+-- Zipping and concat
151+-------------------------------------------------------------------------------
152+
153+zip src = transform $ (S.zipWith (,) src src)
154+concat _n = return ()
155+
156+-------------------------------------------------------------------------------
157+-- Composition
158+-------------------------------------------------------------------------------
159+
160+{-# INLINE compose #-}
161+compose :: Monad m => (Stream m Int -> Stream m Int) -> Stream m Int -> m ()
162+compose f = transform . f . f . f . f
163+
164+composeMapM = compose (S.mapM return)
165+composeAllInFilters = compose (S.filter (<= maxValue))
166+composeAllOutFilters = compose (S.filter (> maxValue))
167+composeMapAllInFilter = compose (S.filter (<= maxValue) . fmap (subtract 1))
168+
169+{-# INLINABLE composeScaling #-}
170+composeScaling :: Monad m => Int -> Stream m Int -> m ()
171+composeScaling m =
172+ case m of
173+ 1 -> transform . f
174+ 2 -> transform . f . f
175+ 3 -> transform . f . f . f
176+ 4 -> transform . f . f . f . f
177+ _ -> undefined
178+ where f = S.filter (<= maxValue)