@@ -1,10 +1,8 @@
11{-# LANGUAGE UndecidableInstances #-}
2−{-# OPTIONS_GHC -Wno-orphans #-}
32
43-- |
54-- Module : Streamly.Internal.Data.Stream.Type
65-- Copyright : (c) 2017 Composewell Technologies
7−--
86-- License : BSD-3-Clause
97-- Maintainer : streamly@composewell.com
108-- Stability : experimental
@@ -12,42 +10,40 @@
1210--
1311module Streamly.Internal.Data.Stream.Type
1412 (
15− Stream(..)
13+ Stream
14+ , fromStreamK
15+ , toStreamK
1616 , fromStreamD
1717 , toStreamD
18− , foldWith
19−
20− -- * Conversion operations
21− , fromList
22− , toList
23−
24− -- * Transformation
25− , list
2618 )
2719where
2820
2921import Control.Applicative (liftA2)
30−import Control.DeepSeq (NFData1(..))
22+import Control.DeepSeq (NFData(..), NFData1(..))
3123import Control.Monad.Base (MonadBase(..), liftBaseDefault)
3224import Control.Monad.Catch (MonadThrow, throwM)
3325import Control.Monad.IO.Class (MonadIO(..))
3426import Control.Monad.Reader.Class (MonadReader(..))
3527import Control.Monad.State.Class (MonadState(..))
3628import Control.Monad.Trans.Class (MonadTrans(lift))
29+import Data.Foldable (Foldable(foldl'), fold)
3730import Data.Functor.Identity (Identity(..), runIdentity)
31+import Data.Maybe (fromMaybe)
32+import Data.Semigroup (Endo(..))
3833#if __GLASGOW_HASKELL__ < 808
3934import Data.Semigroup (Semigroup(..))
4035#endif
41−import Streamly.Internal.Data.Fold.Type (Fold)
36+import GHC.Exts (IsList(..), IsString(..), oneShot)
37+import Streamly.Internal.BaseCompat ((#.))
38+import Streamly.Internal.Data.Maybe.Strict (Maybe'(..), toMaybe)
39+import Text.Read
40+ ( Lexeme(Ident), lexP, parens, prec, readPrec, readListPrec
41+ , readListPrecDefault)
4242
4343import qualified Streamly.Internal.Data.Stream.Common as P
44−import qualified Streamly.Internal.Data.Stream.StreamD.Generate as D
45−import qualified Streamly.Internal.Data.Stream.StreamD.Transform as D
4644import qualified Streamly.Internal.Data.Stream.StreamD.Type as D
4745import qualified Streamly.Internal.Data.Stream.StreamK.Type as K
4846
49−import Prelude hiding (map, mapM, repeat, filter)
50−
5147#include "Instances.hs"
5248#include "inline.hs"
5349
@@ -87,10 +83,30 @@ import Prelude hiding (map, mapM, repeat, filter)
8783-- /Since: 0.2.0 ("Streamly")/
8884--
8985-- @since 0.8.0
90−newtype Stream m a = Stream {getStream :: K.Stream m a}
86+newtype Stream m a = Stream (K.Stream m a)
9187 -- XXX when deriving do we inherit an INLINE?
9288 deriving (Semigroup, Monoid, MonadTrans)
9389
90+------------------------------------------------------------------------------
91+-- Conversions
92+------------------------------------------------------------------------------
93+
94+{-# INLINE fromStreamK #-}
95+fromStreamK :: K.Stream m a -> Stream m a
96+fromStreamK = Stream
97+
98+{-# INLINE toStreamK #-}
99+toStreamK :: Stream m a -> K.Stream m a
100+toStreamK (Stream k) = k
101+
102+{-# INLINE toStreamD #-}
103+toStreamD :: Applicative m => Stream m a -> D.Stream m a
104+toStreamD = D.fromStreamK . toStreamK
105+
106+{-# INLINE fromStreamD #-}
107+fromStreamD :: Monad m => D.Stream m a -> Stream m a
108+fromStreamD = fromStreamK . D.toStreamK
109+
94110------------------------------------------------------------------------------
95111-- Monad
96112------------------------------------------------------------------------------
@@ -109,7 +125,7 @@ instance Monad m => Monad (Stream m) where
109125 -- n binds, breakAfterSome, filterAllIn, state transformer (~2x)
110126 --
111127 {-# INLINE (>>=) #-}
112− (>>=) (Stream m) f = Stream $ K.bindWith K.serial m (getStream . f)
128+ (>>=) (Stream m) f = Stream $ K.bindWith K.serial m (toStreamK . f)
113129
114130 {-# INLINE (>>) #-}
115131 (>>) = (*>)
@@ -155,92 +171,7 @@ instance Monad m => Applicative (Stream m) where
155171 -- (<*) = K.apSerialDiscardSnd
156172
157173MONAD_COMMON_INSTANCES(Stream,)
174+LIST_INSTANCES(Stream)
158175NFDATA1_INSTANCE(Stream)
159−
160−-- XXX Renamed to foldWith because Stream has a Foldable instance having
161−-- method fold.
162−--
163−-- | Fold a stream using the supplied left 'Fold' and reducing the resulting
164−-- expression strictly at each step. The behavior is similar to 'foldl''. A
165−-- 'Fold' can terminate early without consuming the full stream. See the
166−-- documentation of individual 'Fold's for termination behavior.
167−--
168−-- >>> Stream.foldWith Fold.sum (Stream.enumerateFromTo 1 100)
169−-- 5050
170−--
171−-- Folds never fail, therefore, they produce a default value even when no input
172−-- is provided. It means we can always fold an empty stream and get a valid
173−-- result. For example:
174−--
175−-- >>> Stream.foldWith Fold.sum Stream.nil
176−-- 0
177−--
178−-- However, 'foldMany' on an empty stream results in an empty stream.
179−-- Therefore, @Stream.foldWith f@ is not the same as @Stream.head . Stream.foldMany
180−-- f@.
181−--
182−-- @foldWith f = Stream.parse (Parser.fromFold f)@
183−--
184−-- /Pre-release/
185−{-# INLINE foldWith #-}
186−foldWith :: Monad m => Fold m a b -> Stream m a -> m b
187−foldWith fld m = D.fold fld $ toStreamD m
188−
189−-- XXX Renamed to "list" because fromList is present in IsList instance.
190−--
191−-- |
192−-- @
193−-- fromList = 'Prelude.foldr' 'K.cons' 'K.nil'
194−-- @
195−--
196−-- Construct a stream from a list of pure values. This is more efficient than
197−-- 'K.fromFoldable' for serial streams.
198−--
199−-- @since 0.4.0
200−{-# INLINE_EARLY list #-}
201−list :: Monad m => [a] -> Stream m a
202−list = fromStreamD . D.fromList
203−
204−------------------------------------------------------------------------------
205−-- Construction
206−------------------------------------------------------------------------------
207−
208−-- | Build a stream by unfolding a /monadic/ step function starting from a
209−-- seed. The step function returns the next element in the stream and the next
210−-- seed value. When it is done it returns 'Nothing' and the stream ends. For
211−-- example,
212−--
213−-- @
214−-- let f b =
215−-- if b > 3
216−-- then return Nothing
217−-- else print b >> return (Just (b, b + 1))
218−-- in drain $ unfoldrM f 0
219−-- @
220−-- @
221−-- 0
222−-- 1
223−-- 2
224−-- 3
225−-- @
226−--
227−-- /Pre-release/
228−--
229−{-# INLINE toStreamD #-}
230−toStreamD :: Applicative m => Stream m a -> D.Stream m a
231−toStreamD (Stream m) = D.fromStreamK m
232−
233−{-# INLINE fromStreamD #-}
234−fromStreamD :: Monad m => D.Stream m a -> Stream m a
235−fromStreamD m = Stream $ D.toStreamK m
236−
237−{-# INLINE_EARLY fromList #-}
238−fromList :: Monad m => [a] -> Stream m a
239−fromList = fromStreamD . D.fromList
240−
241−-- | Convert a stream into a list in the underlying monad.
242−--
243−-- @since 0.1.0
244−{-# INLINE toList #-}
245−toList :: Monad m => Stream m a -> m [a]
246−toList m = D.toList $ toStreamD m
176+FOLDABLE_INSTANCE(Stream)
177+TRAVERSABLE_INSTANCE(Stream)