on master help sign in
Fix the argument order of Stream.groupsBy
aa02380Adithya Kumar
benchmark/Streamly/Benchmark/Data/Stream/Reduce.hs+33−14
@@ -107,30 +107,50 @@ iterateSource g count len n = f count (sourceUnfoldrM len n)
107-- Grouping transformations
107-- Grouping transformations
108-------------------------------------------------------------------------------
108-------------------------------------------------------------------------------
109
109
110−#ifdef USE_PRELUDE
111{-# INLINE groups #-}
110{-# INLINE groups #-}
112groups :: MonadIO m => Stream m Int -> m ()
111groups :: MonadIO m => Stream m Int -> m ()
112+groups =
113+#ifdef USE_PRELUDE
113−groups = Common.drain . S.groups FL.drain
114+ Common.drain . S.groups FL.drain
115+#else
116+ Common.drain . S.groupsWhile (==) FL.drain
117+#endif
114
118
115−-- XXX Change this test when the order of comparison is later changed
119+{-# INLINE groupsWhileLT #-}
116−{-# INLINE groupsByGT #-}
117−groupsByGT :: MonadIO m => Stream m Int -> m ()
120+groupsWhileLT :: MonadIO m => Stream m Int -> m ()
121+groupsWhileLT =
122+#ifdef USE_PRELUDE
118−groupsByGT = Common.drain . S.groupsBy (>) FL.drain
123+ Common.drain . S.groupsBy (>) FL.drain
124+#else
125+ Common.drain . S.groupsWhile (<) FL.drain
126+#endif
127+
128+{-# INLINE groupsWhileEq #-}
129+groupsWhileEq :: MonadIO m => Stream m Int -> m ()
130+groupsWhileEq =
131+#ifdef USE_PRELUDE
132+ Common.drain . S.groupsBy (==) FL.drain
133+#else
134+ Common.drain . S.groupsWhile (==) FL.drain
135+#endif
119
136
120−{-# INLINE groupsByEq #-}
121−groupsByEq :: MonadIO m => Stream m Int -> m ()
122−groupsByEq = Common.drain . S.groupsBy (==) FL.drain
123
137
124−-- XXX Change this test when the order of comparison is later changed
125{-# INLINE groupsByRollingLT #-}
138{-# INLINE groupsByRollingLT #-}
126groupsByRollingLT :: MonadIO m => Stream m Int -> m ()
139groupsByRollingLT :: MonadIO m => Stream m Int -> m ()
127groupsByRollingLT =
140groupsByRollingLT =
141+#ifdef USE_PRELUDE
128 Common.drain . S.groupsByRolling (<) FL.drain
142 Common.drain . S.groupsByRolling (<) FL.drain
143+#else
144+ Common.drain . S.groupsRollingBy (<) FL.drain
145+#endif
129
146
130{-# INLINE groupsByRollingEq #-}
147{-# INLINE groupsByRollingEq #-}
131groupsByRollingEq :: MonadIO m => Stream m Int -> m ()
148groupsByRollingEq :: MonadIO m => Stream m Int -> m ()
132groupsByRollingEq =
149groupsByRollingEq =
150+#ifdef USE_PRELUDE
133 Common.drain . S.groupsByRolling (==) FL.drain
151 Common.drain . S.groupsByRolling (==) FL.drain
152+#else
153+ Common.drain . S.groupsRollingBy (==) FL.drain
134#endif
154#endif
135
155
136{-# INLINE foldMany #-}
156{-# INLINE foldMany #-}
@@ -190,14 +210,13 @@ o_1_space_grouping value =
190 -- Buffering operations using heap proportional to group/window sizes.
210 -- Buffering operations using heap proportional to group/window sizes.
191 [ bgroup "grouping"
211 [ bgroup "grouping"
192 [
212 [
193−#ifdef USE_PRELUDE
194 benchIOSink value "groups" groups
213 benchIOSink value "groups" groups
195− , benchIOSink value "groupsByGT" groupsByGT
214+ , benchIOSink value "groupsWhileLT" groupsWhileLT
196− , benchIOSink value "groupsByEq" groupsByEq
215+ , benchIOSink value "groupsWhileEq" groupsWhileEq
197 , benchIOSink value "groupsByRollingLT" groupsByRollingLT
216 , benchIOSink value "groupsByRollingLT" groupsByRollingLT
198 , benchIOSink value "groupsByRollingEq" groupsByRollingEq
217 , benchIOSink value "groupsByRollingEq" groupsByRollingEq
199 ,
218 ,
200−#endif
219+
201 -- XXX parseMany/parseIterate benchmarks are in the Parser/ParserD
220 -- XXX parseMany/parseIterate benchmarks are in the Parser/ParserD
202 -- modules we can bring those here. chunksOf benchmarks are in
221 -- modules we can bring those here. chunksOf benchmarks are in
203 -- Parser/ParserD/Array.Stream/FileSystem.Handle.
222 -- Parser/ParserD/Array.Stream/FileSystem.Handle.
core/src/Streamly/Internal/Data/Stream/StreamD/Nesting.hs+25−8
@@ -141,6 +141,7 @@ module Streamly.Internal.Data.Stream.StreamD.Nesting
141 -- | Group segments of a stream and fold. Special case of parsing.
141 -- | Group segments of a stream and fold. Special case of parsing.
142 , groupsOf
142 , groupsOf
143 , groupsBy
143 , groupsBy
144+ , groupsWhile
144 , groupsRollingBy
145 , groupsRollingBy
145
146
146 -- ** Splitting
147 -- ** Splitting
@@ -1896,16 +1897,23 @@ data GroupByState st fs a b
1896 | GroupingYield !b (GroupByState st fs a b)
1897 | GroupingYield !b (GroupByState st fs a b)
1897 | GroupingDone
1898 | GroupingDone
1898
1899
1900+-- | The argument order of the comparison function in `groupsWhile` is
1901+-- different than that of `groupsBy`.
1902+--
1903+-- In `groupsBy` the comparison function takes the next element as the first
1904+-- argument and the previous element as the second argument. In `groupsWhile`
1905+-- the first argument is the previous element and second argument is the next
1906+-- element.
1899−{-# INLINE_NORMAL groupsBy #-}
1907+{-# INLINE_NORMAL groupsWhile #-}
1900−groupsBy :: Monad m
1908+groupsWhile :: Monad m
1901 => (a -> a -> Bool)
1909 => (a -> a -> Bool)
1902 -> Fold m a b
1910 -> Fold m a b
1903 -> Stream m a
1911 -> Stream m a
1904 -> Stream m b
1912 -> Stream m b
1905{-
1913{-
1906−groupsBy eq fld = parseMany (PRD.groupBy eq fld)
1914+groupsWhile eq fld = parseMany (PRD.groupBy eq fld)
1907-}
1915-}
1908−groupsBy cmp (Fold fstep initial done) (Stream step state) =
1916+groupsWhile cmp (Fold fstep initial done) (Stream step state) =
1909 Stream stepOuter (GroupingInit state)
1917 Stream stepOuter (GroupingInit state)
1910
1918
1911 where
1919 where
@@ -1936,7 +1944,7 @@ groupsBy cmp (Fold fstep initial done) (Stream step state) =
1936 res <- step (adaptState gst) stt
1944 res <- step (adaptState gst) stt
1937 case res of
1945 case res of
1938 Yield x s -> do
1946 Yield x s -> do
1939− if cmp x prev
1947+ if cmp prev x
1940 then do
1948 then do
1941 r <- fstep acc x
1949 r <- fstep acc x
1942 case r of
1950 case r of
@@ -1966,7 +1974,7 @@ groupsBy cmp (Fold fstep initial done) (Stream step state) =
1966 res <- step (adaptState gst) stt
1974 res <- step (adaptState gst) stt
1967 case res of
1975 case res of
1968 Yield x s -> do
1976 Yield x s -> do
1969− if cmp x prev
1977+ if cmp prev x
1970 then do
1978 then do
1971 r <- fstep acc x
1979 r <- fstep acc x
1972 case r of
1980 case r of
@@ -1977,9 +1985,18 @@ groupsBy cmp (Fold fstep initial done) (Stream step state) =
1977 return $ Yield r (GroupingInitWith s x)
1985 return $ Yield r (GroupingInitWith s x)
1978 Skip s -> go SPEC s acc
1986 Skip s -> go SPEC s acc
1979 Stop -> done acc >>= \r -> return $ Yield r GroupingDone
1987 Stop -> done acc >>= \r -> return $ Yield r GroupingDone
1980− stepOuter _ (GroupingYield _ _) = error "groupsBy: Unreachable"
1988+ stepOuter _ (GroupingYield _ _) = error "groupsWhile: Unreachable"
1981 stepOuter _ GroupingDone = return Stop
1989 stepOuter _ GroupingDone = return Stop
1982
1990
1991+{-# DEPRECATED groupsBy "Please use groupsWhile instead. Please note the change in the argument order of the comparison function." #-}
1992+{-# INLINE_NORMAL groupsBy #-}
1993+groupsBy :: Monad m
1994+ => (a -> a -> Bool)
1995+ -> Fold m a b
1996+ -> Stream m a
1997+ -> Stream m b
1998+groupsBy cmp = groupsWhile (flip cmp)
1999+
1983{-# INLINE_NORMAL groupsRollingBy #-}
2000{-# INLINE_NORMAL groupsRollingBy #-}
1984groupsRollingBy :: Monad m
2001groupsRollingBy :: Monad m
1985 => (a -> a -> Bool)
2002 => (a -> a -> Bool)
@@ -2045,7 +2062,7 @@ groupsRollingBy cmp (Fold fstep initial done) (Stream step state) =
2045
2062
2046 where
2063 where
2047
2064
2048− -- XXX GHC: groupsBy has one less parameter in this go loop and it
2065+ -- XXX GHC: groupsWhile has one less parameter in this go loop and it
2049 -- fuses. However, groupsRollingBy does not fuse, removing the prev
2066 -- fuses. However, groupsRollingBy does not fuse, removing the prev
2050 -- parameter makes it fuse. Something needs to be fixed in GHC. The
2067 -- parameter makes it fuse. Something needs to be fixed in GHC. The
2051 -- workaround for this is noted in the comments below.
2068 -- workaround for this is noted in the comments below.