on master help sign in
Move sliceOnSuffix to lower level Stream module
b19e108Harendra Kumar
core/src/Streamly/Internal/Data/Array.hs+1−1
@@ -331,7 +331,7 @@ splitOn :: (Monad m, Unbox a) =>
331 (a -> Bool) -> Array a -> Stream m (Array a)
331 (a -> Bool) -> Array a -> Stream m (Array a)
332splitOn predicate arr =
332splitOn predicate arr =
333 fmap (\(i, len) -> getSliceUnsafe i len arr)
333 fmap (\(i, len) -> getSliceUnsafe i len arr)
334− $ D.sliceOnSuffix predicate (A.toStreamD arr)
334+ $ D.indexOnSuffix predicate (A.toStreamD arr)
335
335
336{-# INLINE sliceIndexerFromLen #-}
336{-# INLINE sliceIndexerFromLen #-}
337sliceIndexerFromLen :: forall m a. (Monad m, Unbox a)
337sliceIndexerFromLen :: forall m a. (Monad m, Unbox a)
core/src/Streamly/Internal/Data/MutArray/Type.hs+1−1
@@ -2394,7 +2394,7 @@ splitOn :: (MonadIO m, Unbox a) =>
2394 (a -> Bool) -> MutArray a -> Stream m (MutArray a)
2394 (a -> Bool) -> MutArray a -> Stream m (MutArray a)
2395splitOn predicate arr =
2395splitOn predicate arr =
2396 fmap (\(i, len) -> getSliceUnsafe i len arr)
2396 fmap (\(i, len) -> getSliceUnsafe i len arr)
2397− $ D.rangesOnSuffix predicate (read arr)
2397+ $ D.indexOnSuffix predicate (read arr)
2398
2398
2399-- | Drops the separator byte
2399-- | Drops the separator byte
2400{-# INLINE breakOn #-}
2400{-# INLINE breakOn #-}
core/src/Streamly/Internal/Data/Stream/Nesting.hs−75
@@ -149,7 +149,6 @@ module Streamly.Internal.Data.Stream.Nesting
149 , wordsBy
149 , wordsBy
150 , splitOnSeq
150 , splitOnSeq
151 , splitOnSuffixSeq
151 , splitOnSuffixSeq
152− , sliceOnSuffix
153
152
154 -- XXX Implement these as folds or parsers instead.
153 -- XXX Implement these as folds or parsers instead.
155 , splitOnSuffixSeqAny
154 , splitOnSuffixSeqAny
@@ -182,12 +181,9 @@ import Fusion.Plugin.Types (Fuse(..))
182import GHC.Types (SPEC(..))
181import GHC.Types (SPEC(..))
183
182
184import Streamly.Internal.Data.Array.Type (Array(..))
183import Streamly.Internal.Data.Array.Type (Array(..))
185−import Streamly.Internal.Data.Fold.Step (Step(..))
186import Streamly.Internal.Data.Fold.Type (Fold(..))
184import Streamly.Internal.Data.Fold.Type (Fold(..))
187import Streamly.Internal.Data.Parser (ParseError(..))
185import Streamly.Internal.Data.Parser (ParseError(..))
188−import Streamly.Internal.Data.Refold.Type (Refold(..))
189import Streamly.Internal.Data.SVar.Type (adaptState)
186import Streamly.Internal.Data.SVar.Type (adaptState)
190−import Streamly.Internal.Data.Tuple.Strict (Tuple'(..))
191import Streamly.Internal.Data.Unbox (Unbox, sizeOf)
187import Streamly.Internal.Data.Unbox (Unbox, sizeOf)
192import Streamly.Internal.Data.Unfold.Type (Unfold(..))
188import Streamly.Internal.Data.Unfold.Type (Unfold(..))
193
189
@@ -1294,77 +1290,6 @@ foldIterateM func seed0 (Stream step state) =
1294 stepOuter _ (FIterYield a next) = return $ Yield a next
1290 stepOuter _ (FIterYield a next) = return $ Yield a next
1295 stepOuter _ FIterStop = return Stop
1291 stepOuter _ FIterStop = return Stop
1296
1292
1297−{-# ANN type CIterState Fuse #-}
1298−data CIterState s f fs b
1299− = CIterInit s f
1300− | CIterConsume s fs
1301− | CIterYield b (CIterState s f fs b)
1302− | CIterStop
1303−
1304−-- | Like 'foldIterateM' but using the 'Refold' type instead. This could be
1305−-- much more efficient due to stream fusion.
1306−--
1307−-- /Internal/
1308−{-# INLINE_NORMAL refoldIterateM #-}
1309−refoldIterateM ::
1310− Monad m => Refold m b a b -> m b -> Stream m a -> Stream m b
1311−refoldIterateM (Refold fstep finject fextract) initial (Stream step state) =
1312− Stream stepOuter (CIterInit state initial)
1313−
1314− where
1315−
1316− {-# INLINE iterStep #-}
1317− iterStep st action = do
1318− res <- action
1319− return
1320− $ Skip
1321− $ case res of
1322− FL.Partial fs -> CIterConsume st fs
1323− FL.Done fb -> CIterYield fb $ CIterInit st (return fb)
1324−
1325− {-# INLINE_LATE stepOuter #-}
1326− stepOuter _ (CIterInit st action) = do
1327− iterStep st (action >>= finject)
1328− stepOuter gst (CIterConsume st fs) = do
1329− r <- step (adaptState gst) st
1330− case r of
1331− Yield x s -> iterStep s (fstep fs x)
1332− Skip s -> return $ Skip $ CIterConsume s fs
1333− Stop -> do
1334− b <- fextract fs
1335− return $ Skip $ CIterYield b CIterStop
1336− stepOuter _ (CIterYield a next) = return $ Yield a next
1337− stepOuter _ CIterStop = return Stop
1338−
1339−-- "n" elements at the end are dropped by the fold.
1340−{-# INLINE sliceBy #-}
1341−sliceBy :: Monad m => Fold m a Int -> Int -> Refold m (Int, Int) a (Int, Int)
1342−sliceBy (Fold step1 initial1 extract1 _final) n = Refold step inject extract
1343−
1344− where
1345−
1346− inject (i, len) = do
1347− r <- initial1
1348− return $ case r of
1349− Partial s -> Partial $ Tuple' (i + len + n) s
1350− Done l -> Done (i, l)
1351−
1352− step (Tuple' i s) x = do
1353− r <- step1 s x
1354− return $ case r of
1355− Partial s1 -> Partial $ Tuple' i s1
1356− Done len -> Done (i, len)
1357−
1358− extract (Tuple' i s) = (i,) <$> extract1 s
1359−
1360−{-# INLINE sliceOnSuffix #-}
1361−sliceOnSuffix :: Monad m => (a -> Bool) -> Stream m a -> Stream m (Int, Int)
1362−sliceOnSuffix predicate =
1363− -- Scan the stream with the given refold
1364− refoldIterateM
1365− (sliceBy (FL.takeEndBy_ predicate FL.length) 1)
1366− (return (-1, 0))
1367−
1368------------------------------------------------------------------------------
1293------------------------------------------------------------------------------
1369-- Parsing
1294-- Parsing
1370------------------------------------------------------------------------------
1295------------------------------------------------------------------------------
core/src/Streamly/Internal/Data/Stream/Type.hs+92
@@ -123,14 +123,21 @@ module Streamly.Internal.Data.Stream.Type
123 , foldManyPost
123 , foldManyPost
124 , groupsOf
124 , groupsOf
125 , refoldMany
125 , refoldMany
126+ , refoldIterateM
126
127
127 -- * Fold Iterate
128 -- * Fold Iterate
128 , reduceIterateBfs
129 , reduceIterateBfs
129 , foldIterateBfs
130 , foldIterateBfs
130
131
132+ -- * Splitting
133+ , indexOnSuffix
134+
131 -- * Multi-stream folds
135 -- * Multi-stream folds
132 , eqBy
136 , eqBy
133 , cmpBy
137 , cmpBy
138+
139+ -- * Deprecated
140+ , sliceOnSuffix
134 )
141 )
135where
142where
136
143
@@ -162,6 +169,7 @@ import Streamly.Internal.Data.Maybe.Strict (Maybe'(..), toMaybe)
162import Streamly.Internal.Data.Refold.Type (Refold(..))
169import Streamly.Internal.Data.Refold.Type (Refold(..))
163import Streamly.Internal.Data.Stream.Step (Step (..))
170import Streamly.Internal.Data.Stream.Step (Step (..))
164import Streamly.Internal.Data.SVar.Type (State, adaptState, defState)
171import Streamly.Internal.Data.SVar.Type (State, adaptState, defState)
172+import Streamly.Internal.Data.Tuple.Strict (Tuple'(..))
165import Streamly.Internal.Data.Unfold.Type (Unfold(..))
173import Streamly.Internal.Data.Unfold.Type (Unfold(..))
166
174
167import qualified Streamly.Internal.Data.Fold.Type as FL hiding (foldr)
175import qualified Streamly.Internal.Data.Fold.Type as FL hiding (foldr)
@@ -1974,6 +1982,90 @@ refoldMany (Refold fstep inject extract) action (Stream step state) =
1974 step' _ (FoldManyYield b next) = return $ Yield b next
1982 step' _ (FoldManyYield b next) = return $ Yield b next
1975 step' _ FoldManyDone = return Stop
1983 step' _ FoldManyDone = return Stop
1976
1984
1985+{-# ANN type CIterState Fuse #-}
1986+data CIterState s f fs b
1987+ = CIterInit s f
1988+ | CIterConsume s fs
1989+ | CIterYield b (CIterState s f fs b)
1990+ | CIterStop
1991+
1992+-- | Like 'foldIterateM' but using the 'Refold' type instead. This could be
1993+-- much more efficient due to stream fusion.
1994+--
1995+-- /Internal/
1996+{-# INLINE_NORMAL refoldIterateM #-}
1997+refoldIterateM ::
1998+ Monad m => Refold m b a b -> m b -> Stream m a -> Stream m b
1999+refoldIterateM (Refold fstep finject fextract) initial (Stream step state) =
2000+ Stream stepOuter (CIterInit state initial)
2001+
2002+ where
2003+
2004+ {-# INLINE iterStep #-}
2005+ iterStep st action = do
2006+ res <- action
2007+ return
2008+ $ Skip
2009+ $ case res of
2010+ FL.Partial fs -> CIterConsume st fs
2011+ FL.Done fb -> CIterYield fb $ CIterInit st (return fb)
2012+
2013+ {-# INLINE_LATE stepOuter #-}
2014+ stepOuter _ (CIterInit st action) = do
2015+ iterStep st (action >>= finject)
2016+ stepOuter gst (CIterConsume st fs) = do
2017+ r <- step (adaptState gst) st
2018+ case r of
2019+ Yield x s -> iterStep s (fstep fs x)
2020+ Skip s -> return $ Skip $ CIterConsume s fs
2021+ Stop -> do
2022+ b <- fextract fs
2023+ return $ Skip $ CIterYield b CIterStop
2024+ stepOuter _ (CIterYield a next) = return $ Yield a next
2025+ stepOuter _ CIterStop = return Stop
2026+
2027+-- | The refold @indexerBy f n@ takes an (index, len) tuple as initial input,
2028+-- and returns @(index + len + n, b)@ as output where @b@ is the output of the
2029+-- fold.
2030+{-# INLINE indexerBy #-}
2031+indexerBy :: Monad m =>
2032+ Fold m a Int -> Int -> Refold m (Int, Int) a (Int, Int)
2033+indexerBy (Fold step1 initial1 extract1 _final) n =
2034+ Refold step inject extract
2035+
2036+ where
2037+
2038+ inject (i, len) = do
2039+ r <- initial1
2040+ return $ case r of
2041+ FL.Partial s -> FL.Partial $ Tuple' (i + len + n) s
2042+ FL.Done l -> FL.Done (i, l)
2043+
2044+ step (Tuple' i s) x = do
2045+ r <- step1 s x
2046+ return $ case r of
2047+ FL.Partial s1 -> FL.Partial $ Tuple' i s1
2048+ FL.Done len -> FL.Done (i, len)
2049+
2050+ extract (Tuple' i s) = (i,) <$> extract1 s
2051+
2052+-- | Like 'splitOnSuffix' but generates a stream of (index, len) tuples marking
2053+-- the places where the predicate matches in the stream.
2054+--
2055+-- /Pre-release/
2056+{-# INLINE indexOnSuffix #-}
2057+indexOnSuffix :: Monad m =>
2058+ (a -> Bool) -> Stream m a -> Stream m (Int, Int)
2059+indexOnSuffix predicate =
2060+ -- Scan the stream with the given refold
2061+ refoldIterateM
2062+ (indexerBy (FL.takeEndBy_ predicate FL.length) 1)
2063+ (return (-1, 0))
2064+
2065+{-# DEPRECATED sliceOnSuffix "Please use indexOnSuffix instead." #-}
2066+sliceOnSuffix :: Monad m => (a -> Bool) -> Stream m a -> Stream m (Int, Int)
2067+sliceOnSuffix = indexOnSuffix
2068+
1977------------------------------------------------------------------------------
2069------------------------------------------------------------------------------
1978-- Stream with a cross product style monad instance
2070-- Stream with a cross product style monad instance
1979------------------------------------------------------------------------------
2071------------------------------------------------------------------------------