on master help sign in
Add the classify fold, to classify input into bins
5da5f25Harendra Kumar
src/Streamly/Fold.hs+35−5
@@ -278,6 +278,7 @@ module Streamly.Fold
278 , partitionByM
278 , partitionByM
279 , partitionBy
279 , partitionBy
280 , demux_
280 , demux_
281+ , classify
281
282
282 -- ** Unzipping
283 -- ** Unzipping
283 , unzip
284 , unzip
@@ -307,7 +308,7 @@ import Data.Maybe (fromJust, isJust)
307import Foreign.Storable (Storable(..))
308import Foreign.Storable (Storable(..))
308import Prelude
309import Prelude
309 hiding (filter, drop, dropWhile, take, takeWhile, zipWith, foldr,
310 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,
311 notElem, maximum, minimum, head, last, tail, length, null,
312 notElem, maximum, minimum, head, last, tail, length, null,
312 reverse, iterate, init, and, or, lookup, foldr1, (!!),
313 reverse, iterate, init, and, or, lookup, foldr1, (!!),
313 scanl, scanl1, replicate, concatMap, mconcat, foldMap, unzip,
314 scanl, scanl1, replicate, concatMap, mconcat, foldMap, unzip,
@@ -1726,10 +1727,9 @@ partitionBy f = partitionByM (return . f)
1726-- demux f kv = Fold step begin done
1727-- demux f kv = Fold step begin done
1727-}
1728-}
1728
1729
1730+-- | Split the input stream based on a key field and fold each split using a
1729−-- | Demultiplex to multiple consumers without collecting the results. Useful
1731+-- specific fold without collecting the results. Useful for cases like protocol
1730−-- to run different effectful computations depending on the value of the stream
1732+-- handlers to handle different type of packets.
1731−-- elements, for example handling network packets of different types using
1732−-- different handlers.
1733--
1733--
1734-- @
1734-- @
1735--
1735--
@@ -1748,6 +1748,8 @@ partitionBy f = partitionByM (return . f)
1748-- One 1
1748-- One 1
1749-- Two 2
1749-- Two 2
1750-- @
1750-- @
1751+--
1752+-- @since 0.7.0
1751demux_ :: (Monad m, Ord k) => Map k (Fold m a ()) -> Fold m (k, a) ()
1753demux_ :: (Monad m, Ord k) => Map k (Fold m a ()) -> Fold m (k, a) ()
1752demux_ kv = Fold step initial extract
1754demux_ kv = Fold step initial extract
1753
1755
@@ -1764,6 +1766,34 @@ demux_ kv = Fold step initial extract
1764 initial' >>= \x -> step' x a >>= extract'
1766 initial' >>= \x -> step' x a >>= extract'
1765 extract = return
1767 extract = return
1766
1768
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+
1767------------------------------------------------------------------------------
1797------------------------------------------------------------------------------
1768-- Unzipping
1798-- Unzipping
1769------------------------------------------------------------------------------
1799------------------------------------------------------------------------------