on master help sign in
Add uniq, indexed, indexedR.
5fc469aPranay Sashank
Changelog.md+5−1
@@ -2,7 +2,11 @@
2
2
3* Add benchmarks to measure composed and iterated operations
3* Add benchmarks to measure composed and iterated operations
4* Performance improvements
4* Performance improvements
5−* Add `(!!)`, `insertBy`, `mergeBy`, `merge`, `splitAt`, `the` to Prelude.
5+* Add `(!!)`, `insertBy`, `mergeBy`, `merge`, `splitAt`, `the`, `maximumBy`,
6+ `minimumBy`, `scanl1`, `scanl1M`, `scanl1'`, `scanl1M'`, `scanl`, `scanlM`,
7+ `deleteBy`, `isPrefixOf`, `isSubsequenceOf`, `stripPrefix`,
8+ `replicate`, `generateM`, `generate`, `concatMap`, `concatMapM`,
9+ `findM`, `uniq`, `indexed`, `indexedR` to Prelude.
6
10
7## 0.5.2
11## 0.5.2
8
12
src/Streamly/Prelude.hs+22
@@ -204,6 +204,7 @@ module Streamly.Prelude
204 -- ** Filtering
204 -- ** Filtering
205 , filter
205 , filter
206 , filterM
206 , filterM
207+ , uniq
207 , take
208 , take
208 , takeWhile
209 , takeWhile
209 , takeWhileM
210 , takeWhileM
@@ -235,6 +236,8 @@ module Streamly.Prelude
235 , elemIndices
236 , elemIndices
236
237
237 -- * Zipping
238 -- * Zipping
239+ , indexed
240+ , indexedR
238 , zipWith
241 , zipWith
239 , zipWithM
242 , zipWithM
240 , Z.zipAsyncWith
243 , Z.zipAsyncWith
@@ -993,6 +996,12 @@ filter = K.filter
993filterM :: (IsStream t, Monad m) => (a -> m Bool) -> t m a -> t m a
996filterM :: (IsStream t, Monad m) => (a -> m Bool) -> t m a -> t m a
994filterM p m = fromStreamD $ D.filterM p $ toStreamD m
997filterM p m = fromStreamD $ D.filterM p $ toStreamD m
995
998
999+-- | Drop repeated elements that are adjacent to each other.
1000+--
1001+{-# INLINE uniq #-}
1002+uniq :: (Eq a, IsStream t, Monad m) => t m a -> t m a
1003+uniq = fromStreamD . D.uniq . toStreamD
1004+
996-- | Take first 'n' elements from the stream and discard the rest.
1005-- | Take first 'n' elements from the stream and discard the rest.
997--
1006--
998-- @since 0.1.0
1007-- @since 0.1.0
@@ -1170,6 +1179,19 @@ deleteBy cmp x m = fromStreamS $ S.deleteBy cmp x (toStreamS m)
1170-- Zipping
1179-- Zipping
1171------------------------------------------------------------------------------
1180------------------------------------------------------------------------------
1172
1181
1182+-- | Pair each element in a stream with its index.
1183+--
1184+{-# INLINE indexed #-}
1185+indexed :: (IsStream t, Monad m) => t m a -> t m (Int, a)
1186+indexed = fromStreamD . D.indexed . toStreamD
1187+
1188+-- | Pair each element in a stream with its index, starting from the
1189+-- given index @n@ and counting down.
1190+--
1191+{-# INLINE indexedR #-}
1192+indexedR :: (IsStream t, Monad m) => Int -> t m a -> t m (Int, a)
1193+indexedR n = fromStreamD . D.indexedR n . toStreamD
1194+
1173-- | Zip two streams serially using a monadic zipping function.
1195-- | Zip two streams serially using a monadic zipping function.
1174--
1196--
1175-- @since 0.4.0
1197-- @since 0.4.0
src/Streamly/Streams/StreamD.hs+48
@@ -123,6 +123,7 @@ module Streamly.Streams.StreamD
123 -- * Filtering
123 -- * Filtering
124 , filter
124 , filter
125 , filterM
125 , filterM
126+ , uniq
126 , take
127 , take
127 , takeWhile
128 , takeWhile
128 , takeWhileM
129 , takeWhileM
@@ -146,6 +147,8 @@ module Streamly.Streams.StreamD
146 , mapMaybeM
147 , mapMaybeM
147
148
148 -- * Zipping
149 -- * Zipping
150+ , indexed
151+ , indexedR
149 , zipWith
152 , zipWith
150 , zipWithM
153 , zipWithM
151
154
@@ -954,6 +957,25 @@ filterM f (Stream step state) = Stream step' state
954filter :: Monad m => (a -> Bool) -> Stream m a -> Stream m a
957filter :: Monad m => (a -> Bool) -> Stream m a -> Stream m a
955filter f = filterM (return . f)
958filter f = filterM (return . f)
956
959
960+{-# INLINE_NORMAL uniq #-}
961+uniq :: (Eq a, Monad m) => Stream m a -> Stream m a
962+uniq (Stream step state) = Stream step' (Nothing, state)
963+ where
964+ {-# INLINE_LATE step' #-}
965+ step' gst (Nothing, st) = do
966+ r <- step (rstState gst) st
967+ case r of
968+ Yield x s -> return $ Yield x (Just x, s)
969+ Skip s -> return $ Skip (Nothing, s)
970+ Stop -> return Stop
971+ step' gst (Just x, st) = do
972+ r <- step (rstState gst) st
973+ case r of
974+ Yield y s | x == y -> return $ Skip (Just x, s)
975+ | otherwise -> return $ Yield x (Just y, s)
976+ Skip s -> return $ Skip (Just x, s)
977+ Stop -> return Stop
978+
957------------------------------------------------------------------------------
979------------------------------------------------------------------------------
958-- Transformation by Mapping
980-- Transformation by Mapping
959------------------------------------------------------------------------------
981------------------------------------------------------------------------------
@@ -1055,6 +1077,32 @@ mapMaybeM f = fmap fromJust . filter isJust . mapM f
1055-- Zipping
1077-- Zipping
1056------------------------------------------------------------------------------
1078------------------------------------------------------------------------------
1057
1079
1080+{-# INLINE_NORMAL indexed #-}
1081+indexed :: Monad m => Stream m a -> Stream m (Int, a)
1082+indexed (Stream step state) = Stream step' (state, 0)
1083+ where
1084+ {-# INLINE_LATE step' #-}
1085+ step' gst (st, i) = i `seq` do
1086+ r <- step (rstState gst) st
1087+ case r of
1088+ Yield x s -> return $ Yield (i, x) (s, i+1)
1089+ Skip s -> return $ Skip (s, i)
1090+ Stop -> return Stop
1091+
1092+{-# INLINE_NORMAL indexedR #-}
1093+indexedR :: Monad m => Int -> Stream m a -> Stream m (Int, a)
1094+indexedR m (Stream step state) = Stream step' (state, m)
1095+ where
1096+ {-# INLINE_LATE step' #-}
1097+ step' gst (st, i) = i `seq` do
1098+ r <- step (rstState gst) st
1099+ case r of
1100+ Yield x s -> let i' = i - 1
1101+ in
1102+ return $ Yield (i', x) (s, i')
1103+ Skip s -> return $ Skip (s, i)
1104+ Stop -> return Stop
1105+
1058{-# INLINE_NORMAL zipWithM #-}
1106{-# INLINE_NORMAL zipWithM #-}
1059zipWithM :: Monad m
1107zipWithM :: Monad m
1060 => (a -> b -> m c) -> Stream m a -> Stream m b -> Stream m c
1108 => (a -> b -> m c) -> Stream m a -> Stream m b -> Stream m c