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-------------------------------------------------------------------------------
256-------------------------------------------------------------------------------
259eqBy :: (Monad m, P.Eq a) => S.Stream m a -> m P.Bool
260eqBy src = S.eqBy (==) src src
263cmpBy :: (Monad m, P.Ord a) => S.Stream m a -> m P.Ordering
264cmpBy src = S.cmpBy P.compare src src
267zip :: Monad m => Stream m Int -> m ()
268zip src = transform $ S.zipWith (,) src src
270{-# INLINE concatMapRepl4xN #-}
271concatMapRepl4xN :: Monad m => Stream m Int -> m ()
272concatMapRepl4xN src = transform $ (S.concatMap (S.replicate 4) src)
274{-# INLINE concatMapURepl4xN #-}
275concatMapURepl4xN :: Monad m => Stream m Int -> m ()
276concatMapURepl4xN src = transform $ S.concatMapU (UF.replicateM 4) src
278-------------------------------------------------------------------------------
280-------------------------------------------------------------------------------
282{-# INLINE scanMap #-}
283{-# INLINE dropMap #-}
284{-# INLINE dropScan #-}
285{-# INLINE takeDrop #-}
286{-# INLINE takeScan #-}
287{-# INLINE takeMap #-}
288{-# INLINE filterDrop #-}
289{-# INLINE filterTake #-}
290{-# INLINE filterScan #-}
291{-# INLINE filterMap #-}
292scanMap, dropMap, dropScan, takeDrop, takeScan, takeMap, filterDrop,
293 filterTake, filterScan, filterMap
294 :: Monad m => Int -> Stream m Int -> m ()
296scanMap n = composeN n $ S.map (subtract 1) . S.scanl' (+) 0
297dropMap n = composeN n $ S.map (subtract 1) . S.drop 1
298dropScan n = composeN n $ S.scanl' (+) 0 . S.drop 1
299takeDrop n = composeN n $ S.drop 1 . S.take maxValue
300takeScan n = composeN n $ S.scanl' (+) 0 . S.take maxValue
301takeMap n = composeN n $ S.map (subtract 1) . S.take maxValue
302filterDrop n = composeN n $ S.drop 1 . S.filter (<= maxValue)
303filterTake n = composeN n $ S.take maxValue . S.filter (<= maxValue)
304filterScan n = composeN n $ S.scanl' (+) 0 . S.filter (<= maxBound)
305filterMap n = composeN n $ S.map (subtract 1) . S.filter (<= maxValue)
307-------------------------------------------------------------------------------
309-------------------------------------------------------------------------------
311{-# INLINE toNullApNested #-}
312toNullApNested :: Monad m => Stream m Int -> m ()
313toNullApNested s = runStream $ do
316{-# INLINE toNullNested #-}
317toNullNested :: Monad m => Stream m Int -> m ()
318toNullNested s = runStream $ do
323{-# INLINE toNullNested3 #-}
324toNullNested3 :: Monad m => Stream m Int -> m ()
325toNullNested3 s = runStream $ do
331{-# INLINE filterAllOutNested #-}
334 => Stream m Int -> m ()
335filterAllOutNested str = runStream $ do
343{-# INLINE filterAllInNested #-}
346 => Stream m Int -> m ()
347filterAllInNested 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