3-- Copyright : (c) 2018 Harendra Kumar
6-- Maintainer : streamly@composewell.com
8{-# LANGUAGE FlexibleContexts #-}
9{-# LANGUAGE ScopedTypeVariables #-}
11module StreamKOps where
13import Control.Monad (when)
14import Data.Maybe (isJust)
16 (Monad, Int, (+), ($), (.), return, even, (>), (<=), div,
17 subtract, undefined, Maybe(..), not, (>>=),
18 maxBound, flip, (<$>), (<*>), round, (/), (**), (<))
19import qualified Prelude as P
20import qualified Data.List as List
22import qualified Streamly.Internal.Data.Stream.StreamK as S
23import qualified Streamly.Internal.Data.Stream.Prelude as SP
24import qualified Streamly.Internal.Data.SVar as S
26value, value2, value3, value16, maxValue :: Int
28value2 = round (P.fromIntegral value**(1/2::P.Double)) -- double nested loop
29value3 = round (P.fromIntegral value**(1/3::P.Double)) -- triple nested loop
30value16 = round (P.fromIntegral value**(1/16::P.Double)) -- triple nested loop
33-------------------------------------------------------------------------------
35-------------------------------------------------------------------------------
39{-# INLINE nullTail #-}
40{-# INLINE headTail #-}
42toNull, uncons, nullTail, headTail, zip
44 => Stream m Int -> m ()
47toList :: Monad m => Stream m Int -> m [Int]
49foldl :: Monad m => Stream m Int -> m Int
51last :: Monad m => Stream m Int -> m (Maybe Int)
53-------------------------------------------------------------------------------
54-- Stream generation and elimination
55-------------------------------------------------------------------------------
57type Stream m a = S.Stream m a
59{-# INLINE sourceUnfoldr #-}
60sourceUnfoldr :: Int -> Stream m Int
61sourceUnfoldr n = S.unfoldr step n
66 else Just (cnt, cnt + 1)
68{-# INLINE sourceUnfoldrN #-}
69sourceUnfoldrN :: Int -> Int -> Stream m Int
70sourceUnfoldrN m n = S.unfoldr step n
75 else Just (cnt, cnt + 1)
77{-# INLINE sourceUnfoldrM #-}
78sourceUnfoldrM :: S.MonadAsync m => Int -> Stream m Int
79sourceUnfoldrM n = S.unfoldrM step n
84 else return (Just (cnt, cnt + 1))
86{-# INLINE sourceUnfoldrMN #-}
87sourceUnfoldrMN :: S.MonadAsync m => Int -> Int -> Stream m Int
88sourceUnfoldrMN m n = S.unfoldrM step n
93 else return (Just (cnt, cnt + 1))
96{-# INLINE sourceFromEnum #-}
97sourceFromEnum :: Monad m => Int -> Stream m Int
98sourceFromEnum n = S.enumFromStepN n 1 value
101{-# INLINE sourceFromFoldable #-}
102sourceFromFoldable :: Int -> Stream m Int
103sourceFromFoldable n = S.fromFoldable [n..n+value]
106{-# INLINE sourceFromFoldableM #-}
107sourceFromFoldableM :: S.MonadAsync m => Int -> Stream m Int
108sourceFromFoldableM n = S.fromFoldableM (Prelude.fmap return [n..n+value])
111{-# INLINE sourceFoldMapWith #-}
112sourceFoldMapWith :: Int -> Stream m Int
113sourceFoldMapWith n = SP.foldMapWith S.serial S.yield [n..n+value]
115{-# INLINE sourceFoldMapWithM #-}
116sourceFoldMapWithM :: Monad m => Int -> Stream m Int
117sourceFoldMapWithM n = SP.foldMapWith S.serial (S.yieldM . return) [n..n+value]
120source :: S.MonadAsync m => Int -> Stream m Int
121source = sourceUnfoldrM
123-------------------------------------------------------------------------------
125-------------------------------------------------------------------------------
127{-# INLINE runStream #-}
128runStream :: Monad m => Stream m a -> m ()
130-- runStream = S.mapM_ (\_ -> return ())
133mapM_ :: Monad m => Stream m a -> m ()
134mapM_ = S.mapM_ (\_ -> return ())
141 Just (_, t) -> uncons t
144init :: (Monad m, S.IsStream t) => t m a -> m ()
150tail :: (Monad m, S.IsStream t) => t m a -> m ()
151tail s = S.tail s >>= P.mapM_ tail
155 when (not r) $ S.tail s >>= P.mapM_ nullTail
159 when (isJust h) $ S.tail s >>= P.mapM_ headTail
162foldl = S.foldl' (+) 0
165-------------------------------------------------------------------------------
167-------------------------------------------------------------------------------
169{-# INLINE transform #-}
170transform :: Monad m => Stream m a -> m ()
173{-# INLINE composeN #-}
176 => Int -> (Stream m Int -> Stream m Int) -> Stream m Int -> m ()
180 2 -> transform . f . f
181 3 -> transform . f . f . f
182 4 -> transform . f . f . f . f
188{-# INLINE filterEven #-}
189{-# INLINE filterAllOut #-}
190{-# INLINE filterAllIn #-}
191{-# INLINE takeOne #-}
192{-# INLINE takeAll #-}
193{-# INLINE takeWhileTrue #-}
194{-# INLINE dropOne #-}
195{-# INLINE dropAll #-}
196{-# INLINE dropWhileTrue #-}
197{-# INLINE dropWhileFalse #-}
199{-# INLINE concatMap #-}
200scan, map, fmap, filterEven, filterAllOut,
201 filterAllIn, takeOne, takeAll, takeWhileTrue, dropAll, dropOne,
202 dropWhileTrue, dropWhileFalse, foldlS, concatMap
204 => Int -> Stream m Int -> m ()
207{-# INLINE mapMSerial #-}
208{-# INLINE intersperse #-}
209mapM, mapMSerial, intersperse
210 :: S.MonadAsync m => Int -> Stream m Int -> m ()
212scan n = composeN n $ S.scanl' (+) 0
213map n = composeN n $ P.fmap (+1)
214fmap n = composeN n $ P.fmap (+1)
215mapM n = composeN n $ S.mapM return
216mapMSerial n = composeN n $ S.mapMSerial return
217filterEven n = composeN n $ S.filter even
218filterAllOut n = composeN n $ S.filter (> maxValue)
219filterAllIn n = composeN n $ S.filter (<= maxValue)
220takeOne n = composeN n $ S.take 1
221takeAll n = composeN n $ S.take maxValue
222takeWhileTrue n = composeN n $ S.takeWhile (<= maxValue)
223dropOne n = composeN n $ S.drop 1
224dropAll n = composeN n $ S.drop maxValue
225dropWhileTrue n = composeN n $ S.dropWhile (<= maxValue)
226dropWhileFalse n = composeN n $ S.dropWhile (<= 1)
227foldlS n = composeN n $ S.foldlS (flip S.cons) S.nil
228-- We use a (sqrt n) element stream as source and then concat the same stream
229-- for each element to produce an n element stream.
230concatMap n = composeN n $ (\s -> S.concatMap (\_ -> s) s)
231intersperse n = composeN n $ S.intersperse maxValue
233-------------------------------------------------------------------------------
235-------------------------------------------------------------------------------
237iterStreamLen, maxIters :: Int
241{-# INLINE iterateSource #-}
244 => (Stream m Int -> Stream m Int) -> Int -> Int -> Stream m Int
245iterateSource g i n = f i (sourceUnfoldrMN iterStreamLen n)
248 f x m = g (f (x P.- 1) m)
250{-# INLINE iterateMapM #-}
251{-# INLINE iterateScan #-}
252{-# INLINE iterateFilterEven #-}
253{-# INLINE iterateTakeAll #-}
254{-# INLINE iterateDropOne #-}
255{-# INLINE iterateDropWhileFalse #-}
256{-# INLINE iterateDropWhileTrue #-}
257iterateMapM, iterateScan, iterateFilterEven, iterateTakeAll, iterateDropOne,
258 iterateDropWhileFalse, iterateDropWhileTrue
260 => Int -> Stream m Int
263iterateScan = iterateSource (S.scanl' (+) 0) (maxIters `div` 10)
264iterateDropWhileFalse = iterateSource (S.dropWhile (> maxValue))
267iterateMapM = iterateSource (S.mapM return) maxIters
268iterateFilterEven = iterateSource (S.filter even) maxIters
269iterateTakeAll = iterateSource (S.take maxValue) maxIters
270iterateDropOne = iterateSource (S.drop 1) maxIters
271iterateDropWhileTrue = iterateSource (S.dropWhile (<= maxValue)) maxIters
273-------------------------------------------------------------------------------
275-------------------------------------------------------------------------------
277zip src = transform $ S.zipWith (,) src src
279{-# INLINE concatMapRepl4xN #-}
280concatMapRepl4xN :: Monad m => Stream m Int -> m ()
281concatMapRepl4xN src = transform $ (S.concatMap (S.replicate 4) src)
283-------------------------------------------------------------------------------
285-------------------------------------------------------------------------------
287{-# INLINE scanMap #-}
288{-# INLINE dropMap #-}
289{-# INLINE dropScan #-}
290{-# INLINE takeDrop #-}
291{-# INLINE takeScan #-}
292{-# INLINE takeMap #-}
293{-# INLINE filterDrop #-}
294{-# INLINE filterTake #-}
295{-# INLINE filterScan #-}
296{-# INLINE filterMap #-}
297scanMap, dropMap, dropScan, takeDrop, takeScan, takeMap, filterDrop,
298 filterTake, filterScan, filterMap
299 :: Monad m => Int -> Stream m Int -> m ()
301scanMap n = composeN n $ S.map (subtract 1) . S.scanl' (+) 0
302dropMap n = composeN n $ S.map (subtract 1) . S.drop 1
303dropScan n = composeN n $ S.scanl' (+) 0 . S.drop 1
304takeDrop n = composeN n $ S.drop 1 . S.take maxValue
305takeScan n = composeN n $ S.scanl' (+) 0 . S.take maxValue
306takeMap n = composeN n $ S.map (subtract 1) . S.take maxValue
307filterDrop n = composeN n $ S.drop 1 . S.filter (<= maxValue)
308filterTake n = composeN n $ S.take maxValue . S.filter (<= maxValue)
309filterScan n = composeN n $ S.scanl' (+) 0 . S.filter (<= maxBound)
310filterMap n = composeN n $ S.map (subtract 1) . S.filter (<= maxValue)
312-------------------------------------------------------------------------------
314-------------------------------------------------------------------------------
316{-# INLINE toNullApNested #-}
317toNullApNested :: Monad m => Stream m Int -> m ()
318toNullApNested s = runStream $ do
321{-# INLINE toNullNested #-}
322toNullNested :: Monad m => Stream m Int -> m ()
323toNullNested s = runStream $ do
328{-# INLINE toNullNested3 #-}
329toNullNested3 :: Monad m => Stream m Int -> m ()
330toNullNested3 s = runStream $ do
336{-# INLINE filterAllOutNested #-}
339 => Stream m Int -> m ()
340filterAllOutNested str = runStream $ do
348{-# INLINE filterAllInNested #-}
351 => Stream m Int -> m ()
352filterAllInNested str = runStream $ do
360-------------------------------------------------------------------------------
361-- Nested Composition Pure lists
362-------------------------------------------------------------------------------
364{-# INLINE sourceUnfoldrList #-}
365sourceUnfoldrList :: Int -> Int -> [Int]
366sourceUnfoldrList maxval n = List.unfoldr step n
371 else Just (cnt, cnt + 1)
373{-# INLINE toNullApNestedList #-}
374toNullApNestedList :: [Int] -> [Int]
375toNullApNestedList s = (+) <$> s <*> s
377{-# INLINE toNullNestedList #-}
378toNullNestedList :: [Int] -> [Int]
379toNullNestedList s = do
384{-# INLINE toNullNestedList3 #-}
385toNullNestedList3 :: [Int] -> [Int]
386toNullNestedList3 s = do
392{-# INLINE filterAllOutNestedList #-}
393filterAllOutNestedList :: [Int] -> [Int]
394filterAllOutNestedList str = do
402{-# INLINE filterAllInNestedList #-}
403filterAllInNestedList :: [Int] -> [Int]
404filterAllInNestedList str = do
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list