on master help sign in
Update span/break/groupsBy/groupsRollingBy docs
5798787Harendra Kumar
src/Streamly/Fold.hs+90−35
@@ -76,10 +76,13 @@ module Streamly.Fold
76 , foldMapM
76 , foldMapM
77
77
78 -- ** Full Folds (To Containers)
78 -- ** Full Folds (To Containers)
79+ -- | Avoid using these folds in scalable or performance critical
80+ -- applications, they buffer all the input in memory.
81+
79− -- , toStream -- experimental
82+ , toStream -- experimental
80 , toStreamRev -- experimental
83 , toStreamRev -- experimental
81
84
82− -- , toList
85+ , toList
83 , toListRev -- experimental
86 , toListRev -- experimental
84
87
85 -- ** Partial Folds
88 -- ** Partial Folds
@@ -646,9 +649,9 @@ foldMapM act = Fold step begin done
646-- @since 0.7.0
649-- @since 0.7.0
647
650
648-- id . (x1 :) . (x2 :) . (x3 :) . ... . (xn :) $ []
651-- id . (x1 :) . (x2 :) . (x3 :) . ... . (xn :) $ []
649−{-# INLINABLE _toList #-}
652+{-# INLINABLE toList #-}
650−_toList :: Monad m => Fold m a [a]
653+toList :: Monad m => Fold m a [a]
651−_toList = Fold (\f x -> return $ f . (x :))
654+toList = Fold (\f x -> return $ f . (x :))
652 (return id)
655 (return id)
653 (return . ($ []))
656 (return . ($ []))
654
657
@@ -673,9 +676,9 @@ toListRev = Fold (\xs x -> return $ x:xs) (return []) return
673-- be very inefficient, consider using "Streamly.Array" instead.
676-- be very inefficient, consider using "Streamly.Array" instead.
674--
677--
675-- @since 0.7.0
678-- @since 0.7.0
676−{-# INLINABLE _toStream #-}
679+{-# INLINABLE toStream #-}
677−_toStream :: Monad m => Fold m a (SerialT Identity a)
680+toStream :: Monad m => Fold m a (SerialT Identity a)
678−_toStream = Fold (\f x -> return $ f . (x `K.cons`))
681+toStream = Fold (\f x -> return $ f . (x `K.cons`))
679 (return id)
682 (return id)
680 (return . ($ K.nil))
683 (return . ($ K.nil))
681
684
@@ -943,13 +946,31 @@ ltakeWhile predicate (Fold step initial done) = Fold step' initial' done'
943------------------------------------------------------------------------------
946------------------------------------------------------------------------------
944--
947--
945
948
946−{-
949+-- | @splitAt n f1 f2@ composes folds @f1@ and @f2@ such that first @n@
947−-- | Split the input stream into two groups at index @n@, the first group
950+-- elements of its input are sent to fold @f1@ and the rest of the stream is
948−-- consisting of elements from index @0@ to index @n - 1@ i.e. the stream
951+-- sent to fold @f2@.
949−-- prefix of length @n@ and the second group consisting of the rest of the
950−-- stream.
951--
952--
952−-}
953+-- > let splitAt_ n xs = FL.foldl' (FL.splitAt n FL.toList FL.toList) $ S.fromList xs
954+--
955+-- >>> splitAt_ 6 "Hello World!"
956+-- > ("Hello ","World!")
957+--
958+-- >>> splitAt_ (-1) [1,2,3]
959+-- > ([],[1,2,3])
960+--
961+-- >>> splitAt_ 0 [1,2,3]
962+-- > ([],[1,2,3])
963+--
964+-- >>> splitAt_ 1 [1,2,3]
965+-- > ([1],[2,3])
966+--
967+-- >>> splitAt_ 3 [1,2,3]
968+-- > ([1,2,3],[])
969+--
970+-- >>> splitAt_ 4 [1,2,3]
971+-- > ([1,2,3],[])
972+--
973+-- @since 0.7.0
953{-# INLINE splitAt #-}
974{-# INLINE splitAt #-}
954splitAt
975splitAt
955 :: Monad m
976 :: Monad m
@@ -1018,11 +1039,11 @@ intervalsOf n f m = grouped (lcatMaybes f) s
1018-- Binary APIs
1039-- Binary APIs
1019------------------------------------------------------------------------------
1040------------------------------------------------------------------------------
1020
1041
1042+{-
1021-- | Break the input stream into two groups, the first group takes the input as
1043-- | Break the input stream into two groups, the first group takes the input as
1022-- long as the predicate applied to the first element of the stream and next
1044-- long as the predicate applied to the first element of the stream and next
1023-- input element holds 'True', the second group takes the rest of the input.
1045-- input element holds 'True', the second group takes the rest of the input.
1024--
1046--
1025−{-
1026spanBy
1047spanBy
1027 :: Monad m
1048 :: Monad m
1028 => (a -> a -> Bool)
1049 => (a -> a -> Bool)
@@ -1052,11 +1073,23 @@ spanBy cmp (Fold stepL initialL extractL) (Fold stepR initialR extractR) =
1052 extract (Tuple3' a b _) = (,) <$> extractL a <*> extractR b
1073 extract (Tuple3' a b _) = (,) <$> extractL a <*> extractR b
1053-}
1074-}
1054
1075
1055−-- |
1076+-- | Span as long as the predicate is 'True'. @span p f1 f2@ composes folds
1077+-- @f1@ and @f2@ such that the composed fold continues sending the input to
1078+-- @f1@ as long as the predicate @p@ is 'True'. The rest of the input is sent
1079+-- to @f2@.
1056--
1080--
1057−-- Break the input stream into two groups, the first group takes the input as
1081+-- > let span_ p xs = FL.foldl' (FL.span p FL.toList FL.toList) $ S.fromList xs
1058−-- long as the predicate is 'True', the second group takes the rest of the
1082+--
1059−-- input.
1083+-- >>> span_ (< 1) [1,2,3]
1084+-- > ([],[1,2,3])
1085+--
1086+-- >>> span_ (< 2) [1,2,3]
1087+-- > ([1],[2,3])
1088+--
1089+-- >>> span_ (< 4) [1,2,3]
1090+-- > ([1,2,3],[])
1091+--
1092+-- @since 0.7.0
1060{-# INLINE span #-}
1093{-# INLINE span #-}
1061span
1094span
1062 :: Monad m
1095 :: Monad m
@@ -1080,9 +1113,22 @@ span p (Fold stepL initialL extractL) (Fold stepR initialR extractR) =
1080-- |
1113-- |
1081-- > break p = span (not . p)
1114-- > break p = span (not . p)
1082--
1115--
1083−-- Break the input stream into two groups, the first group takes the input as
1116+-- Break as soon as the predicate becomes 'True'. @break p f1 f2@ composes
1084−-- long as the predicate is 'False', the second group takes the rest of the
1117+-- folds @f1@ and @f2@ such that @f1@ stops receiving input as soon as the
1085−-- input.
1118+-- predicate @p@ becomes 'True'. The rest of the input is sent to @f2@.
1119+--
1120+-- > let break_ p xs = FL.foldl' (FL.break p FL.toList FL.toList) $ S.fromList xs
1121+--
1122+-- >>> break_ (< 1) [3,2,1]
1123+-- > ([3,2,1],[])
1124+--
1125+-- >>> break_ (< 2) [3,2,1]
1126+-- > ([3,2],[1])
1127+--
1128+-- >>> break_ (< 4) [3,2,1]
1129+-- > ([],[3,2,1])
1130+--
1131+-- @since 0.7.0
1086{-# INLINE break #-}
1132{-# INLINE break #-}
1087break
1133break
1088 :: Monad m
1134 :: Monad m
@@ -1144,13 +1190,14 @@ _newline m = S.foldrS (\x xs ->
1144 then (x,True) `K.cons` xs
1190 then (x,True) `K.cons` xs
1145 else (x,False) `K.cons` xs) K.nil m
1191 else (x,False) `K.cons` xs) K.nil m
1146
1192
1147−-- | Group by applying a predicate to the first element of the current group
1193+-- | @groupsBy cmp f $ S.fromList [a,b,c,...]@ assigns the element @a@ to the
1148−-- and the next element in the input stream. The next element is considered
1194+-- first group, if @a \`cmp` b@ is 'True' then @b@ is also assigned to the same
1149−-- part of the current group if the predicate succeeds otherwise a new group
1195+-- group. If @a \`cmp` c@ is 'True' then @c@ is also assigned to the same
1150−-- starts.
1196+-- group and so on. When the comparison fails a new group is started. Each
1197+-- group is folded using the fold @f@.
1151--
1198--
1152−-- >>> S.toList $ FL.groupsBy (==) FL.toList $ S.fromList [1,1,2,2]
1199+-- >>> S.toList $ FL.groupsBy (>) FL.toList $ S.fromList [1,3,7,0,2,5]
1153−-- > [[1,1],[2,2]]
1200+-- > [[1,3,7],[0,2,5]]
1154--
1201--
1155-- @since 0.7.0
1202-- @since 0.7.0
1156groupsBy
1203groupsBy
@@ -1161,13 +1208,18 @@ groupsBy
1161 -> t m b
1208 -> t m b
1162groupsBy cmp f m = D.fromStreamD $ D.groupsBy cmp f (D.toStreamD m)
1209groupsBy cmp f m = D.fromStreamD $ D.groupsBy cmp f (D.toStreamD m)
1163
1210
1164−{-
1211+-- | Unlike @groupsBy@ this function performs a rolling comparison of two
1165−-- | Apply a predicate to each new element in the input stream and the last
1166−-- element of the current group. In other words, perform a rolling comparison
1167−-- between two successive elements in the stream. The new element is considered
1212+-- successive elements in the input stream. @groupsRollingBy cmp f $ S.fromList
1168−-- part of the current group if the predicate succeeds otherwise a new group
1213+-- [a,b,c,...]@ assigns the element @a@ to the first group, if @a \`cmp` b@ is
1169−-- starts.
1214+-- 'True' then @b@ is also assigned to the same group. If @b \`cmp` c@ is
1170−-}
1215+-- 'True' then @c@ is also assigned to the same group and so on. When the
1216+-- comparison fails a new group is started. Each group is folded using the fold
1217+-- @f@.
1218+--
1219+-- >>> S.toList $ FL.groupsRollingBy (\a b -> a + 1 == b) FL.toList $ S.fromList [1,2,3,7,8,9]
1220+-- > [[1,2,3],[7,8,9]]
1221+--
1222+-- @since 0.7.0
1171groupsRollingBy
1223groupsRollingBy
1172 :: (IsStream t, Monad m)
1224 :: (IsStream t, Monad m)
1173 => (a -> a -> Bool)
1225 => (a -> a -> Bool)
@@ -1178,6 +1230,9 @@ groupsRollingBy cmp f m = D.fromStreamD $ D.groupsRollingBy cmp f (D.toStreamD
1178
1230
1179-- |
1231-- |
1180-- > groups = groupsBy (==)
1232-- > groups = groupsBy (==)
1233+-- > groups = groupsRollingBy (==)
1234+--
1235+-- Groups a contiguous span of equal elements together in one group.
1181--
1236--
1182-- >>> S.toList $ FL.groups FL.toList $ S.fromList [1,1,2,2]
1237-- >>> S.toList $ FL.groups FL.toList $ S.fromList [1,1,2,2]
1183-- > [[1,1],[2,2]]
1238-- > [[1,1],[2,2]]