@@ -1,6 +1,3 @@
1−{-# LANGUAGE UndecidableInstances #-}
2−{-# OPTIONS_GHC -Wno-orphans #-}
3−
41-- |
52-- Module : Streamly.Internal.Data.Stream.Serial
63-- Copyright : (c) 2017 Composewell Technologies
@@ -17,64 +14,36 @@
1714module Streamly.Internal.Data.Stream.Serial
1815 (
1916 -- * Serial appending stream
20− SerialT(..)
17+ SerialT
2118 , Serial
2219 , serial
2320
2421 -- * Construction
25− , cons
26− , consM
22+ , Stream.cons
23+ , Stream.consM
2724 , repeat
2825 , unfoldrM
2926 , fromList
30− , list
3127
3228 -- * Elimination
3329 , toList
34− , foldWith
35− , drain
3630
3731 -- * Transformation
3832 , map
39− , mapM
40− , filter
41− , foldFilter
33+ , Stream.mapM
4234 )
4335where
4436
45−import Control.Applicative (liftA2)
46−import Control.DeepSeq (NFData(..), NFData1(..))
47−import Control.Monad.Base (MonadBase(..), liftBaseDefault)
48−import Control.Monad.Catch (MonadThrow, throwM)
49−import Control.Monad.IO.Class (MonadIO(..))
50−import Control.Monad.Reader.Class (MonadReader(..))
51−import Control.Monad.State.Class (MonadState(..))
52−import Control.Monad.Trans.Class (MonadTrans(lift))
53−import Data.Foldable (Foldable(foldl'), fold)
54−import Data.Functor.Identity (Identity(..), runIdentity)
55−import Data.Maybe (fromMaybe)
56−import Data.Semigroup (Endo(..))
5737#if __GLASGOW_HASKELL__ < 808
5838import Data.Semigroup (Semigroup(..))
5939#endif
60−import GHC.Exts (IsList(..), IsString(..), oneShot)
61−import Text.Read
62− ( Lexeme(Ident), lexP, parens, prec, readPrec, readListPrec
63− , readListPrecDefault)
64−import Streamly.Internal.BaseCompat ((#.))
65−import Streamly.Internal.Data.Fold.Type (Fold)
66−import Streamly.Internal.Data.Maybe.Strict (Maybe'(..), toMaybe)
67−import Streamly.Internal.Data.Stream.StreamK.Type (Stream)
40+import GHC.Exts (IsList(..))
6841
69−import qualified Streamly.Internal.Data.Stream.Common as P
7042import qualified Streamly.Internal.Data.Stream.StreamD.Generate as D
71−import qualified Streamly.Internal.Data.Stream.StreamD.Transform as D
72−import qualified Streamly.Internal.Data.Stream.StreamD.Type as D
73−import qualified Streamly.Internal.Data.Stream.StreamK.Type as K
43+import qualified Streamly.Internal.Data.Stream as Stream
7444
75−import Prelude hiding (map, mapM, repeat, filter)
45+import Prelude hiding (map, mapM, repeat)
7646
77−#include "Instances.hs"
7847#include "inline.hs"
7948
8049-- $setup
@@ -84,38 +53,7 @@ import Prelude hiding (map, mapM, repeat, filter)
8453-- SerialT
8554------------------------------------------------------------------------------
8655
87−-- | For 'SerialT' streams:
88−--
89−-- @
90−-- (<>) = 'Streamly.Prelude.serial' -- 'Semigroup'
91−-- (>>=) = flip . 'Streamly.Prelude.concatMapWith' 'Streamly.Prelude.serial' -- 'Monad'
92−-- @
93−--
94−-- A single 'Monad' bind behaves like a @for@ loop:
95−--
96−-- >>> :{
97−-- Stream.toList $ do
98−-- x <- Stream.fromList [1,2] -- foreach x in stream
99−-- return x
100−-- :}
101−-- [1,2]
102−--
103−-- Nested monad binds behave like nested @for@ loops:
104−--
105−-- >>> :{
106−-- Stream.toList $ do
107−-- x <- Stream.fromList [1,2] -- foreach x in stream
108−-- y <- Stream.fromList [3,4] -- foreach y in stream
109−-- return (x, y)
110−-- :}
111−-- [(1,3),(1,4),(2,3),(2,4)]
112−--
113−-- /Since: 0.2.0 ("Streamly")/
114−--
115−-- @since 0.8.0
116−newtype SerialT m a = SerialT {getSerialT :: Stream m a}
117− -- XXX when deriving do we inherit an INLINE?
118− deriving (Semigroup, Monoid, MonadTrans)
56+type SerialT = Stream.Stream
11957
12058-- | A serial IO stream of elements of type @a@. See 'SerialT' documentation
12159-- for more details.
@@ -129,21 +67,12 @@ type Serial = SerialT IO
12967-- Generation
13068------------------------------------------------------------------------------
13169
132−{-# INLINE cons #-}
133−cons :: a -> SerialT m a -> SerialT m a
134−cons x (SerialT ms) = SerialT $ K.cons x ms
135−
136−{-# INLINE consM #-}
137−{-# SPECIALIZE consM :: IO a -> SerialT IO a -> SerialT IO a #-}
138−consM :: Monad m => m a -> SerialT m a -> SerialT m a
139−consM m (SerialT ms) = SerialT $ K.consM m ms
140−
14170-- |
14271-- Generate an infinite stream by repeating a pure value.
14372--
14473{-# INLINE_NORMAL repeat #-}
14574repeat :: Monad m => a -> SerialT m a
146−repeat = SerialT . D.toStreamK . D.repeat
75+repeat = Stream.fromStreamD . D.repeat
14776
14877------------------------------------------------------------------------------
14978-- Combining
@@ -153,37 +82,6 @@ repeat = SerialT . D.toStreamK . D.repeat
15382serial :: SerialT m a -> SerialT m a -> SerialT m a
15483serial = (<>)
15584
156−------------------------------------------------------------------------------
157−-- Monad
158−------------------------------------------------------------------------------
159−
160−instance Monad m => Monad (SerialT m) where
161− return = pure
162−
163− -- Benchmarks better with StreamD bind and pure:
164− -- toList, filterAllout, *>, *<, >> (~2x)
165− --
166− -- pure = SerialT . D.fromStreamD . D.fromPure
167− -- m >>= f = D.fromStreamD $ D.concatMap (D.toStreamD . f) (D.toStreamD m)
168−
169− -- Benchmarks better with CPS bind and pure:
170− -- Prime sieve (25x)
171− -- n binds, breakAfterSome, filterAllIn, state transformer (~2x)
172− --
173− {-# INLINE (>>=) #-}
174− (>>=) (SerialT m) f = SerialT $ K.bindWith K.serial m (getSerialT . f)
175−
176− {-# INLINE (>>) #-}
177− (>>) = (*>)
178−
179−------------------------------------------------------------------------------
180−-- Other instances
181−------------------------------------------------------------------------------
182−
183−{-# INLINE mapM #-}
184−mapM :: Monad m => (a -> m b) -> SerialT m a -> SerialT m b
185−mapM f (SerialT m) = SerialT $ D.toStreamK $ D.mapM f $ D.fromStreamK m
186−
18785-- |
18886-- @
18987-- map = fmap
@@ -199,120 +97,7 @@ mapM f (SerialT m) = SerialT $ D.toStreamK $ D.mapM f $ D.fromStreamK m
19997-- @since 0.4.0
20098{-# INLINE map #-}
20199map :: Monad m => (a -> b) -> SerialT m a -> SerialT m b
202−map f = mapM (return . f)
203−
204−{-# INLINE apSerial #-}
205−apSerial :: Monad m => SerialT m (a -> b) -> SerialT m a -> SerialT m b
206−apSerial (SerialT m1) (SerialT m2) =
207− SerialT $ D.toStreamK $ D.fromStreamK m1 <*> D.fromStreamK m2
208−
209−{-# INLINE apSequence #-}
210−apSequence :: Monad m => SerialT m a -> SerialT m b -> SerialT m b
211−apSequence (SerialT m1) (SerialT m2) =
212− SerialT $ D.toStreamK $ D.fromStreamK m1 *> D.fromStreamK m2
213−
214−{-# INLINE apDiscardSnd #-}
215−apDiscardSnd :: Monad m => SerialT m a -> SerialT m b -> SerialT m a
216−apDiscardSnd (SerialT m1) (SerialT m2) =
217− SerialT $ D.toStreamK $ D.fromStreamK m1 <* D.fromStreamK m2
218−
219−-- Note: we need to define all the typeclass operations because we want to
220−-- INLINE them.
221−instance Monad m => Applicative (SerialT m) where
222− {-# INLINE pure #-}
223− pure = SerialT . K.fromPure
224−
225− {-# INLINE (<*>) #-}
226− (<*>) = apSerial
227− -- (<*>) = K.apSerial
228−
229− {-# INLINE liftA2 #-}
230− liftA2 f x = (<*>) (fmap f x)
231−
232− {-# INLINE (*>) #-}
233− (*>) = apSequence
234− -- (*>) = K.apSerialDiscardFst
235−
236− {-# INLINE (<*) #-}
237− (<*) = apDiscardSnd
238− -- (<*) = K.apSerialDiscardSnd
239−
240−MONAD_COMMON_INSTANCES(SerialT,)
241−LIST_INSTANCES(SerialT)
242−NFDATA1_INSTANCE(SerialT)
243−FOLDABLE_INSTANCE(SerialT)
244−TRAVERSABLE_INSTANCE(SerialT)
245−
246−{-# INLINE toStreamD #-}
247−toStreamD :: Applicative m => SerialT m a -> D.Stream m a
248−toStreamD (SerialT m) = D.fromStreamK m
249−
250−{-# INLINE fromStreamD #-}
251−fromStreamD :: Monad m => D.Stream m a -> SerialT m a
252−fromStreamD m = SerialT $ D.toStreamK m
253−
254−-- XXX We should only export generation and combinators from this module.
255−--
256−-- | Include only those elements that pass a predicate.
257−--
258−{-# INLINE filter #-}
259−filter :: Monad m => (a -> Bool) -> SerialT m a -> SerialT m a
260−filter p = fromStreamD . D.filter p . toStreamD
261−
262−-- | Use a filtering fold on a stream.
263−--
264−-- > Stream.sum $ Stream.foldFilter (Fold.satisfy (> 5)) $ Stream.fromList [1..10]
265−-- 40
266−--
267−{-# INLINE foldFilter #-}
268−foldFilter :: Monad m => Fold m a (Maybe b) -> SerialT m a -> SerialT m b
269−foldFilter p = fromStreamD . D.foldFilter p . toStreamD
270−
271−-- XXX Renamed to foldWith because SerialT has a Foldable instance having
272−-- method fold.
273−--
274−-- | Fold a stream using the supplied left 'Fold' and reducing the resulting
275−-- expression strictly at each step. The behavior is similar to 'foldl''. A
276−-- 'Fold' can terminate early without consuming the full stream. See the
277−-- documentation of individual 'Fold's for termination behavior.
278−--
279−-- >>> Stream.foldWith Fold.sum (Stream.enumerateFromTo 1 100)
280−-- 5050
281−--
282−-- Folds never fail, therefore, they produce a default value even when no input
283−-- is provided. It means we can always fold an empty stream and get a valid
284−-- result. For example:
285−--
286−-- >>> Stream.foldWith Fold.sum Stream.nil
287−-- 0
288−--
289−-- However, 'foldMany' on an empty stream results in an empty stream.
290−-- Therefore, @Stream.foldWith f@ is not the same as @Stream.head . Stream.foldMany
291−-- f@.
292−--
293−-- @foldWith f = Stream.parse (Parser.fromFold f)@
294−--
295−-- /Pre-release/
296−{-# INLINE foldWith #-}
297−foldWith :: Monad m => Fold m a b -> SerialT m a -> m b
298−foldWith fld m = D.fold fld $ toStreamD m
299−
300−-- XXX Renamed to "list" because fromList is present in IsList instance.
301−--
302−-- |
303−-- @
304−-- fromList = 'Prelude.foldr' 'K.cons' 'K.nil'
305−-- @
306−--
307−-- Construct a stream from a list of pure values. This is more efficient than
308−-- 'K.fromFoldable' for serial streams.
309−--
310−-- @since 0.4.0
311−{-# INLINE_EARLY list #-}
312−list :: Monad m => [a] -> SerialT m a
313−list = fromStreamD . D.fromList
314−{-# RULES "list fallback to StreamK" [1]
315− forall a. D.toStreamK (D.fromList a) = K.fromFoldable a #-}
100+map f = Stream.mapM (return . f)
316101
317102------------------------------------------------------------------------------
318103-- Construction
@@ -341,10 +126,4 @@ list = fromStreamD . D.fromList
341126--
342127{-# INLINE unfoldrM #-}
343128unfoldrM :: Monad m => (b -> m (Maybe (a, b))) -> b -> SerialT m a
344−unfoldrM step seed = SerialT $ D.toStreamK (D.unfoldrM step seed)
345−
346−{-# INLINE_EARLY drain #-}
347−drain :: Monad m => SerialT m a -> m ()
348−drain (SerialT m) = D.drain $ D.fromStreamK m
349−{-# RULES "drain fallback to CPS" [1]
350− forall a. D.drain (D.fromStreamK a) = K.drain a #-}
129+unfoldrM step seed = Stream.fromStreamD (D.unfoldrM step seed)