@@ -146,16 +146,10 @@ module Streamly.Fold
146146 -- ** Filtering
147147 , lfilter
148148 , lfilterM
149− , ltake
150− , ltakeWhile
151− {-
152− , ltakeWhileM
153− , ldrop
154− , ldropWhile
155− , ldropWhileM
156− , ldeleteBy
157− , luniq
149+ -- , ldeleteBy
150+ -- , luniq
158151
152+ {-
159153 -- ** Mapping Filters
160154 , lmapMaybe
161155 , lmapMaybeM
@@ -174,23 +168,36 @@ module Streamly.Fold
174168 , lreverse
175169 -}
176170
177− -- * Stream Splitting Operations
178− -- ** Spanning
179− -- | Spanning splits the input into two groups and applies two different
180− -- folds on each group.
171+ -- * Parsing
172+ -- ** Trimming
173+ , ltake
174+ -- , lrunFor -- time
175+ , ltakeWhile
176+ {-
177+ , ltakeWhileM
178+ , ldrop
179+ , ldropWhile
180+ , ldropWhileM
181+ -}
181182
182− -- Element unaware spanning
183+ -- ** Breaking
184+
185+ -- By chunks
183186 , splitAt
187+ -- , splitIn -- time
184188
185− -- Element aware spanning
189+ -- By elements
186190 , span
187− , break
191+ , break -- breakPre
192+ -- , breakPost
193+ -- , breakOn
188194 -- , spanBy
189195 -- , spanRollingBy
190196
191− -- ** Grouping
192− -- | Grouping splits the stream into groups and applies the supplied fold
193− -- on each group.
197+ -- By sequences
198+ -- breakOnSeq
199+
200+ -- ** Splitting
194201
195202 -- In imperative terms grouped folding can be considered as a nested loop
196203 -- where we loop over the stream to group elements and then loop over
@@ -205,23 +212,17 @@ module Streamly.Fold
205212 -- groups in memory and then map a fold on it to fold the groups. This kind
206213 -- of grouping and folding would not work well when the group size is big.
207214
208− -- Element unaware grouping
209− , groupsOf
210− , intervalsOf
215+ -- *** By Chunks
216+ , chunksOf
217+ , spellsOf
211218
212− -- Element aware grouping
213− , groups
214− , groupsBy
215− , groupsRollingBy
216− , grouped -- XXX experimental
217−
218− -- ** Splitting by an Element
219+ -- *** By Elements
219220 , splitBy
220221 , splitSuffixBy
221222 -- , splitPrefixBy
222223 , wordsBy
223224
224− -- ** Splitting on a Sequence
225+ -- *** By Sequences
225226 , splitOn
226227 , splitSuffixOn
227228 -- , splitPrefixOn
@@ -237,7 +238,12 @@ module Streamly.Fold
237238 -- , splitSuffixOnAny
238239 -- , splitPrefixOnAny
239240
240− -- ** Distributing
241+ -- ** Grouping
242+ , groups
243+ , groupsBy
244+ , groupsRollingBy
245+
246+ -- * Distributing
241247 -- |
242248 -- The 'Applicative' instance of a distributing 'Fold' distributes one copy
243249 -- of the stream to each fold and combines the results using a function.
@@ -271,7 +277,7 @@ module Streamly.Fold
271277 , tee
272278 , distribute
273279
274− -- ** Partitioning
280+ -- * Partitioning
275281 -- |
276282 -- Direct items in the input stream to different folds using a function to
277283 -- select the fold. This is useful to demultiplex the input stream.
@@ -280,21 +286,15 @@ module Streamly.Fold
280286 , demux_
281287 , classify
282288
283− -- ** Unzipping
289+ -- * Unzipping
284290 , unzip
285291 , unzipWith
286292 , unzipWithM
287293
288− -- ** Nested Folds
294+ -- * Nested Folds
289295 -- , concatMap
290− -- , groupsOf
296+ -- , chunksOf
291297 , duplicate -- experimental
292−
293− {-
294− -- * Splitter scans
295− -- | Scans that can be used to split and fold a stream using 'grouped'.
296− , _newline
297− -}
298298 )
299299where
300300
@@ -303,7 +303,7 @@ import Control.Monad (void)
303303import Control.Monad.IO.Class (MonadIO(..))
304304import Data.Functor.Identity (Identity)
305305import Data.Map.Strict (Map)
306−import Data.Maybe (fromJust, isJust)
306+import Data.Maybe (fromJust, isJust, isNothing)
307307
308308import Foreign.Storable (Storable(..))
309309import Prelude
@@ -970,6 +970,9 @@ ltakeWhile predicate (Fold step initial done) = Fold step' initial' done'
970970-- >>> splitAt_ 4 [1,2,3]
971971-- > ([1,2,3],[])
972972--
973+-- This can be considered as a two-fold version of 'ltake' where we take both
974+-- the segments instead of discarding the leftover.
975+--
973976-- @since 0.7.0
974977{-# INLINE splitAt #-}
975978splitAt
@@ -997,39 +1000,43 @@ splitAt n (Fold stepL initialL extractL) (Fold stepR initialR extractR) =
9971000-- | Group the input stream into groups of @n@ elements each and then fold each
9981001-- group using the provided fold function.
9991002--
1000−-- >> S.toList $ FL.groupsOf 2 FL.sum (S.enumerateFromTo 1 10)
1003+-- >> S.toList $ FL.chunksOf 2 FL.sum (S.enumerateFromTo 1 10)
10011004-- > [3,7,11,15,19]
10021005--
1006+-- This can be considered as an n-fold version of 'ltake' where we apply
1007+-- 'ltake' repeatedly on the leftover stream until the stream exhausts.
1008+--
10031009-- @since 0.7.0
1004−{-# INLINE groupsOf #-}
1005−groupsOf
1010+{-# INLINE chunksOf #-}
1011+chunksOf
10061012 :: (IsStream t, Monad m)
10071013 => Int -> Fold m a b -> t m a -> t m b
1008−groupsOf n f m = D.fromStreamD $ D.groupsOf n f (D.toStreamD m)
1014+chunksOf n f m = D.fromStreamD $ D.groupsOf n f (D.toStreamD m)
10091015
10101016-- | Transform a fold from a pure input to a 'Maybe' input, consuming only
10111017-- 'Just' values.
10121018lcatMaybes :: Monad m => Fold m a b -> Fold m (Maybe a) b
10131019lcatMaybes = lfilter isJust . lmap fromJust
10141020
1021+-- XXX we can implement this by repeatedly applying the 'lrunFor' fold.
10151022-- XXX add this example after fixing the serial stream rate control
1016−-- >>> S.toList $ S.take 5 $ intervalsOf 1 FL.sum $ constRate 2 $ S.enumerateFrom 1
1023+-- >>> S.toList $ S.take 5 $ spellsOf 1 FL.sum $ constRate 2 $ S.enumerateFrom 1
10171024-- > [3,7,11,15,19]
10181025--
10191026-- | Group the input stream into windows of @n@ second each and then fold each
10201027-- group using the provided fold function.
10211028--
10221029-- @since 0.7.0
1023−{-# INLINE intervalsOf #-}
1024−intervalsOf
1030+{-# INLINE spellsOf #-}
1031+spellsOf
10251032 :: (IsStream t, MonadAsync m)
10261033 => Double -> Fold m a b -> t m a -> t m b
1027−intervalsOf n f m = grouped (lcatMaybes f) s
1034+spellsOf n f m = splitSuffixBy' isNothing (lcatMaybes f) s
10281035 where
1029− s = S.map (\x -> (Just x, False)) m `parallel` S.repeatM timeout
1036+ s = S.map Just m `parallel` S.repeatM timeout
10301037 timeout = do
10311038 liftIO $ threadDelay (round $ n * 1000000)
1032− return (Nothing, True)
1039+ return Nothing
10331040
10341041------------------------------------------------------------------------------
10351042-- Element Aware APIs
@@ -1039,18 +1046,17 @@ intervalsOf n f m = grouped (lcatMaybes f) s
10391046-- Binary APIs
10401047------------------------------------------------------------------------------
10411048
1042−{-
10431049-- | Break the input stream into two groups, the first group takes the input as
10441050-- long as the predicate applied to the first element of the stream and next
10451051-- input element holds 'True', the second group takes the rest of the input.
10461052--
1047−spanBy
1053+_spanBy
10481054 :: Monad m
10491055 => (a -> a -> Bool)
10501056 -> Fold m a b
10511057 -> Fold m a c
10521058 -> Fold m a (b, c)
1053−spanBy cmp (Fold stepL initialL extractL) (Fold stepR initialR extractR) =
1059+_spanBy cmp (Fold stepL initialL extractL) (Fold stepR initialR extractR) =
10541060 Fold step init extract
10551061
10561062 where
@@ -1071,7 +1077,6 @@ spanBy cmp (Fold stepL initialL extractL) (Fold stepR initialR extractR) =
10711077 >>= (\a' -> return (Tuple3' a a' (Tuple' Nothing False)))
10721078
10731079 extract (Tuple3' a b _) = (,) <$> extractL a <*> extractR b
1074−-}
10751080
10761081-- | Span as long as the predicate is 'True'. @span p f1 f2@ composes folds
10771082-- @f1@ and @f2@ such that the composed fold continues sending the input to
@@ -1089,6 +1094,9 @@ spanBy cmp (Fold stepL initialL extractL) (Fold stepR initialR extractR) =
10891094-- >>> span_ (< 4) [1,2,3]
10901095-- > ([1,2,3],[])
10911096--
1097+-- This can be considered as a two-fold version of 'ltakeWhile' where we take
1098+-- both the segments instead of discarding the leftover.
1099+--
10921100-- @since 0.7.0
10931101{-# INLINE span #-}
10941102span
@@ -1117,6 +1125,8 @@ span p (Fold stepL initialL extractL) (Fold stepR initialR extractR) =
11171125-- folds @f1@ and @f2@ such that @f1@ stops receiving input as soon as the
11181126-- predicate @p@ becomes 'True'. The rest of the input is sent to @f2@.
11191127--
1128+-- This is the binary version of 'splitBy'.
1129+--
11201130-- > let break_ p xs = FL.foldl' (FL.break p FL.toList FL.toList) $ S.fromList xs
11211131--
11221132-- >>> break_ (< 1) [3,2,1]
@@ -1138,17 +1148,16 @@ break
11381148 -> Fold m a (b, c)
11391149break p = span (not . p)
11401150
1141−{-
11421151-- | Like 'spanBy' but applies the predicate in a rolling fashion i.e.
11431152-- predicate is applied to the previous and the next input elements.
1144−{-# INLINE spanRollingBy #-}
1145−spanRollingBy
1153+{-# INLINE _spanRollingBy #-}
1154+_spanRollingBy
11461155 :: Monad m
11471156 => (a -> a -> Bool)
11481157 -> Fold m a b
11491158 -> Fold m a c
11501159 -> Fold m a (b, c)
1151−spanRollingBy cmp (Fold stepL initialL extractL) (Fold stepR initialR extractR) =
1160+_spanRollingBy cmp (Fold stepL initialL extractL) (Fold stepR initialR extractR) =
11521161 Fold step init extract
11531162
11541163 where
@@ -1163,33 +1172,11 @@ spanRollingBy cmp (Fold stepL initialL extractL) (Fold stepR initialR extractR)
11631172 stepL a input >>= (\a' -> return (Tuple3' a' b (Just input)))
11641173
11651174 extract (Tuple3' a b _) = (,) <$> extractL a <*> extractR b
1166−-}
11671175
11681176------------------------------------------------------------------------------
11691177-- N-ary APIs
11701178------------------------------------------------------------------------------
11711179--
1172−-- XXX should we use a strict pair?
1173−--
1174−-- | The splitter returns True if the current element is the last element of
1175−-- the group, otherwise returns false.
1176−--
1177−-- @since 0.7.0
1178−{-# INLINE grouped #-}
1179−grouped
1180− :: (IsStream t, Monad m)
1181− => Fold m a b
1182− -> t m (a, Bool)
1183− -> t m b
1184−grouped f m = D.fromStreamD $ D.grouped f (D.toStreamD m)
1185−
1186−-- An example of a splitter to be used with grouped.
1187−_newline :: IsStream t => t m Char -> t m (Char,Bool)
1188−_newline m = S.foldrS (\x xs ->
1189− if x == '\n'
1190− then (x,True) `K.cons` xs
1191− else (x,False) `K.cons` xs) K.nil m
1192−
11931180-- | @groupsBy cmp f $ S.fromList [a,b,c,...]@ assigns the element @a@ to the
11941181-- first group, if @a \`cmp` b@ is 'True' then @b@ is also assigned to the same
11951182-- group. If @a \`cmp` c@ is 'True' then @c@ is also assigned to the same
@@ -1292,6 +1279,10 @@ breakOn pat f m = undefined
12921279-- >>> splitBy_ (== '.') "a..b"
12931280-- > ["a","","b"]
12941281--
1282+-- This can be considered as an n-fold version of 'break' where we apply
1283+-- 'break' successively on the input stream, dropping the first element
1284+-- of the second segment after each break.
1285+--
12951286-- @since 0.7.0
12961287{-# INLINE splitBy #-}
12971288splitBy
@@ -1334,6 +1325,10 @@ splitBy predicate f m =
13341325--
13351326-- > lines = splitSuffixBy (== '\n')
13361327--
1328+-- This can be considered as an n-fold version of 'breakPost' where we apply
1329+-- 'breakPost' successively on the input stream, dropping the first element
1330+-- of the second segment after each break.
1331+--
13371332-- @since 0.7.0
13381333{-# INLINE splitSuffixBy #-}
13391334splitSuffixBy
@@ -1402,15 +1397,19 @@ wordsBy predicate f m =
14021397-- >>> splitSuffixBy'_ (== '.') "a..b.."
14031398-- > ["a.",".","b.","."]
14041399--
1400+-- This can be considered as an n-fold version of 'breakPost' where we apply
1401+-- 'breakPost' successively on the input stream.
1402+--
14051403-- @since 0.7.0
1406−{-# INLINE _splitSuffixBy' #-}
1407−_splitSuffixBy'
1404+{-# INLINE splitSuffixBy' #-}
1405+splitSuffixBy'
14081406 :: (IsStream t, Monad m)
14091407 => (a -> Bool) -> Fold m a b -> t m a -> t m b
1410−_splitSuffixBy' predicate f m = grouped f (S.map (\a -> (a, predicate a)) m)
1408+splitSuffixBy' predicate f m =
1409+ D.fromStreamD $ D.splitSuffixBy' predicate f (D.toStreamD m)
14111410
14121411------------------------------------------------------------------------------
1413−-- Split on a delimiter
1412+-- Split on a delimiter sequence
14141413------------------------------------------------------------------------------
14151414
14161415-- Int list examples for splitOn:
@@ -1986,6 +1985,6 @@ lconcatMap s f1 f2 = undefined
19861985-- -----Fold m a b----|-Fold n a c-|-Fold n a c-|-...-|----Fold m a c
19871986--
19881987-- @
1989−lgroupsOf :: Int -> Fold m a b -> Fold m b c -> Fold m a c
1990−lgroupsOf n f1 f2 = undefined
1988+lchunksOf :: Int -> Fold m a b -> Fold m b c -> Fold m a c
1989+lchunksOf n f1 f2 = undefined
19911990-}