@@ -1,10 +1,8 @@
1{-# LANGUAGE UndecidableInstances #-}
1{-# LANGUAGE UndecidableInstances #-}
2−{-# OPTIONS_GHC -Wno-orphans #-}
5-- Module : Streamly.Internal.Data.Stream.Type
4-- Module : Streamly.Internal.Data.Stream.Type
6-- Copyright : (c) 2017 Composewell Technologies
5-- Copyright : (c) 2017 Composewell Technologies
8-- License : BSD-3-Clause
6-- License : BSD-3-Clause
9-- Maintainer : streamly@composewell.com
7-- Maintainer : streamly@composewell.com
10-- Stability : experimental
8-- Stability : experimental
@@ -12,42 +10,40 @@
13module Streamly.Internal.Data.Stream.Type
11module Streamly.Internal.Data.Stream.Type
16 , fromStreamD
16 , fromStreamD
17 , toStreamD
17 , toStreamD
20− -- * Conversion operations
29import Control.Applicative (liftA2)
21import Control.Applicative (liftA2)
30−import Control.DeepSeq (NFData1(..))
22+import Control.DeepSeq (NFData(..), NFData1(..))
31import Control.Monad.Base (MonadBase(..), liftBaseDefault)
23import Control.Monad.Base (MonadBase(..), liftBaseDefault)
32import Control.Monad.Catch (MonadThrow, throwM)
24import Control.Monad.Catch (MonadThrow, throwM)
33import Control.Monad.IO.Class (MonadIO(..))
25import Control.Monad.IO.Class (MonadIO(..))
34import Control.Monad.Reader.Class (MonadReader(..))
26import Control.Monad.Reader.Class (MonadReader(..))
35import Control.Monad.State.Class (MonadState(..))
27import Control.Monad.State.Class (MonadState(..))
36import Control.Monad.Trans.Class (MonadTrans(lift))
28import Control.Monad.Trans.Class (MonadTrans(lift))
29+import Data.Foldable (Foldable(foldl'), fold)
37import Data.Functor.Identity (Identity(..), runIdentity)
30import Data.Functor.Identity (Identity(..), runIdentity)
31+import Data.Maybe (fromMaybe)
32+import Data.Semigroup (Endo(..))
38#if __GLASGOW_HASKELL__ < 808
33#if __GLASGOW_HASKELL__ < 808
39import Data.Semigroup (Semigroup(..))
34import Data.Semigroup (Semigroup(..))
36+import GHC.Exts (IsList(..), IsString(..), oneShot)
37+import Streamly.Internal.BaseCompat ((#.))
41−import Streamly.Internal.Data.Fold.Type (Fold)
38+import Streamly.Internal.Data.Maybe.Strict (Maybe'(..), toMaybe)
40+ ( Lexeme(Ident), lexP, parens, prec, readPrec, readListPrec
41+ , readListPrecDefault)
43import qualified Streamly.Internal.Data.Stream.Common as P
43import 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
46import qualified Streamly.Internal.Data.Stream.StreamD.Type as D
44import qualified Streamly.Internal.Data.Stream.StreamD.Type as D
47import qualified Streamly.Internal.Data.Stream.StreamK.Type as K
45import qualified Streamly.Internal.Data.Stream.StreamK.Type as K
49−import Prelude hiding (map, mapM, repeat, filter)
51#include "Instances.hs"
47#include "Instances.hs"
52#include "inline.hs"
48#include "inline.hs"
@@ -87,10 +83,30 @@ import Prelude hiding (map, mapM, repeat, filter)
87-- /Since: 0.2.0 ("Streamly")/
83-- /Since: 0.2.0 ("Streamly")/
89-- @since 0.8.0
85-- @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)
91 -- XXX when deriving do we inherit an INLINE?
87 -- XXX when deriving do we inherit an INLINE?
92 deriving (Semigroup, Monoid, MonadTrans)
88 deriving (Semigroup, Monoid, MonadTrans)
90+------------------------------------------------------------------------------
92+------------------------------------------------------------------------------
94+{-# INLINE fromStreamK #-}
95+fromStreamK :: K.Stream m a -> Stream m a
98+{-# INLINE toStreamK #-}
99+toStreamK :: Stream m a -> K.Stream m a
100+toStreamK (Stream k) = k
102+{-# INLINE toStreamD #-}
103+toStreamD :: Applicative m => Stream m a -> D.Stream m a
104+toStreamD = D.fromStreamK . toStreamK
106+{-# INLINE fromStreamD #-}
107+fromStreamD :: Monad m => D.Stream m a -> Stream m a
108+fromStreamD = fromStreamK . D.toStreamK
94------------------------------------------------------------------------------
110------------------------------------------------------------------------------
96------------------------------------------------------------------------------
112------------------------------------------------------------------------------
@@ -109,7 +125,7 @@ instance Monad m => Monad (Stream m) where
109 -- n binds, breakAfterSome, filterAllIn, state transformer (~2x)
125 -- n binds, breakAfterSome, filterAllIn, state transformer (~2x)
111 {-# INLINE (>>=) #-}
127 {-# 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)
114 {-# INLINE (>>) #-}
130 {-# INLINE (>>) #-}
115 (>>) = (*>)
131 (>>) = (*>)
@@ -155,92 +171,7 @@ instance Monad m => Applicative (Stream m) where
155 -- (<*) = K.apSerialDiscardSnd
171 -- (<*) = K.apSerialDiscardSnd
157MONAD_COMMON_INSTANCES(Stream,)
173MONAD_COMMON_INSTANCES(Stream,)
174+LIST_INSTANCES(Stream)
158NFDATA1_INSTANCE(Stream)
175NFDATA1_INSTANCE(Stream)
159−
176+FOLDABLE_INSTANCE(Stream)
160−-- XXX Renamed to foldWith because Stream has a Foldable instance having
177+TRAVERSABLE_INSTANCE(Stream)
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.
168−-- >>> Stream.foldWith Fold.sum (Stream.enumerateFromTo 1 100)
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:
175−-- >>> Stream.foldWith Fold.sum Stream.nil
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
182−-- @foldWith f = Stream.parse (Parser.fromFold f)@
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
189−-- XXX Renamed to "list" because fromList is present in IsList instance.
193−-- fromList = 'Prelude.foldr' 'K.cons' 'K.nil'
196−-- Construct a stream from a list of pure values. This is more efficient than
197−-- 'K.fromFoldable' for serial streams.
200−{-# INLINE_EARLY list #-}
201−list :: Monad m => [a] -> Stream m a
202−list = fromStreamD . D.fromList
204−------------------------------------------------------------------------------
206−------------------------------------------------------------------------------
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
216−-- then return Nothing
217−-- else print b >> return (Just (b, b + 1))
218−-- in drain $ unfoldrM f 0
229−{-# INLINE toStreamD #-}
230−toStreamD :: Applicative m => Stream m a -> D.Stream m a
231−toStreamD (Stream m) = D.fromStreamK m
233−{-# INLINE fromStreamD #-}
234−fromStreamD :: Monad m => D.Stream m a -> Stream m a
235−fromStreamD m = Stream $ D.toStreamK m
237−{-# INLINE_EARLY fromList #-}
238−fromList :: Monad m => [a] -> Stream m a
239−fromList = fromStreamD . D.fromList
241−-- | Convert a stream into a list in the underlying monad.
244−{-# INLINE toList #-}
245−toList :: Monad m => Stream m a -> m [a]
246−toList m = D.toList $ toStreamD m