@@ -0,0 +1,424 @@
2+-- Module : StreamDKOps
3+-- Copyright : (c) 2018 Harendra Kumar
6+-- Maintainer : harendra.kumar@gmail.com
8+{-# LANGUAGE FlexibleContexts #-}
9+{-# LANGUAGE ScopedTypeVariables #-}
11+module StreamDKOps where
13+-- import Control.Monad (when)
14+-- import Data.Maybe (isJust)
16+ (Monad, Int, (+), ($), (.), return, even, (>), (<=), div,
17+ subtract, undefined, Maybe(..), not, (>>=),
18+ maxBound, flip, (<$>), (<*>), round, (/), (**), (<))
19+import qualified Prelude as P
20+-- import qualified Data.List as List
22+import qualified Streamly.Streams.StreamDK as S
23+-- import qualified Streamly.Streams.Prelude as SP
24+-- import qualified Streamly.SVar as S
26+value, value2, value3, value16, maxValue :: Int
28+value2 = round (P.fromIntegral value**(1/2::P.Double)) -- double nested loop
29+value3 = round (P.fromIntegral value**(1/3::P.Double)) -- triple nested loop
30+value16 = round (P.fromIntegral value**(1/16::P.Double)) -- triple nested loop
33+-------------------------------------------------------------------------------
35+-------------------------------------------------------------------------------
37+-------------------------------------------------------------------------------
38+-- Stream generation and elimination
39+-------------------------------------------------------------------------------
41+type Stream m a = S.Stream m a
43+{-# INLINE sourceUnfoldr #-}
44+sourceUnfoldr :: Monad m => Int -> Stream m Int
45+sourceUnfoldr n = S.unfoldr step n
50+ else Just (cnt, cnt + 1)
52+{-# INLINE sourceUnfoldrN #-}
53+sourceUnfoldrN :: Monad m => Int -> Int -> Stream m Int
54+sourceUnfoldrN m n = S.unfoldr step n
59+ else Just (cnt, cnt + 1)
61+{-# INLINE sourceUnfoldrM #-}
62+sourceUnfoldrM :: Monad m => Int -> Stream m Int
63+sourceUnfoldrM n = S.unfoldrM step n
68+ else return (Just (cnt, cnt + 1))
70+{-# INLINE sourceUnfoldrMN #-}
71+sourceUnfoldrMN :: Monad m => Int -> Int -> Stream m Int
72+sourceUnfoldrMN m n = S.unfoldrM step n
77+ else return (Just (cnt, cnt + 1))
80+{-# INLINE sourceFromEnum #-}
81+sourceFromEnum :: Monad m => Int -> Stream m Int
82+sourceFromEnum n = S.enumFromStepN n 1 value
86+{-# INLINE sourceFromFoldable #-}
87+sourceFromFoldable :: Int -> Stream m Int
88+sourceFromFoldable n = S.fromFoldable [n..n+value]
92+{-# INLINE sourceFromFoldableM #-}
93+sourceFromFoldableM :: S.MonadAsync m => Int -> Stream m Int
94+sourceFromFoldableM n = S.fromFoldableM (Prelude.fmap return [n..n+value])
98+{-# INLINE sourceFoldMapWith #-}
99+sourceFoldMapWith :: Int -> Stream m Int
100+sourceFoldMapWith n = SP.foldMapWith S.serial S.yield [n..n+value]
102+{-# INLINE sourceFoldMapWithM #-}
103+sourceFoldMapWithM :: Monad m => Int -> Stream m Int
104+sourceFoldMapWithM n = SP.foldMapWith S.serial (S.yieldM . return) [n..n+value]
107+{-# INLINE source #-}
108+source :: Monad m => Int -> Stream m Int
109+source = sourceUnfoldrM
111+-------------------------------------------------------------------------------
113+-------------------------------------------------------------------------------
115+{-# INLINE runStream #-}
116+runStream :: Monad m => Stream m a -> m ()
118+-- runStream = S.mapM_ (\_ -> return ())
122+mapM_ :: Monad m => Stream m a -> m ()
123+mapM_ = S.mapM_ (\_ -> return ())
126+{-# INLINE toNull #-}
127+toNull :: Monad m => Stream m Int -> m ()
130+{-# INLINE uncons #-}
131+uncons :: Monad m => Stream m Int -> m ()
135+ Nothing -> return ()
136+ Just (_, t) -> uncons t
140+init :: (Monad m, S.IsStream t) => t m a -> m ()
146+tail :: (Monad m, S.IsStream t) => t m a -> m ()
147+tail s = S.tail s >>= P.mapM_ tail
149+{-# INLINE nullTail #-}
150+{-# INLINE headTail #-}
152+nullTail, headTail, zip
154+ => Stream m Int -> m ()
158+ when (not r) $ S.tail s >>= P.mapM_ nullTail
162+ when (isJust h) $ S.tail s >>= P.mapM_ headTail
164+{-# INLINE toList #-}
165+toList :: Monad m => Stream m Int -> m [Int]
169+foldl :: Monad m => Stream m Int -> m Int
170+foldl = S.foldl' (+) 0
173+last :: Monad m => Stream m Int -> m (Maybe Int)
177+-------------------------------------------------------------------------------
179+-------------------------------------------------------------------------------
181+{-# INLINE transform #-}
182+transform :: Monad m => Stream m a -> m ()
183+transform = runStream
185+{-# INLINE composeN #-}
188+ => Int -> (Stream m Int -> Stream m Int) -> Stream m Int -> m ()
192+ 2 -> transform . f . f
193+ 3 -> transform . f . f . f
194+ 4 -> transform . f . f . f . f
201+{-# INLINE filterEven #-}
202+{-# INLINE filterAllOut #-}
203+{-# INLINE filterAllIn #-}
204+{-# INLINE takeOne #-}
205+{-# INLINE takeAll #-}
206+{-# INLINE takeWhileTrue #-}
207+{-# INLINE dropOne #-}
208+{-# INLINE dropAll #-}
209+{-# INLINE dropWhileTrue #-}
210+{-# INLINE dropWhileFalse #-}
211+{-# INLINE foldlS #-}
212+{-# INLINE concatMap #-}
213+scan, map, fmap, filterEven, filterAllOut,
214+ filterAllIn, takeOne, takeAll, takeWhileTrue, dropAll, dropOne,
215+ dropWhileTrue, dropWhileFalse, foldlS, concatMap
217+ => Int -> Stream m Int -> m ()
220+{-# INLINE mapMSerial #-}
221+{-# INLINE intersperse #-}
222+mapM, mapMSerial, intersperse
223+ :: S.MonadAsync m => Int -> Stream m Int -> m ()
225+scan n = composeN n $ S.scanl' (+) 0
226+map n = composeN n $ P.fmap (+1)
227+fmap n = composeN n $ P.fmap (+1)
228+mapM n = composeN n $ S.mapM return
229+mapMSerial n = composeN n $ S.mapMSerial return
230+filterEven n = composeN n $ S.filter even
231+filterAllOut n = composeN n $ S.filter (> maxValue)
232+filterAllIn n = composeN n $ S.filter (<= maxValue)
233+takeOne n = composeN n $ S.take 1
234+takeAll n = composeN n $ S.take maxValue
235+takeWhileTrue n = composeN n $ S.takeWhile (<= maxValue)
236+dropOne n = composeN n $ S.drop 1
237+dropAll n = composeN n $ S.drop maxValue
238+dropWhileTrue n = composeN n $ S.dropWhile (<= maxValue)
239+dropWhileFalse n = composeN n $ S.dropWhile (<= 1)
240+foldlS n = composeN n $ S.foldlS (flip S.cons) S.nil
241+-- We use a (sqrt n) element stream as source and then concat the same stream
242+-- for each element to produce an n element stream.
243+concatMap n = composeN n $ (\s -> S.concatMap (\_ -> s) s)
244+intersperse n = composeN n $ S.intersperse maxValue
246+-------------------------------------------------------------------------------
248+-------------------------------------------------------------------------------
250+iterStreamLen, maxIters :: Int
254+{-# INLINE iterateSource #-}
257+ => (Stream m Int -> Stream m Int) -> Int -> Int -> Stream m Int
258+iterateSource g i n = f i (sourceUnfoldrMN iterStreamLen n)
260+ f (0 :: Int) m = g m
261+ f x m = g (f (x P.- 1) m)
263+{-# INLINE iterateMapM #-}
264+{-# INLINE iterateScan #-}
265+{-# INLINE iterateFilterEven #-}
266+{-# INLINE iterateTakeAll #-}
267+{-# INLINE iterateDropOne #-}
268+{-# INLINE iterateDropWhileFalse #-}
269+{-# INLINE iterateDropWhileTrue #-}
270+iterateMapM, iterateScan, iterateFilterEven, iterateTakeAll, iterateDropOne,
271+ iterateDropWhileFalse, iterateDropWhileTrue
273+ => Int -> Stream m Int
276+iterateScan = iterateSource (S.scanl' (+) 0) (maxIters `div` 10)
277+iterateDropWhileFalse = iterateSource (S.dropWhile (> maxValue))
280+iterateMapM = iterateSource (S.mapM return) maxIters
281+iterateFilterEven = iterateSource (S.filter even) maxIters
282+iterateTakeAll = iterateSource (S.take maxValue) maxIters
283+iterateDropOne = iterateSource (S.drop 1) maxIters
284+iterateDropWhileTrue = iterateSource (S.dropWhile (<= maxValue)) maxIters
286+-------------------------------------------------------------------------------
287+-- Zipping and concat
288+-------------------------------------------------------------------------------
290+zip src = transform $ S.zipWith (,) src src
292+{-# INLINE concatMapRepl4xN #-}
293+concatMapRepl4xN :: Monad m => Stream m Int -> m ()
294+concatMapRepl4xN src = transform $ (S.concatMap (S.replicate 4) src)
296+-------------------------------------------------------------------------------
298+-------------------------------------------------------------------------------
300+{-# INLINE scanMap #-}
301+{-# INLINE dropMap #-}
302+{-# INLINE dropScan #-}
303+{-# INLINE takeDrop #-}
304+{-# INLINE takeScan #-}
305+{-# INLINE takeMap #-}
306+{-# INLINE filterDrop #-}
307+{-# INLINE filterTake #-}
308+{-# INLINE filterScan #-}
309+{-# INLINE filterMap #-}
310+scanMap, dropMap, dropScan, takeDrop, takeScan, takeMap, filterDrop,
311+ filterTake, filterScan, filterMap
312+ :: Monad m => Int -> Stream m Int -> m ()
314+scanMap n = composeN n $ S.map (subtract 1) . S.scanl' (+) 0
315+dropMap n = composeN n $ S.map (subtract 1) . S.drop 1
316+dropScan n = composeN n $ S.scanl' (+) 0 . S.drop 1
317+takeDrop n = composeN n $ S.drop 1 . S.take maxValue
318+takeScan n = composeN n $ S.scanl' (+) 0 . S.take maxValue
319+takeMap n = composeN n $ S.map (subtract 1) . S.take maxValue
320+filterDrop n = composeN n $ S.drop 1 . S.filter (<= maxValue)
321+filterTake n = composeN n $ S.take maxValue . S.filter (<= maxValue)
322+filterScan n = composeN n $ S.scanl' (+) 0 . S.filter (<= maxBound)
323+filterMap n = composeN n $ S.map (subtract 1) . S.filter (<= maxValue)
325+-------------------------------------------------------------------------------
326+-- Nested Composition
327+-------------------------------------------------------------------------------
329+{-# INLINE toNullApNested #-}
330+toNullApNested :: Monad m => Stream m Int -> m ()
331+toNullApNested s = runStream $ do
334+{-# INLINE toNullNested #-}
335+toNullNested :: Monad m => Stream m Int -> m ()
336+toNullNested s = runStream $ do
341+{-# INLINE toNullNested3 #-}
342+toNullNested3 :: Monad m => Stream m Int -> m ()
343+toNullNested3 s = runStream $ do
349+{-# INLINE filterAllOutNested #-}
352+ => Stream m Int -> m ()
353+filterAllOutNested str = runStream $ do
361+{-# INLINE filterAllInNested #-}
364+ => Stream m Int -> m ()
365+filterAllInNested str = runStream $ do
373+-------------------------------------------------------------------------------
374+-- Nested Composition Pure lists
375+-------------------------------------------------------------------------------
377+{-# INLINE sourceUnfoldrList #-}
378+sourceUnfoldrList :: Int -> Int -> [Int]
379+sourceUnfoldrList maxval n = List.unfoldr step n
384+ else Just (cnt, cnt + 1)
386+{-# INLINE toNullApNestedList #-}
387+toNullApNestedList :: [Int] -> [Int]
388+toNullApNestedList s = (+) <$> s <*> s
390+{-# INLINE toNullNestedList #-}
391+toNullNestedList :: [Int] -> [Int]
392+toNullNestedList s = do
397+{-# INLINE toNullNestedList3 #-}
398+toNullNestedList3 :: [Int] -> [Int]
399+toNullNestedList3 s = do
405+{-# INLINE filterAllOutNestedList #-}
406+filterAllOutNestedList :: [Int] -> [Int]
407+filterAllOutNestedList str = do
415+{-# INLINE filterAllInNestedList #-}
416+filterAllInNestedList :: [Int] -> [Int]
417+filterAllInNestedList str = do