3-- Copyright : (c) 2018 Harendra Kumar
6-- Maintainer : streamly@composewell.com
8{-# LANGUAGE FlexibleContexts #-}
9{-# LANGUAGE ScopedTypeVariables #-}
11module StreamDOps where
13import Control.Monad (when)
14import Data.Maybe (isJust)
16 (Monad, Int, (+), ($), (.), return, (>), even, (<=), div,
17 subtract, undefined, Maybe(..), not, (>>=),
18 maxBound, fmap, odd, (==), flip, (<$>), (<*>), round, (/), (**), (<))
19import qualified Prelude as P
21import qualified Streamly.Internal.Data.Stream.StreamD as S
22import qualified Streamly.Internal.Data.Unfold as UF
24-- We try to keep the total number of iterations same irrespective of nesting
25-- of the loops so that the overhead is easy to compare.
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-------------------------------------------------------------------------------
34-- Stream generation and elimination
35-------------------------------------------------------------------------------
37type Stream m a = S.Stream m a
39{-# INLINE sourceUnfoldr #-}
40sourceUnfoldr :: Monad m => Int -> Stream m Int
41sourceUnfoldr n = S.unfoldr step n
46 else Just (cnt, cnt + 1)
48{-# INLINE sourceUnfoldrN #-}
49sourceUnfoldrN :: Monad m => Int -> Int -> Stream m Int
50sourceUnfoldrN m n = S.unfoldr step n
55 else Just (cnt, cnt + 1)
57{-# INLINE sourceUnfoldrMN #-}
58sourceUnfoldrMN :: Monad m => Int -> Int -> Stream m Int
59sourceUnfoldrMN m n = S.unfoldrM step n
64 else return (Just (cnt, cnt + 1))
66{-# INLINE sourceUnfoldrM #-}
67sourceUnfoldrM :: Monad m => Int -> Stream m Int
68sourceUnfoldrM n = S.unfoldrM step n
73 else return (Just (cnt, cnt + 1))
75{-# INLINE sourceIntFromTo #-}
76sourceIntFromTo :: Monad m => Int -> Stream m Int
77sourceIntFromTo n = S.enumerateFromToIntegral n (n + value)
79{-# INLINE sourceFromList #-}
80sourceFromList :: Monad m => Int -> Stream m Int
81sourceFromList n = S.fromList [n..n+value]
84source :: Monad m => Int -> Stream m Int
85source = sourceUnfoldrM
87-------------------------------------------------------------------------------
89-------------------------------------------------------------------------------
91{-# INLINE runStream #-}
92runStream :: Monad m => Stream m a -> m ()
96mapM_ :: Monad m => Stream m a -> m ()
97mapM_ = S.mapM_ (\_ -> return ())
100toNull :: Monad m => Stream m Int -> m ()
104{-# INLINE nullTail #-}
105{-# INLINE headTail #-}
106uncons, nullTail, headTail
108 => Stream m Int -> m ()
114 Just (_, t) -> uncons t
117tail :: Monad m => Stream m a -> m ()
118tail s = S.tail s >>= P.mapM_ tail
122 when (not r) $ S.tail s >>= P.mapM_ nullTail
126 when (isJust h) $ S.tail s >>= P.mapM_ headTail
129toList :: Monad m => Stream m Int -> m [Int]
133foldl :: Monad m => Stream m Int -> m Int
134foldl = S.foldl' (+) 0
137last :: Monad m => Stream m Int -> m (Maybe Int)
140-------------------------------------------------------------------------------
142-------------------------------------------------------------------------------
144{-# INLINE transform #-}
145transform :: Monad m => Stream m a -> m ()
148{-# INLINE composeN #-}
151 => Int -> (Stream m Int -> Stream m Int) -> Stream m Int -> m ()
155 2 -> transform . f . f
156 3 -> transform . f . f . f
157 4 -> transform . f . f . f . f
164{-# INLINE mapMaybe #-}
165{-# INLINE mapMaybeM #-}
166{-# INLINE filterEven #-}
167{-# INLINE filterAllOut #-}
168{-# INLINE filterAllIn #-}
169{-# INLINE takeOne #-}
170{-# INLINE takeAll #-}
171{-# INLINE takeWhileTrue #-}
172{-# INLINE takeWhileMTrue #-}
173{-# INLINE dropOne #-}
174{-# INLINE dropAll #-}
175{-# INLINE dropWhileTrue #-}
176{-# INLINE dropWhileMTrue #-}
177{-# INLINE dropWhileFalse #-}
180{-# INLINE concatMap #-}
181{-# INLINE intersperse #-}
182scan, map, fmap, mapM, mapMaybe, mapMaybeM, filterEven, filterAllOut,
183 filterAllIn, takeOne, takeAll, takeWhileTrue, takeWhileMTrue, dropOne,
184 dropAll, dropWhileTrue, dropWhileMTrue, dropWhileFalse, foldrS, foldlS,
185 concatMap, intersperse
187 => Int -> Stream m Int -> m ()
189scan n = composeN n $ S.scanl' (+) 0
190fmap n = composeN n $ Prelude.fmap (+1)
191map n = composeN n $ S.map (+1)
192mapM n = composeN n $ S.mapM return
193mapMaybe n = composeN n $ S.mapMaybe
194 (\x -> if Prelude.odd x then Nothing else Just x)
195mapMaybeM n = composeN n $ S.mapMaybeM
196 (\x -> if Prelude.odd x then return Nothing else return $ Just x)
197filterEven n = composeN n $ S.filter even
198filterAllOut n = composeN n $ S.filter (> maxValue)
199filterAllIn n = composeN n $ S.filter (<= maxValue)
200takeOne n = composeN n $ S.take 1
201takeAll n = composeN n $ S.take maxValue
202takeWhileTrue n = composeN n $ S.takeWhile (<= maxValue)
203takeWhileMTrue n = composeN n $ S.takeWhileM (return . (<= maxValue))
204dropOne n = composeN n $ S.drop 1
205dropAll n = composeN n $ S.drop maxValue
206dropWhileTrue n = composeN n $ S.dropWhile (<= maxValue)
207dropWhileMTrue n = composeN n $ S.dropWhileM (return . (<= maxValue))
208dropWhileFalse n = composeN n $ S.dropWhile (> maxValue)
209foldrS n = composeN n $ S.foldrS S.cons S.nil
210foldlS n = composeN n $ S.foldlS (flip S.cons) S.nil
211concatMap n = composeN n $ (\s -> S.concatMap (\_ -> s) s)
212intersperse n = composeN n $ S.intersperse maxValue
214-------------------------------------------------------------------------------
216-------------------------------------------------------------------------------
218iterStreamLen, maxIters :: Int
222{-# INLINE iterateSource #-}
225 => (Stream m Int -> Stream m Int) -> Int -> Int -> Stream m Int
226iterateSource g i n = f i (sourceUnfoldrMN iterStreamLen n)
229 f x m = g (f (x P.- 1) m)
231{-# INLINE iterateMapM #-}
232{-# INLINE iterateScan #-}
233{-# INLINE iterateFilterEven #-}
234{-# INLINE iterateTakeAll #-}
235{-# INLINE iterateDropOne #-}
236{-# INLINE iterateDropWhileFalse #-}
237{-# INLINE iterateDropWhileTrue #-}
238iterateMapM, iterateScan, iterateFilterEven, iterateTakeAll, iterateDropOne,
239 iterateDropWhileFalse, iterateDropWhileTrue
241 => Int -> Stream m Int
244iterateScan = iterateSource (S.scanl' (+) 0) (maxIters `div` 10)
245iterateDropWhileFalse = iterateSource (S.dropWhile (> maxValue))
248iterateMapM = iterateSource (S.mapM return) maxIters
249iterateFilterEven = iterateSource (S.filter even) maxIters
250iterateTakeAll = iterateSource (S.take maxValue) maxIters
251iterateDropOne = iterateSource (S.drop 1) maxIters
252iterateDropWhileTrue = iterateSource (S.dropWhile (<= maxValue)) maxIters
254{-# INLINE iterateM #-}
255iterateM :: Monad m => Int -> Stream m Int
256iterateM i = S.take maxIters (S.iterateM (\x -> return (x + 1)) (return i))
258-------------------------------------------------------------------------------
260-------------------------------------------------------------------------------
263eqBy :: (Monad m, P.Eq a) => S.Stream m a -> m P.Bool
264eqBy src = S.eqBy (==) src src
267cmpBy :: (Monad m, P.Ord a) => S.Stream m a -> m P.Ordering
268cmpBy src = S.cmpBy P.compare src src
271zip :: Monad m => Stream m Int -> m ()
272zip src = transform $ S.zipWith (,) src src
274{-# INLINE concatMapRepl4xN #-}
275concatMapRepl4xN :: Monad m => Stream m Int -> m ()
276concatMapRepl4xN src = transform $ (S.concatMap (S.replicate 4) src)
278{-# INLINE concatMapURepl4xN #-}
279concatMapURepl4xN :: Monad m => Stream m Int -> m ()
280concatMapURepl4xN src = transform $ S.concatMapU (UF.replicateM 4) src
282-------------------------------------------------------------------------------
284-------------------------------------------------------------------------------
286{-# INLINE scanMap #-}
287{-# INLINE dropMap #-}
288{-# INLINE dropScan #-}
289{-# INLINE takeDrop #-}
290{-# INLINE takeScan #-}
291{-# INLINE takeMap #-}
292{-# INLINE filterDrop #-}
293{-# INLINE filterTake #-}
294{-# INLINE filterScan #-}
295{-# INLINE filterMap #-}
296scanMap, dropMap, dropScan, takeDrop, takeScan, takeMap, filterDrop,
297 filterTake, filterScan, filterMap
298 :: Monad m => Int -> Stream m Int -> m ()
300scanMap n = composeN n $ S.map (subtract 1) . S.scanl' (+) 0
301dropMap n = composeN n $ S.map (subtract 1) . S.drop 1
302dropScan n = composeN n $ S.scanl' (+) 0 . S.drop 1
303takeDrop n = composeN n $ S.drop 1 . S.take maxValue
304takeScan n = composeN n $ S.scanl' (+) 0 . S.take maxValue
305takeMap n = composeN n $ S.map (subtract 1) . S.take maxValue
306filterDrop n = composeN n $ S.drop 1 . S.filter (<= maxValue)
307filterTake n = composeN n $ S.take maxValue . S.filter (<= maxValue)
308filterScan n = composeN n $ S.scanl' (+) 0 . S.filter (<= maxBound)
309filterMap n = composeN n $ S.map (subtract 1) . S.filter (<= maxValue)
311-------------------------------------------------------------------------------
313-------------------------------------------------------------------------------
315{-# INLINE toNullApNested #-}
316toNullApNested :: Monad m => Stream m Int -> m ()
317toNullApNested s = runStream $ do
320{-# INLINE toNullNested #-}
321toNullNested :: Monad m => Stream m Int -> m ()
322toNullNested s = runStream $ do
327{-# INLINE toNullNested3 #-}
328toNullNested3 :: Monad m => Stream m Int -> m ()
329toNullNested3 s = runStream $ do
335{-# INLINE filterAllOutNested #-}
338 => Stream m Int -> m ()
339filterAllOutNested str = runStream $ do
347{-# INLINE filterAllInNested #-}
350 => Stream m Int -> m ()
351filterAllInNested str = runStream $ 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