on master help sign in
Fixed insertBy to use correct state. Add deleteBy.
acc3871Pranay Sashank
benchmark/Linear.hs+8
@@ -138,6 +138,10 @@ main =
138 , benchIOSink "findIndices" (Ops.findIndices 1)
138 , benchIOSink "findIndices" (Ops.findIndices 1)
139 , benchIOSink "elemIndices" (Ops.elemIndices 1)
139 , benchIOSink "elemIndices" (Ops.elemIndices 1)
140 -- , benchIOSink "concat" Ops.concat
140 -- , benchIOSink "concat" Ops.concat
141+ , benchIOSink "insertLarge" (Ops.insertLarge 1)
142+ , benchIOSink "insertSmall" (Ops.insertSmall 1)
143+ , benchIOSink "deleteLarge" (Ops.deleteLarge 1)
144+ , benchIOSink "deleteSmall" (Ops.deleteSmall 1)
141 ]
145 ]
142 , bgroup "transformationX4"
146 , bgroup "transformationX4"
143 [ benchIOSink "scan" (Ops.scan 4)
147 [ benchIOSink "scan" (Ops.scan 4)
@@ -151,6 +155,10 @@ main =
151 -- Ops.sequence serially (Ops.sourceUnfoldrMAction n)
155 -- Ops.sequence serially (Ops.sourceUnfoldrMAction n)
152 , benchIOSink "findIndices" (Ops.findIndices 4)
156 , benchIOSink "findIndices" (Ops.findIndices 4)
153 , benchIOSink "elemIndices" (Ops.elemIndices 4)
157 , benchIOSink "elemIndices" (Ops.elemIndices 4)
158+ , benchIOSink "insertLarge" (Ops.insertLarge 4)
159+ , benchIOSink "insertSmall" (Ops.insertSmall 4)
160+ , benchIOSink "deleteLarge" (Ops.deleteLarge 4)
161+ , benchIOSink "deleteSmall" (Ops.deleteSmall 4)
154 -- , benchIOSink "concat" Ops.concat
162 -- , benchIOSink "concat" Ops.concat
155 ]
163 ]
156 , bgroup "filtering"
164 , bgroup "filtering"
benchmark/LinearOps.hs+7−2
@@ -15,7 +15,7 @@ import Control.Monad (when)
15import Data.Functor.Identity (Identity, runIdentity)
15import Data.Functor.Identity (Identity, runIdentity)
16import Data.Maybe (fromJust)
16import Data.Maybe (fromJust)
17import Prelude
17import Prelude
18− (Monad, Int, (+), ($), (.), return, fmap, even, (>), (<=), (==), (<=),
18+ (Monad, Int, (+), ($), (.), return, fmap, even, (>), (<=), (==), (>=),
19 subtract, undefined, Maybe(..), odd, Bool, not, (>>=), mapM_, curry,
19 subtract, undefined, Maybe(..), odd, Bool, not, (>>=), mapM_, curry,
20 maxBound, div, IO, compare)
20 maxBound, div, IO, compare)
21import qualified Prelude as P
21import qualified Prelude as P
@@ -275,7 +275,8 @@ composeN' n f =
275scan, scanl1, map, fmap, mapMaybe, filterEven, filterAllOut,
275scan, scanl1, map, fmap, mapMaybe, filterEven, filterAllOut,
276 filterAllIn, takeOne, takeAll, takeWhileTrue, takeWhileMTrue, dropOne,
276 filterAllIn, takeOne, takeAll, takeWhileTrue, takeWhileMTrue, dropOne,
277 dropAll, dropWhileTrue, dropWhileMTrue, dropWhileFalse,
277 dropAll, dropWhileTrue, dropWhileMTrue, dropWhileFalse,
278− findIndices, elemIndices
278+ findIndices, elemIndices, insertLarge, insertSmall, deleteLarge,
279+ deleteSmall
279 :: Monad m
280 :: Monad m
280 => Int -> Stream m Int -> m ()
281 => Int -> Stream m Int -> m ()
281
282
@@ -314,6 +315,10 @@ dropWhileMTrue n = composeN n $ S.dropWhileM (return . (<= maxValue))
314dropWhileFalse n = composeN n $ S.dropWhile (> maxValue)
315dropWhileFalse n = composeN n $ S.dropWhile (> maxValue)
315findIndices n = composeN n $ S.findIndices (== maxValue)
316findIndices n = composeN n $ S.findIndices (== maxValue)
316elemIndices n = composeN n $ S.elemIndices maxValue
317elemIndices n = composeN n $ S.elemIndices maxValue
318+insertLarge n = composeN n $ S.insertBy compare maxValue
319+insertSmall n = composeN n $ S.insertBy compare 0
320+deleteSmall n = composeN n $ S.deleteBy (==) 0
321+deleteLarge n = composeN n $ S.deleteBy (>=) maxValue
317
322
318-------------------------------------------------------------------------------
323-------------------------------------------------------------------------------
319-- Iteration
324-- Iteration
src/Streamly/Prelude.hs+17
@@ -205,6 +205,9 @@ module Streamly.Prelude
205 , intersperseM
205 , intersperseM
206 , insertBy
206 , insertBy
207
207
208+ -- ** Deleting
209+ , deleteBy
210+
208 -- * Reordering
211 -- * Reordering
209 , reverse
212 , reverse
210
213
@@ -1072,11 +1075,25 @@ reverse m = fromStream $ go K.nil (toStream m)
1072intersperseM :: (IsStream t, MonadAsync m) => m a -> t m a -> t m a
1075intersperseM :: (IsStream t, MonadAsync m) => m a -> t m a -> t m a
1073intersperseM = K.intersperseM
1076intersperseM = K.intersperseM
1074
1077
1078+-- | Inserts @x@ before the first element in the Stream that is
1079+-- less than @x@, based on the user supplied comparison function.
1080+--
1075{-# INLINE insertBy #-}
1081{-# INLINE insertBy #-}
1076insertBy ::
1082insertBy ::
1077 (IsStream t, Monad m) => (a -> a -> Ordering) -> a -> t m a -> t m a
1083 (IsStream t, Monad m) => (a -> a -> Ordering) -> a -> t m a -> t m a
1078insertBy cmp x m = fromStreamS $ S.insertBy cmp x (toStreamS m)
1084insertBy cmp x m = fromStreamS $ S.insertBy cmp x (toStreamS m)
1079
1085
1086+------------------------------------------------------------------------------
1087+-- Deleting
1088+------------------------------------------------------------------------------
1089+
1090+-- | Deletes the first occurence of @x@ in the Stream that satisfies the
1091+-- equality predicate.
1092+--
1093+{-# INLINE deleteBy #-}
1094+deleteBy :: (IsStream t, Monad m) => (a -> a -> Bool) -> a -> t m a -> t m a
1095+deleteBy cmp x m = fromStreamS $ S.deleteBy cmp x (toStreamS m)
1096+
1080------------------------------------------------------------------------------
1097------------------------------------------------------------------------------
1081-- Zipping
1098-- Zipping
1082------------------------------------------------------------------------------
1099------------------------------------------------------------------------------
src/Streamly/Streams/StreamD.hs+39−8
@@ -128,6 +128,9 @@ module Streamly.Streams.StreamD
128 -- * Inserting
128 -- * Inserting
129 , insertBy
129 , insertBy
130
130
131+ -- * Deleting
132+ , deleteBy
133+
131 -- ** Map and Filter
134 -- ** Map and Filter
132 , mapMaybe
135 , mapMaybe
133 , mapMaybeM
136 , mapMaybeM
@@ -867,22 +870,50 @@ sequence (Stream step state) = Stream step' state
867
870
868{-# INLINE_NORMAL insertBy #-}
871{-# INLINE_NORMAL insertBy #-}
869insertBy :: Monad m => (a -> a -> Ordering) -> a -> Stream m a -> Stream m a
872insertBy :: Monad m => (a -> a -> Ordering) -> a -> Stream m a -> Stream m a
870−insertBy cmp a (Stream step state) = Stream step' (state, False)
873+insertBy cmp a (Stream step state) = Stream step' (state, False, Nothing)
871 where
874 where
875+ {-# INLINE_LATE step' #-}
872− step' gst (st, False) = do
876+ step' gst (st, False, _) = do
873 r <- step (rstState gst) st
877 r <- step (rstState gst) st
874 case r of
878 case r of
875 Yield x s -> case cmp a x of
879 Yield x s -> case cmp a x of
876− GT -> return $ Yield x (s, False)
880+ GT -> return $ Yield x (s, False, Nothing)
877− _ -> return $ Yield a (st, True)
881+ _ -> return $ Yield a (s, True, Just x)
882+ Skip s -> return $ Skip (s, False, Nothing)
883+ Stop -> return $ Yield a (st, True, Nothing)
884+
885+ step' _ (_, True, Nothing) = return Stop
886+
887+ step' gst (st, True, Just prev) = do
888+ r <- step (rstState gst) st
889+ case r of
890+ Yield x s -> return $ Yield prev (s, True, Just x)
891+ Skip s -> return $ Skip (s, True, Just prev)
892+ Stop -> return $ Yield prev (st, True, Nothing)
893+
894+------------------------------------------------------------------------------
895+-- Deleting
896+------------------------------------------------------------------------------
897+
898+{-# INLINE_NORMAL deleteBy #-}
899+deleteBy :: Monad m => (a -> a -> Bool) -> a -> Stream m a -> Stream m a
900+deleteBy eq x (Stream step state) = Stream step' (state, False)
901+ where
902+ {-# INLINE_LATE step' #-}
903+ step' gst (st, False) = do
904+ r <- step (rstState gst) st
905+ case r of
906+ Yield y s -> return $
907+ if eq x y then Skip (s, True) else Yield y (s, False)
878 Skip s -> return $ Skip (s, False)
908 Skip s -> return $ Skip (s, False)
879− Stop -> return $ Yield a (st, True)
909+ Stop -> return Stop
910+
880 step' gst (st, True) = do
911 step' gst (st, True) = do
881 r <- step (rstState gst) st
912 r <- step (rstState gst) st
882 case r of
913 case r of
883− Yield x s -> return $ Yield x (s, True)
914+ Yield y s -> return $ Yield y (s, True)
884− Skip s -> return $ Skip (s, True)
915+ Skip s -> return $ Skip (s, True)
885− Stop -> return Stop
916+ Stop -> return Stop
886
917
887------------------------------------------------------------------------------
918------------------------------------------------------------------------------
888-- Transformation by Map and Filter
919-- Transformation by Map and Filter
src/Streamly/Streams/StreamK.hs+18
@@ -126,6 +126,9 @@ module Streamly.Streams.StreamK
126 , intersperseM
126 , intersperseM
127 , insertBy
127 , insertBy
128
128
129+ -- ** Deleting
130+ , deleteBy
131+
129 -- ** Map and Filter
132 -- ** Map and Filter
130 , mapMaybe
133 , mapMaybe
131
134
@@ -990,6 +993,21 @@ insertBy cmp x m = fromStream $ go (toStream m)
990 _ -> yld x (a `cons` r)
993 _ -> yld x (a `cons` r)
991 in unStream m1 (rstState st) stop single yieldk
994 in unStream m1 (rstState st) stop single yieldk
992
995
996+------------------------------------------------------------------------------
997+-- Deleting
998+------------------------------------------------------------------------------
999+
1000+{-# INLINE deleteBy #-}
1001+deleteBy :: IsStream t => (a -> a -> Bool) -> a -> t m a -> t m a
1002+deleteBy eq x m = fromStream $ go (toStream m)
1003+ where
1004+ go m1 = Stream $ \st stp sng yld ->
1005+ let single a = if eq x a then stp else sng a
1006+ yieldk a r = if eq x a
1007+ then unStream r (rstState st) stp sng yld
1008+ else yld a (go r)
1009+ in unStream m1 (rstState st) stp single yieldk
1010+
993-------------------------------------------------------------------------------
1011-------------------------------------------------------------------------------
994-- Map and Filter
1012-- Map and Filter
995-------------------------------------------------------------------------------
1013-------------------------------------------------------------------------------
test/Prop.hs+7−1
@@ -14,7 +14,7 @@ import Data.IORef (readIORef, modifyIORef, newIORef)
14import Data.List
14import Data.List
15 (sort, foldl', scanl', findIndices, findIndex, elemIndices,
15 (sort, foldl', scanl', findIndices, findIndex, elemIndices,
16 elemIndex, find, insertBy, intersperse, foldl1', (\\),
16 elemIndex, find, insertBy, intersperse, foldl1', (\\),
17− maximumBy, minimumBy)
17+ maximumBy, minimumBy, deleteBy)
18import Data.Maybe (mapMaybe)
18import Data.Maybe (mapMaybe)
19import GHC.Word (Word8)
19import GHC.Word (Word8)
20
20
@@ -384,6 +384,12 @@ transformOps constr desc eq t = do
384 transform (insertBy compare 0) $ t . S.insertBy compare 0
384 transform (insertBy compare 0) $ t . S.insertBy compare 0
385 prop (desc <> " insertBy 4") $
385 prop (desc <> " insertBy 4") $
386 transform (insertBy compare 4) $ t . S.insertBy compare 4
386 transform (insertBy compare 4) $ t . S.insertBy compare 4
387+ prop (desc <> " deleteBy (<=) maxBound") $
388+ transform (deleteBy (<=) maxBound) $ t . S.deleteBy (<=) maxBound
389+ prop (desc <> " deleteBy (<=) 0") $
390+ transform (deleteBy (<=) 0) $ t . S.deleteBy (<=) 0
391+ prop (desc <> " deleteBy (==) 4") $
392+ transform (deleteBy (==) 4) $ t . S.deleteBy (==) 4
387
393
388concurrentOps
394concurrentOps
389 :: IsStream t
395 :: IsStream t