@@ -269,6 +269,8 @@ module Streamly.Internal.Data.Fold
270 , duplicate
270 , duplicate
273 -- * Deprecated
275 -- * Deprecated
274 , sequence
276 , sequence
@@ -286,6 +288,7 @@ import Data.Int (Int64)
286import Data.IORef (newIORef, readIORef, writeIORef)
288import Data.IORef (newIORef, readIORef, writeIORef)
287import Data.Map.Strict (Map)
289import Data.Map.Strict (Map)
288import Data.Maybe (isJust, fromJust)
290import Data.Maybe (isJust, fromJust)
291+import Foreign.Storable (Storable)
289import Streamly.Internal.Data.IsMap (IsMap(..))
292import Streamly.Internal.Data.IsMap (IsMap(..))
290import Streamly.Internal.Data.Pipe.Type (Pipe (..), PipeState(..))
293import Streamly.Internal.Data.Pipe.Type (Pipe (..), PipeState(..))
291import Streamly.Internal.Data.Unfold.Type (Unfold(..))
294import Streamly.Internal.Data.Unfold.Type (Unfold(..))
@@ -296,6 +299,7 @@ import qualified Data.IntSet as IntSet
296import qualified Data.Set as Set
299import qualified Data.Set as Set
297import qualified Streamly.Internal.Data.IsMap as IsMap
300import qualified Streamly.Internal.Data.IsMap as IsMap
298import qualified Prelude
301import qualified Prelude
302+import qualified Streamly.Internal.Data.Array.Foreign.Mut.Type as MA
299import qualified Streamly.Internal.Data.Pipe.Type as Pipe
303import qualified Streamly.Internal.Data.Pipe.Type as Pipe
300import qualified Streamly.Internal.Data.Stream.StreamD.Type as StreamD
304import qualified Streamly.Internal.Data.Stream.StreamD.Type as StreamD
@@ -320,6 +324,7 @@ import Streamly.Internal.Data.Fold.Type
320-- >>> import qualified Streamly.Internal.Data.Parser as Parser
324-- >>> import qualified Streamly.Internal.Data.Parser as Parser
321-- >>> import Streamly.Internal.Data.Stream.Serial (SerialT(..))
325-- >>> import Streamly.Internal.Data.Stream.Serial (SerialT(..))
322-- >>> import Data.IORef (newIORef, readIORef, writeIORef)
326-- >>> import Data.IORef (newIORef, readIORef, writeIORef)
327+-- >>> import qualified Streamly.Internal.Data.Array.Foreign.Mut.Type as MA
324------------------------------------------------------------------------------
329------------------------------------------------------------------------------
@@ -2121,3 +2126,57 @@ unfoldMany (Unfold ustep inject) (Fold fstep initial extract) =
2122 {-# INLINE_LATE consume #-}
2127 {-# INLINE_LATE consume #-}
2123 consume s a = inject a >>= produce s
2128 consume s a = inject a >>= produce s
2130+{-# INLINE topBy #-}
2131+topBy :: (MonadIO m, Storable a) =>
2132+ (a -> a -> Ordering)
2134+ -> Fold m a (MA.Array a)
2135+topBy cmp n = Fold step initial extract
2140+ arr <- MA.newArray n
2142+ then return $ Done arr
2143+ else return $ Partial (arr, 0)
2148+ arr' <- MA.snoc arr x
2150+ return $ Partial (arr', i + 1)
2152+ x1 <- MA.getIndexUnsafe (i - 1) arr
2155+ MA.putIndexUnsafe (i - 1) x arr
2157+ return $ Partial (arr, i)
2158+ _ -> return $ Partial (arr, i)
2160+ extract = return . fst
2162+-- | Fold the input stream to top n elements.
2164+-- >>> stream = Stream.fromList [2::Int,7,9,3,1,5,6,11,17]
2165+-- >>> Stream.fold (Fold.top 3) stream >>= MA.toList
2170+top :: (MonadIO m, Storable a, Ord a) => Int -> Fold m a (MA.Array a)
2171+top = topBy $ flip compare
2173+-- | Fold the input stream to bottom n elements.
2175+-- >>> stream = Stream.fromList [2::Int,7,9,3,1,5,6,11,17]
2176+-- >>> Stream.fold (Fold.bottom 3) stream >>= MA.toList
2180+{-# INLINE bottom #-}
2181+bottom :: (MonadIO m, Storable a, Ord a) => Int -> Fold m a (MA.Array a)
2182+bottom = topBy compare