on master help sign in
Add the classify fold, to classify input into bins
commit5da5f25f3302670755e8a14fb04612796f8fa159 authorHarendra Kumar <harendra.kumar@gmail.com> dateTue 14 May 2019, 19:08 (7 years ago) parent6084321
1 file changed+35−5
src/Streamly/Fold.hs+35−5
src/Streamly/Fold.hs+35−5
@@ -278,6 +278,7 @@ module Streamly.Fold
278278 , partitionByM
279279 , partitionBy
280280 , demux_
281+ , classify
281282
282283 -- ** Unzipping
283284 , unzip
@@ -307,7 +308,7 @@ import Data.Maybe (fromJust, isJust)
307308import Foreign.Storable (Storable(..))
308309import Prelude
309310 hiding (filter, drop, dropWhile, take, takeWhile, zipWith, foldr,
310− foldl, map, mapM, mapM_, sequence, all, any, sum, product, elem,
311+ foldl, map, mapM_, sequence, all, any, sum, product, elem,
311312 notElem, maximum, minimum, head, last, tail, length, null,
312313 reverse, iterate, init, and, or, lookup, foldr1, (!!),
313314 scanl, scanl1, replicate, concatMap, mconcat, foldMap, unzip,
@@ -1726,10 +1727,9 @@ partitionBy f = partitionByM (return . f)
17261727-- demux f kv = Fold step begin done
17271728-}
17281729
1729−-- | Demultiplex to multiple consumers without collecting the results. Useful
1730−-- to run different effectful computations depending on the value of the stream
1731−-- elements, for example handling network packets of different types using
1732−-- different handlers.
1730+-- | Split the input stream based on a key field and fold each split using a
1731+-- specific fold without collecting the results. Useful for cases like protocol
1732+-- handlers to handle different type of packets.
17331733--
17341734-- @
17351735--
@@ -1748,6 +1748,8 @@ partitionBy f = partitionByM (return . f)
17481748-- One 1
17491749-- Two 2
17501750-- @
1751+--
1752+-- @since 0.7.0
17511753demux_ :: (Monad m, Ord k) => Map k (Fold m a ()) -> Fold m (k, a) ()
17521754demux_ kv = Fold step initial extract
17531755
@@ -1764,6 +1766,34 @@ demux_ kv = Fold step initial extract
17641766 initial' >>= \x -> step' x a >>= extract'
17651767 extract = return
17661768
1769+-- | Split the input stream based on a key field and fold each split using the
1770+-- given fold. Useful for map/reduce, bucketizing the input in different bins
1771+-- or for generating histograms.
1772+--
1773+-- @
1774+-- > let input = S.fromList [(\"ONE",1),(\"ONE",1.1),(\"TWO",2), (\"TWO",2.2)]
1775+-- in FL.foldl' (FL.classify FL.toListRev) input
1776+-- fromList [(\"ONE",[1.1,1.0]),(\"TWO",[2.2,2.0])]
1777+-- @
1778+--
1779+-- @since 0.7.0
1780+classify :: (Monad m, Ord k) => Fold m a b -> Fold m (k, a) (Map k b)
1781+classify (Fold step initial extract) = Fold step' initial' extract'
1782+
1783+ where
1784+
1785+ initial' = return Map.empty
1786+ step' kv (k, a) =
1787+ case Map.lookup k kv of
1788+ Nothing -> do
1789+ x <- initial
1790+ r <- step x a
1791+ return $ Map.insert k r kv
1792+ Just x -> do
1793+ r <- step x a
1794+ return $ Map.insert k r kv
1795+ extract' = mapM extract
1796+
17671797------------------------------------------------------------------------------
17681798-- Unzipping
17691799------------------------------------------------------------------------------