2018-04-09 18:02:49 +03:00
|
|
|
-- |
|
|
|
|
-- Module : BenchmarkOps
|
|
|
|
-- Copyright : (c) 2018 Harendra Kumar
|
|
|
|
--
|
|
|
|
-- License : MIT
|
|
|
|
-- Maintainer : harendra.kumar@gmail.com
|
|
|
|
|
2018-10-09 10:18:53 +03:00
|
|
|
{-# LANGUAGE CPP #-}
|
2018-05-24 14:18:48 +03:00
|
|
|
{-# LANGUAGE FlexibleContexts #-}
|
2018-10-30 21:30:58 +03:00
|
|
|
{-# LANGUAGE ScopedTypeVariables #-}
|
2018-05-24 14:18:48 +03:00
|
|
|
|
2018-04-24 15:13:10 +03:00
|
|
|
module LinearOps where
|
2018-04-09 18:02:49 +03:00
|
|
|
|
2018-10-13 06:11:02 +03:00
|
|
|
import Control.Monad (when)
|
2018-06-27 06:03:06 +03:00
|
|
|
import Data.Maybe (fromJust)
|
2018-04-09 18:02:49 +03:00
|
|
|
import Prelude
|
2018-07-25 22:12:53 +03:00
|
|
|
(Monad, Int, (+), ($), (.), return, fmap, even, (>), (<=), (==), (<=),
|
2018-10-28 21:51:16 +03:00
|
|
|
subtract, undefined, Maybe(..), odd, Bool, not, (>>=), mapM_, curry,
|
2018-11-06 00:42:08 +03:00
|
|
|
maxBound, div)
|
2018-10-30 21:30:58 +03:00
|
|
|
import qualified Prelude as P
|
2018-04-09 18:02:49 +03:00
|
|
|
|
|
|
|
import qualified Streamly as S
|
|
|
|
import qualified Streamly.Prelude as S
|
|
|
|
|
2018-06-12 12:21:38 +03:00
|
|
|
value, maxValue :: Int
|
2018-10-09 10:18:53 +03:00
|
|
|
#ifdef LINEAR_ASYNC
|
|
|
|
value = 10000
|
|
|
|
#else
|
2018-05-30 06:50:08 +03:00
|
|
|
value = 100000
|
2018-10-09 10:18:53 +03:00
|
|
|
#endif
|
|
|
|
maxValue = value + 1
|
2018-04-09 18:02:49 +03:00
|
|
|
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
-- Benchmark ops
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
-- Stream generation and elimination
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
2018-05-13 07:57:49 +03:00
|
|
|
type Stream m a = S.SerialT m a
|
2018-04-09 18:02:49 +03:00
|
|
|
|
2018-05-21 15:24:19 +03:00
|
|
|
{-# INLINE source #-}
|
2018-06-09 18:41:15 +03:00
|
|
|
source :: (S.MonadAsync m, S.IsStream t) => Int -> t m Int
|
|
|
|
source n = S.serially $ sourceUnfoldrM n
|
2018-06-24 20:13:30 +03:00
|
|
|
-- source n = S.serially $ sourceFromList n
|
2018-05-21 15:24:19 +03:00
|
|
|
|
2018-06-24 03:49:41 +03:00
|
|
|
{-# INLINE sourceFromList #-}
|
|
|
|
sourceFromList :: (Monad m, S.IsStream t) => Int -> t m Int
|
|
|
|
sourceFromList n = S.fromList [n..n+value]
|
|
|
|
|
|
|
|
{-# INLINE sourceFromListM #-}
|
|
|
|
sourceFromListM :: (S.MonadAsync m, S.IsStream t) => Int -> t m Int
|
|
|
|
sourceFromListM n = S.fromListM (Prelude.fmap return [n..n+value])
|
|
|
|
|
2018-05-27 12:52:57 +03:00
|
|
|
{-# INLINE sourceFromFoldable #-}
|
|
|
|
sourceFromFoldable :: S.IsStream t => Int -> t m Int
|
2018-05-21 15:24:19 +03:00
|
|
|
sourceFromFoldable n = S.fromFoldable [n..n+value]
|
|
|
|
|
|
|
|
{-# INLINE sourceFromFoldableM #-}
|
2018-05-27 12:52:57 +03:00
|
|
|
sourceFromFoldableM :: (S.IsStream t, S.MonadAsync m) => Int -> t m Int
|
2018-05-21 15:24:19 +03:00
|
|
|
sourceFromFoldableM n = S.fromFoldableM (Prelude.fmap return [n..n+value])
|
|
|
|
|
2018-05-27 12:52:57 +03:00
|
|
|
{-# INLINE sourceFoldMapWith #-}
|
2018-06-26 07:14:06 +03:00
|
|
|
sourceFoldMapWith :: (S.IsStream t, S.Semigroup (t m Int))
|
2018-05-27 12:52:57 +03:00
|
|
|
=> Int -> t m Int
|
2018-06-26 07:14:06 +03:00
|
|
|
sourceFoldMapWith n = S.foldMapWith (S.<>) S.yield [n..n+value]
|
2018-05-27 12:52:57 +03:00
|
|
|
|
|
|
|
{-# INLINE sourceFoldMapWithM #-}
|
|
|
|
sourceFoldMapWithM :: (S.IsStream t, Monad m, S.Semigroup (t m Int))
|
|
|
|
=> Int -> t m Int
|
2018-06-23 04:20:59 +03:00
|
|
|
sourceFoldMapWithM n = S.foldMapWith (S.<>) (S.yieldM . return) [n..n+value]
|
2018-05-21 15:24:19 +03:00
|
|
|
|
2018-06-09 18:41:15 +03:00
|
|
|
{-# INLINE sourceUnfoldr #-}
|
2018-06-24 03:49:41 +03:00
|
|
|
sourceUnfoldr :: (Monad m, S.IsStream t) => Int -> t m Int
|
2018-06-09 18:41:15 +03:00
|
|
|
sourceUnfoldr n = S.unfoldr step n
|
|
|
|
where
|
|
|
|
step cnt =
|
|
|
|
if cnt > n + value
|
|
|
|
then Nothing
|
2018-10-13 06:11:02 +03:00
|
|
|
else Just (cnt, cnt + 1)
|
2018-06-09 18:41:15 +03:00
|
|
|
|
2018-05-21 15:24:19 +03:00
|
|
|
{-# INLINE sourceUnfoldrM #-}
|
2018-05-27 12:52:57 +03:00
|
|
|
sourceUnfoldrM :: (S.IsStream t, S.MonadAsync m) => Int -> t m Int
|
2018-05-21 15:24:19 +03:00
|
|
|
sourceUnfoldrM n = S.unfoldrM step n
|
|
|
|
where
|
|
|
|
step cnt =
|
|
|
|
if cnt > n + value
|
|
|
|
then return Nothing
|
|
|
|
else return (Just (cnt, cnt + 1))
|
2018-04-09 18:02:49 +03:00
|
|
|
|
2018-08-08 16:58:22 +03:00
|
|
|
{-# INLINE sourceUnfoldrMN #-}
|
|
|
|
sourceUnfoldrMN :: (S.IsStream t, S.MonadAsync m) => Int -> Int -> t m Int
|
|
|
|
sourceUnfoldrMN m n = S.unfoldrM step n
|
|
|
|
where
|
|
|
|
step cnt =
|
|
|
|
if cnt > n + m
|
|
|
|
then return Nothing
|
|
|
|
else return (Just (cnt, cnt + 1))
|
|
|
|
|
2018-06-25 00:45:22 +03:00
|
|
|
{-# INLINE sourceUnfoldrMAction #-}
|
|
|
|
sourceUnfoldrMAction :: (S.IsStream t, S.MonadAsync m) => Int -> t m (m Int)
|
|
|
|
sourceUnfoldrMAction n = S.serially $ S.unfoldrM step n
|
|
|
|
where
|
|
|
|
step cnt =
|
|
|
|
if cnt > n + value
|
|
|
|
then return Nothing
|
|
|
|
else return (Just (return cnt, cnt + 1))
|
2018-04-09 18:02:49 +03:00
|
|
|
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
-- Elimination
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
2018-06-25 00:45:22 +03:00
|
|
|
{-# INLINE runStream #-}
|
|
|
|
runStream :: Monad m => Stream m a -> m ()
|
|
|
|
runStream = S.runStream
|
|
|
|
|
2018-07-25 22:12:53 +03:00
|
|
|
{-# INLINE toList #-}
|
|
|
|
{-# INLINE foldr #-}
|
|
|
|
{-# INLINE foldrM #-}
|
|
|
|
toList, foldr, foldrM :: Monad m => Stream m Int -> m [Int]
|
|
|
|
|
|
|
|
{-# INLINE last #-}
|
|
|
|
{-# INLINE maximum #-}
|
|
|
|
{-# INLINE minimum #-}
|
|
|
|
{-# INLINE find #-}
|
|
|
|
{-# INLINE findIndex #-}
|
|
|
|
{-# INLINE elemIndex #-}
|
|
|
|
{-# INLINE foldl1' #-}
|
|
|
|
{-# INLINE foldr1 #-}
|
|
|
|
last, minimum, maximum, find, findIndex, elemIndex, foldl1', foldr1 :: Monad m => Stream m Int -> m (Maybe Int)
|
|
|
|
|
|
|
|
{-# INLINE foldl' #-}
|
|
|
|
{-# INLINE length #-}
|
|
|
|
{-# INLINE sum #-}
|
|
|
|
{-# INLINE product #-}
|
|
|
|
foldl', length, sum, product :: Monad m => Stream m Int -> m Int
|
|
|
|
|
|
|
|
{-# INLINE all #-}
|
|
|
|
{-# INLINE any #-}
|
|
|
|
{-# INLINE and #-}
|
|
|
|
{-# INLINE or #-}
|
|
|
|
{-# INLINE elem #-}
|
|
|
|
{-# INLINE notElem #-}
|
|
|
|
elem, notElem, all, any, and, or :: Monad m => Stream m Int -> m Bool
|
|
|
|
|
|
|
|
{-# INLINE toNull #-}
|
|
|
|
toNull :: Monad m => (t m Int -> S.SerialT m Int) -> t m Int -> m ()
|
2018-05-27 12:52:57 +03:00
|
|
|
toNull t = runStream . t
|
2018-07-25 22:12:53 +03:00
|
|
|
|
|
|
|
{-# INLINE uncons #-}
|
|
|
|
uncons :: Monad m => Stream m Int -> m ()
|
2018-06-27 02:50:14 +03:00
|
|
|
uncons s = do
|
|
|
|
r <- S.uncons s
|
|
|
|
case r of
|
|
|
|
Nothing -> return ()
|
|
|
|
Just (_, t) -> uncons t
|
2018-07-25 22:12:53 +03:00
|
|
|
|
|
|
|
{-# INLINE init #-}
|
|
|
|
init :: Monad m => Stream m a -> m ()
|
2018-10-13 06:11:02 +03:00
|
|
|
init s = S.init s >>= Prelude.mapM_ S.runStream
|
2018-07-25 22:12:53 +03:00
|
|
|
|
|
|
|
{-# INLINE tail #-}
|
|
|
|
tail :: Monad m => Stream m a -> m ()
|
2018-10-13 06:11:02 +03:00
|
|
|
tail s = S.tail s >>= Prelude.mapM_ tail
|
2018-07-25 22:12:53 +03:00
|
|
|
|
|
|
|
{-# INLINE nullHeadTail #-}
|
|
|
|
nullHeadTail :: Monad m => Stream m Int -> m ()
|
2018-06-27 02:50:14 +03:00
|
|
|
nullHeadTail s = do
|
|
|
|
r <- S.null s
|
2018-10-13 06:11:02 +03:00
|
|
|
when (not r) $ do
|
2018-06-27 02:50:14 +03:00
|
|
|
_ <- S.head s
|
2018-10-13 06:11:02 +03:00
|
|
|
S.tail s >>= Prelude.mapM_ nullHeadTail
|
2018-07-25 22:12:53 +03:00
|
|
|
|
2018-10-28 21:51:16 +03:00
|
|
|
{-# INLINE mapM_ #-}
|
|
|
|
mapM_ :: Monad m => Stream m Int -> m ()
|
2018-06-24 20:13:30 +03:00
|
|
|
mapM_ = S.mapM_ (\_ -> return ())
|
2018-10-28 21:51:16 +03:00
|
|
|
|
2018-04-09 18:02:49 +03:00
|
|
|
toList = S.toList
|
2018-06-24 20:13:30 +03:00
|
|
|
foldr = S.foldr (:) []
|
2018-07-25 22:12:53 +03:00
|
|
|
foldr1 = S.foldr1 (+)
|
2018-06-24 20:13:30 +03:00
|
|
|
foldrM = S.foldrM (\a xs -> return (a : xs)) []
|
2018-07-25 22:12:53 +03:00
|
|
|
foldl' = S.foldl' (+) 0
|
|
|
|
foldl1' = S.foldl1' (+)
|
2018-04-09 18:02:49 +03:00
|
|
|
last = S.last
|
2018-06-26 22:34:26 +03:00
|
|
|
elem = S.elem maxValue
|
|
|
|
notElem = S.notElem maxValue
|
2018-06-25 01:21:02 +03:00
|
|
|
length = S.length
|
2018-06-26 22:34:26 +03:00
|
|
|
all = S.all (<= maxValue)
|
|
|
|
any = S.any (> maxValue)
|
2018-07-25 22:12:53 +03:00
|
|
|
and = S.and . S.map (<= maxValue)
|
|
|
|
or = S.or . S.map (> maxValue)
|
|
|
|
find = S.find (== maxValue)
|
|
|
|
findIndex = S.findIndex (== maxValue)
|
|
|
|
elemIndex = S.elemIndex maxValue
|
2018-06-25 01:21:02 +03:00
|
|
|
maximum = S.maximum
|
|
|
|
minimum = S.minimum
|
2018-06-26 22:34:26 +03:00
|
|
|
sum = S.sum
|
|
|
|
product = S.product
|
2018-04-09 18:02:49 +03:00
|
|
|
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
-- Transformation
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
{-# INLINE transform #-}
|
|
|
|
transform :: Monad m => Stream m a -> m ()
|
|
|
|
transform = runStream
|
|
|
|
|
2018-10-28 21:51:16 +03:00
|
|
|
{-# INLINE composeN #-}
|
|
|
|
composeN
|
|
|
|
:: Monad m
|
|
|
|
=> Int -> (Stream m Int -> Stream m Int) -> Stream m Int -> m ()
|
|
|
|
composeN n f =
|
|
|
|
case n of
|
|
|
|
1 -> transform . f
|
|
|
|
2 -> transform . f . f
|
|
|
|
3 -> transform . f . f . f
|
|
|
|
4 -> transform . f . f . f . f
|
|
|
|
_ -> undefined
|
|
|
|
|
|
|
|
-- polymorphic stream version of composeN
|
|
|
|
{-# INLINE composeN' #-}
|
|
|
|
composeN'
|
|
|
|
:: (S.IsStream t, Monad m)
|
|
|
|
=> Int -> (t m Int -> Stream m Int) -> t m Int -> m ()
|
|
|
|
composeN' n f =
|
|
|
|
case n of
|
|
|
|
1 -> transform . f
|
|
|
|
2 -> transform . f . S.adapt . f
|
|
|
|
3 -> transform . f . S.adapt . f . S.adapt . f
|
|
|
|
4 -> transform . f . S.adapt . f . S.adapt . f . S.adapt . f
|
|
|
|
_ -> undefined
|
|
|
|
|
2018-07-25 22:12:53 +03:00
|
|
|
{-# INLINE scan #-}
|
|
|
|
{-# INLINE map #-}
|
|
|
|
{-# INLINE fmap #-}
|
|
|
|
{-# INLINE mapMaybe #-}
|
|
|
|
{-# INLINE filterEven #-}
|
|
|
|
{-# INLINE filterAllOut #-}
|
|
|
|
{-# INLINE filterAllIn #-}
|
|
|
|
{-# INLINE takeOne #-}
|
|
|
|
{-# INLINE takeAll #-}
|
|
|
|
{-# INLINE takeWhileTrue #-}
|
|
|
|
{-# INLINE takeWhileMTrue #-}
|
2018-10-31 14:20:00 +03:00
|
|
|
{-# INLINE dropOne #-}
|
2018-07-25 22:12:53 +03:00
|
|
|
{-# INLINE dropAll #-}
|
|
|
|
{-# INLINE dropWhileTrue #-}
|
|
|
|
{-# INLINE dropWhileMTrue #-}
|
2018-10-31 14:20:00 +03:00
|
|
|
{-# INLINE dropWhileFalse #-}
|
2018-07-25 22:12:53 +03:00
|
|
|
{-# INLINE findIndices #-}
|
|
|
|
{-# INLINE elemIndices #-}
|
2018-10-28 21:51:16 +03:00
|
|
|
scan, map, fmap, mapMaybe, filterEven, filterAllOut,
|
2018-10-31 14:20:00 +03:00
|
|
|
filterAllIn, takeOne, takeAll, takeWhileTrue, takeWhileMTrue, dropOne,
|
|
|
|
dropAll, dropWhileTrue, dropWhileMTrue, dropWhileFalse,
|
2018-07-25 22:12:53 +03:00
|
|
|
findIndices, elemIndices
|
|
|
|
:: Monad m
|
2018-10-28 21:51:16 +03:00
|
|
|
=> Int -> Stream m Int -> m ()
|
2018-07-25 22:12:53 +03:00
|
|
|
|
|
|
|
{-# INLINE mapMaybeM #-}
|
2018-10-28 21:51:16 +03:00
|
|
|
mapMaybeM :: S.MonadAsync m => Int -> Stream m Int -> m ()
|
2018-07-25 22:12:53 +03:00
|
|
|
|
|
|
|
{-# INLINE mapM #-}
|
|
|
|
mapM :: (S.IsStream t, S.MonadAsync m)
|
2018-10-28 21:51:16 +03:00
|
|
|
=> (t m Int -> S.SerialT m Int) -> Int -> t m Int -> m ()
|
2018-07-25 22:12:53 +03:00
|
|
|
|
|
|
|
{-# INLINE sequence #-}
|
|
|
|
sequence :: (S.IsStream t, S.MonadAsync m)
|
|
|
|
=> (t m Int -> S.SerialT m Int) -> t m (m Int) -> m ()
|
|
|
|
|
2018-10-28 21:51:16 +03:00
|
|
|
scan n = composeN n $ S.scanl' (+) 0
|
|
|
|
fmap n = composeN n $ Prelude.fmap (+1)
|
|
|
|
map n = composeN n $ S.map (+1)
|
|
|
|
mapM t n = composeN' n $ t . S.mapM return
|
|
|
|
mapMaybe n = composeN n $ S.mapMaybe
|
|
|
|
(\x -> if Prelude.odd x then Nothing else Just x)
|
|
|
|
mapMaybeM n = composeN n $ S.mapMaybeM
|
|
|
|
(\x -> if Prelude.odd x then return Nothing else return $ Just x)
|
2018-06-25 00:45:22 +03:00
|
|
|
sequence t = transform . t . S.sequence
|
2018-10-28 21:51:16 +03:00
|
|
|
filterEven n = composeN n $ S.filter even
|
|
|
|
filterAllOut n = composeN n $ S.filter (> maxValue)
|
|
|
|
filterAllIn n = composeN n $ S.filter (<= maxValue)
|
|
|
|
takeOne n = composeN n $ S.take 1
|
|
|
|
takeAll n = composeN n $ S.take maxValue
|
|
|
|
takeWhileTrue n = composeN n $ S.takeWhile (<= maxValue)
|
|
|
|
takeWhileMTrue n = composeN n $ S.takeWhileM (return . (<= maxValue))
|
2018-10-31 14:20:00 +03:00
|
|
|
dropOne n = composeN n $ S.drop 1
|
2018-10-28 21:51:16 +03:00
|
|
|
dropAll n = composeN n $ S.drop maxValue
|
|
|
|
dropWhileTrue n = composeN n $ S.dropWhile (<= maxValue)
|
|
|
|
dropWhileMTrue n = composeN n $ S.dropWhileM (return . (<= maxValue))
|
2018-11-06 00:42:08 +03:00
|
|
|
dropWhileFalse n = composeN n $ S.dropWhile (> maxValue)
|
2018-10-28 21:51:16 +03:00
|
|
|
findIndices n = composeN n $ S.findIndices (== maxValue)
|
|
|
|
elemIndices n = composeN n $ S.elemIndices maxValue
|
2018-04-09 18:02:49 +03:00
|
|
|
|
|
|
|
-------------------------------------------------------------------------------
|
2018-10-30 21:30:58 +03:00
|
|
|
-- Iteration
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
2018-11-06 00:42:08 +03:00
|
|
|
iterStreamLen, maxIters :: Int
|
|
|
|
iterStreamLen = 10
|
|
|
|
maxIters = 10000
|
|
|
|
|
2018-10-30 21:30:58 +03:00
|
|
|
{-# INLINE iterateSource #-}
|
|
|
|
iterateSource
|
|
|
|
:: S.MonadAsync m
|
|
|
|
=> (Stream m Int -> Stream m Int) -> Int -> Int -> Stream m Int
|
2018-11-06 00:42:08 +03:00
|
|
|
iterateSource g i n = f i (sourceUnfoldrMN iterStreamLen n)
|
2018-10-30 21:30:58 +03:00
|
|
|
where
|
|
|
|
f (0 :: Int) m = g m
|
|
|
|
f x m = g (f (x P.- 1) m)
|
|
|
|
|
|
|
|
{-# INLINE iterateMapM #-}
|
|
|
|
{-# INLINE iterateScan #-}
|
|
|
|
{-# INLINE iterateFilterEven #-}
|
|
|
|
{-# INLINE iterateTakeAll #-}
|
|
|
|
{-# INLINE iterateDropOne #-}
|
|
|
|
{-# INLINE iterateDropWhileFalse #-}
|
|
|
|
{-# INLINE iterateDropWhileTrue #-}
|
|
|
|
iterateMapM, iterateScan, iterateFilterEven, iterateTakeAll, iterateDropOne,
|
|
|
|
iterateDropWhileFalse, iterateDropWhileTrue
|
|
|
|
:: S.MonadAsync m
|
|
|
|
=> Int -> Stream m Int
|
|
|
|
|
|
|
|
-- this is quadratic
|
2018-11-06 00:42:08 +03:00
|
|
|
iterateScan = iterateSource (S.scanl' (+) 0) (maxIters `div` 10)
|
|
|
|
|
|
|
|
iterateMapM = iterateSource (S.mapM return) maxIters
|
|
|
|
iterateFilterEven = iterateSource (S.filter even) maxIters
|
|
|
|
iterateTakeAll = iterateSource (S.take maxValue) maxIters
|
|
|
|
iterateDropOne = iterateSource (S.drop 1) maxIters
|
|
|
|
iterateDropWhileFalse = iterateSource (S.dropWhile (> maxValue)) maxIters
|
|
|
|
iterateDropWhileTrue = iterateSource (S.dropWhile (<= maxValue)) maxIters
|
2018-10-30 21:30:58 +03:00
|
|
|
|
|
|
|
-------------------------------------------------------------------------------
|
2018-04-09 18:02:49 +03:00
|
|
|
-- Zipping and concat
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
2018-07-25 22:12:53 +03:00
|
|
|
{-# INLINE zip #-}
|
|
|
|
{-# INLINE zipM #-}
|
|
|
|
{-# INLINE concat #-}
|
|
|
|
zip, zipM, concat :: Monad m => Stream m Int -> m ()
|
|
|
|
|
2018-06-27 06:03:06 +03:00
|
|
|
zip src = do
|
|
|
|
r <- S.tail src
|
|
|
|
let src1 = fromJust r
|
2018-10-13 06:11:02 +03:00
|
|
|
transform (S.zipWith (,) src src1)
|
2018-06-27 06:03:06 +03:00
|
|
|
zipM src = do
|
|
|
|
r <- S.tail src
|
|
|
|
let src1 = fromJust r
|
2018-10-13 06:11:02 +03:00
|
|
|
transform (S.zipWithM (curry return) src src1)
|
2018-10-24 07:37:02 +03:00
|
|
|
|
|
|
|
{-# INLINE zipAsync #-}
|
|
|
|
{-# INLINE zipAsyncM #-}
|
|
|
|
zipAsync, zipAsyncM :: S.MonadAsync m => Stream m Int -> m ()
|
|
|
|
|
2018-06-27 06:03:06 +03:00
|
|
|
zipAsync src = do
|
|
|
|
r <- S.tail src
|
|
|
|
let src1 = fromJust r
|
2018-10-13 06:11:02 +03:00
|
|
|
transform (S.zipAsyncWith (,) src src1)
|
2018-06-27 06:03:06 +03:00
|
|
|
zipAsyncM src = do
|
|
|
|
r <- S.tail src
|
|
|
|
let src1 = fromJust r
|
2018-10-13 06:11:02 +03:00
|
|
|
transform (S.zipAsyncWithM (curry return) src src1)
|
2018-04-09 18:02:49 +03:00
|
|
|
concat _n = return ()
|
|
|
|
|
|
|
|
-------------------------------------------------------------------------------
|
2018-10-28 21:51:16 +03:00
|
|
|
-- Mixed Composition
|
2018-04-09 18:02:49 +03:00
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
2018-10-28 21:51:16 +03:00
|
|
|
{-# INLINE scanMap #-}
|
|
|
|
{-# INLINE dropMap #-}
|
|
|
|
{-# INLINE dropScan #-}
|
|
|
|
{-# INLINE takeDrop #-}
|
|
|
|
{-# INLINE takeScan #-}
|
|
|
|
{-# INLINE takeMap #-}
|
|
|
|
{-# INLINE filterDrop #-}
|
|
|
|
{-# INLINE filterTake #-}
|
|
|
|
{-# INLINE filterScan #-}
|
|
|
|
{-# INLINE filterMap #-}
|
|
|
|
scanMap, dropMap, dropScan, takeDrop, takeScan, takeMap, filterDrop,
|
|
|
|
filterTake, filterScan, filterMap
|
|
|
|
:: Monad m => Int -> Stream m Int -> m ()
|
|
|
|
|
|
|
|
scanMap n = composeN n $ S.map (subtract 1) . S.scanl' (+) 0
|
|
|
|
dropMap n = composeN n $ S.map (subtract 1) . S.drop 1
|
|
|
|
dropScan n = composeN n $ S.scanl' (+) 0 . S.drop 1
|
|
|
|
takeDrop n = composeN n $ S.drop 1 . S.take maxValue
|
|
|
|
takeScan n = composeN n $ S.scanl' (+) 0 . S.take maxValue
|
|
|
|
takeMap n = composeN n $ S.map (subtract 1) . S.take maxValue
|
|
|
|
filterDrop n = composeN n $ S.drop 1 . S.filter (<= maxValue)
|
|
|
|
filterTake n = composeN n $ S.take maxValue . S.filter (<= maxValue)
|
|
|
|
filterScan n = composeN n $ S.scanl' (+) 0 . S.filter (<= maxBound)
|
|
|
|
filterMap n = composeN n $ S.map (subtract 1) . S.filter (<= maxValue)
|