@@ -1,4 +1,5 @@
1{-# LANGUAGE UndecidableInstances #-}
1{-# LANGUAGE UndecidableInstances #-}
2+{-# OPTIONS_GHC -Wno-orphans #-}
4-- Module : Streamly.Internal.Data.Stream.Serial
5-- Module : Streamly.Internal.Data.Stream.Serial
@@ -35,13 +36,16 @@ module Streamly.Internal.Data.Stream.Serial
36 , unfoldrM
37 , unfoldrM
37 , fromList
38 , fromList
39 -- * Elimination
41 -- * Elimination
42 -- * Transformation
45 -- * Transformation
45 , foldFilter
49 , foldFilter
@@ -77,7 +81,7 @@ import qualified Streamly.Internal.Data.Stream.StreamD.Transform as D
77import qualified Streamly.Internal.Data.Stream.StreamD.Type as D
81import qualified Streamly.Internal.Data.Stream.StreamD.Type as D
78import qualified Streamly.Internal.Data.Stream.StreamK.Type as K
82import qualified Streamly.Internal.Data.Stream.StreamK.Type as K
80−import Prelude hiding (map, mapM, repeat)
84+import Prelude hiding (map, mapM, repeat, filter)
82#include "Instances.hs"
86#include "Instances.hs"
83#include "inline.hs"
87#include "inline.hs"
@@ -256,6 +260,14 @@ toStreamD (SerialT m) = D.fromStreamK m
256fromStreamD :: Monad m => D.Stream m a -> SerialT m a
260fromStreamD :: Monad m => D.Stream m a -> SerialT m a
257fromStreamD m = SerialT $ D.toStreamK m
261fromStreamD m = SerialT $ D.toStreamK m
263+-- XXX We should only export generation and combinators from this module.
265+-- | Include only those elements that pass a predicate.
267+{-# INLINE filter #-}
268+filter :: Monad m => (a -> Bool) -> SerialT m a -> SerialT m a
269+filter p = fromStreamD . D.filter p . toStreamD
259-- | Use a filtering fold on a stream.
271-- | Use a filtering fold on a stream.
261-- > Stream.sum $ Stream.foldFilter (Fold.satisfy (> 5)) $ Stream.fromList [1..10]
273-- > Stream.sum $ Stream.foldFilter (Fold.satisfy (> 5)) $ Stream.fromList [1..10]
@@ -265,6 +277,52 @@ fromStreamD m = SerialT $ D.toStreamK m
265foldFilter :: Monad m => Fold m a (Maybe b) -> SerialT m a -> SerialT m b
277foldFilter :: Monad m => Fold m a (Maybe b) -> SerialT m a -> SerialT m b
266foldFilter p = fromStreamD . D.foldFilter p . toStreamD
278foldFilter p = fromStreamD . D.foldFilter p . toStreamD
280+-- XXX Renamed to foldWith because SerialT has a Foldable instance having
283+-- | Fold a stream using the supplied left 'Fold' and reducing the resulting
284+-- expression strictly at each step. The behavior is similar to 'foldl''. A
285+-- 'Fold' can terminate early without consuming the full stream. See the
286+-- documentation of individual 'Fold's for termination behavior.
288+-- >>> Stream.foldWith Fold.sum (Stream.enumerateFromTo 1 100)
291+-- Folds never fail, therefore, they produce a default value even when no input
292+-- is provided. It means we can always fold an empty stream and get a valid
293+-- result. For example:
295+-- >>> Stream.foldWith Fold.sum Stream.nil
298+-- However, 'foldMany' on an empty stream results in an empty stream.
299+-- Therefore, @Stream.foldWith f@ is not the same as @Stream.head . Stream.foldMany
302+-- @foldWith f = Stream.parse (Parser.fromFold f)@
305+{-# INLINE foldWith #-}
306+foldWith :: Monad m => Fold m a b -> SerialT m a -> m b
307+foldWith fld m = D.fold fld $ toStreamD m
309+-- XXX Renamed to "list" because fromList is present in IsList instance.
313+-- fromList = 'Prelude.foldr' 'K.cons' 'K.nil'
316+-- Construct a stream from a list of pure values. This is more efficient than
317+-- 'K.fromFoldable' for serial streams.
320+{-# INLINE_EARLY list #-}
321+list :: Monad m => [a] -> SerialT m a
322+list = fromStreamD . D.fromList
323+{-# RULES "list fallback to StreamK" [1]
324+ forall a. D.toStreamK (D.fromList a) = K.fromFoldable a #-}
268------------------------------------------------------------------------------
326------------------------------------------------------------------------------
269-- WSerialT
327-- WSerialT
270------------------------------------------------------------------------------
328------------------------------------------------------------------------------