on master help sign in
Add flag to switch stream backend to streamk
commitc7d2f9e0a3f8165708fcccb54aba3feb25823739 authorHarendra Kumar <harendra.kumar@gmail.com> dateTue 26 Jun 2018, 09:44 (8 years ago) parent689b9c5
5 files changed+73−22
.travis.yml+3 benchmark/LinearOps.hs+2−2 src/Streamly/Prelude.hs+44−20 src/Streamly/Streams/StreamK.hs+16 streamly.cabal+8
.travis.yml+3
@@ -117,6 +117,9 @@ matrix:
117117 - env: BUILD=cabal-new GHCVER=8.4.3 GHC_OPTIONS=""
118118 addons: {apt: {packages: [cabal-install-2.2,ghc-8.4.3], sources: [hvr-ghc]}}
119119
120+ - env: BUILD=cabal-new GHCVER=8.4.3 GHC_OPTIONS="" CABAL_NEWBUILD_OPTIONS="--flags=streamk"
121+ addons: {apt: {packages: [cabal-install-2.2,ghc-8.4.3], sources: [hvr-ghc]}}
122+
120123 - env: BUILD=cabal-new GHCVER=head GHC_OPTIONS=""
121124 addons: {apt: {packages: [cabal-install-head,ghc-head], sources: [hvr-ghc]}}
122125
benchmark/LinearOps.hs+2−2
@@ -112,9 +112,9 @@ sourceFromFoldableM :: (S.IsStream t, S.MonadAsync m) => Int -> t m Int
112112sourceFromFoldableM n = S.fromFoldableM (Prelude.fmap return [n..n+value])
113113
114114{-# INLINE sourceFoldMapWith #-}
115−sourceFoldMapWith :: (S.IsStream t, Monad (t m), S.Semigroup (t m Int))
115+sourceFoldMapWith :: (S.IsStream t, S.Semigroup (t m Int))
116116 => Int -> t m Int
117−sourceFoldMapWith n = S.foldMapWith (S.<>) return [n..n+value]
117+sourceFoldMapWith n = S.foldMapWith (S.<>) S.yield [n..n+value]
118118
119119{-# INLINE sourceFoldMapWithM #-}
120120sourceFoldMapWithM :: (S.IsStream t, Monad m, S.Semigroup (t m Int))
src/Streamly/Prelude.hs+44−20
@@ -71,8 +71,8 @@ module Streamly.Prelude
7171
7272 -- ** Conversions
7373 -- | Transform an input structure into a stream.
74− , K.yield
75− , K.yieldM
74+ , yield
75+ , yieldM
7676 , fromList
7777 , fromListM
7878 , K.fromFoldable
@@ -170,12 +170,28 @@ import Streamly.Streams.Zip (zipWith, zipWithM, zipAsyncWith, zipAsyncWithM)
170170
171171import qualified Streamly.Streams.StreamK as K
172172import qualified Streamly.Streams.StreamD as D
173+
174+#ifdef USE_STREAMK_ONLY
175+import qualified Streamly.Streams.StreamK as S
176+#else
177+import qualified Streamly.Streams.StreamD as S
178+#endif
179+
173180import qualified Streamly.Streams.Serial as Serial
174181
175182------------------------------------------------------------------------------
176183-- Conversion to and from direct style stream
177184------------------------------------------------------------------------------
178185
186+-- These definitions are dependent on what is imported as S
187+{-# INLINE fromStreamS #-}
188+fromStreamS :: (IsStream t, Monad m) => S.Stream m a -> t m a
189+fromStreamS = fromStream . S.toStreamK
190+
191+{-# INLINE toStreamS #-}
192+toStreamS :: (IsStream t, Monad m) => t m a -> S.Stream m a
193+toStreamS = S.fromStreamK . toStream
194+
179195{-# INLINE fromStreamD #-}
180196fromStreamD :: (IsStream t, Monad m) => D.Stream m a -> t m a
181197fromStreamD = fromStream . D.toStreamK
@@ -223,9 +239,9 @@ uncons m =
223239-- @since 0.1.0
224240{-# INLINE_EARLY unfoldr #-}
225241unfoldr :: (Monad m, IsStream t) => (b -> Maybe (a, b)) -> b -> t m a
226−unfoldr step seed = fromStreamD (D.unfoldr step seed)
242+unfoldr step seed = fromStreamS (S.unfoldr step seed)
227243{-# RULES "unfoldr fallback to StreamK" [1]
228− forall a b. D.toStreamK (D.unfoldr a b) = K.unfoldr a b #-}
244+ forall a b. S.toStreamK (S.unfoldr a b) = K.unfoldr a b #-}
229245
230246-- | Build a stream by unfolding a /monadic/ step function starting from a
231247-- seed. The step function returns the next element in the stream and the next
@@ -265,12 +281,20 @@ unfoldrM = K.unfoldrM
265281{-# RULES "unfoldrM serial" unfoldrM = unfoldrMSerial #-}
266282{-# INLINE_EARLY unfoldrMSerial #-}
267283unfoldrMSerial :: MonadAsync m => (b -> m (Maybe (a, b))) -> b -> SerialT m a
268−unfoldrMSerial step seed = fromStreamD (D.unfoldrM step seed)
284+unfoldrMSerial step seed = fromStreamS (S.unfoldrM step seed)
269285
270286------------------------------------------------------------------------------
271287-- Specialized Generation
272288------------------------------------------------------------------------------
273289
290+{-# INLINE yield #-}
291+yield :: IsStream t => a -> t m a
292+yield a = K.yield a
293+
294+{-# INLINE yieldM #-}
295+yieldM :: (Monad m, IsStream t) => m a -> t m a
296+yieldM m = K.yieldM m
297+
274298-- | Generate a stream by performing a monadic action @n@ times.
275299--
276300--
@@ -345,9 +369,9 @@ iterateM step = go
345369-- @since 0.4.0
346370{-# INLINE_EARLY fromList #-}
347371fromList :: (Monad m, IsStream t) => [a] -> t m a
348−fromList = fromStreamD . D.fromList
372+fromList = fromStreamS . S.fromList
349373{-# RULES "fromList fallback to StreamK" [1]
350− forall a. D.toStreamK (D.fromList a) = K.fromFoldable a #-}
374+ forall a. S.toStreamK (S.fromList a) = K.fromFoldable a #-}
351375
352376-- | Construct a stream from a list containing monadic actions. This can be
353377-- more efficient than 'fromFoldableM' especially for serial streams as it can
@@ -411,7 +435,7 @@ fromHandle h = fromStream go
411435-- @since 0.2.0
412436{-# INLINE foldrM #-}
413437foldrM :: Monad m => (a -> b -> m b) -> b -> SerialT m a -> m b
414−foldrM step acc m = D.foldrM step acc $ toStreamD m
438+foldrM step acc m = S.foldrM step acc $ toStreamS m
415439
416440-- | Lazy right associative fold. For example, to fold a stream into a list:
417441--
@@ -424,7 +448,7 @@ foldrM step acc m = D.foldrM step acc $ toStreamD m
424448{-# INLINE foldr #-}
425449foldr :: Monad m => (a -> b -> b) -> b -> SerialT m a -> m b
426450-- XXX somehow this definition does not perform well, need to investigate
427−-- foldr step acc m = D.foldr step acc $ D.fromStreamK (toStream m)
451+-- foldr step acc m = S.foldr step acc $ S.fromStreamK (toStream m)
428452foldr f = foldrM (\a b -> return (f a b))
429453
430454-- | Strict left fold with an extraction function. Like the standard strict
@@ -448,7 +472,7 @@ foldl = foldx
448472-- @since 0.2.0
449473{-# INLINE foldl' #-}
450474foldl' :: Monad m => (b -> a -> b) -> b -> SerialT m a -> m b
451−foldl' step begin m = D.foldl' step begin $ toStreamD m
475+foldl' step begin m = S.foldl' step begin $ toStreamS m
452476
453477-- XXX replace the recursive "go" with explicit continuations.
454478-- | Like 'foldx', but with a monadic step function.
@@ -467,7 +491,7 @@ foldlM = foldxM
467491--
468492-- @since 0.2.0
469493foldlM' :: Monad m => (b -> a -> m b) -> b -> SerialT m a -> m b
470−foldlM' step begin m = D.foldlM' step begin $ toStreamD m
494+foldlM' step begin m = S.foldlM' step begin $ toStreamS m
471495
472496------------------------------------------------------------------------------
473497-- Specialized folds
@@ -524,7 +548,7 @@ tail m =
524548-- @since 0.1.1
525549{-# INLINE last #-}
526550last :: Monad m => SerialT m a -> m (Maybe a)
527−last m = D.last $ toStreamD m
551+last m = S.last $ toStreamS m
528552
529553-- | Determine whether the stream is empty.
530554--
@@ -614,7 +638,7 @@ maximum m = go Nothing (toStream m)
614638-- @since 0.1.0
615639{-# INLINE mapM_ #-}
616640mapM_ :: Monad m => (a -> m b) -> SerialT m a -> m ()
617−mapM_ f m = D.mapM_ f $ toStreamD m
641+mapM_ f m = S.mapM_ f $ toStreamS m
618642
619643------------------------------------------------------------------------------
620644-- Conversions
@@ -625,7 +649,7 @@ mapM_ f m = D.mapM_ f $ toStreamD m
625649-- @since 0.1.0
626650{-# INLINE toList #-}
627651toList :: Monad m => SerialT m a -> m [a]
628−toList m = D.toList $ toStreamD m
652+toList m = S.toList $ toStreamS m
629653
630654-- | Write a stream of Strings to an IO Handle.
631655--
@@ -687,7 +711,7 @@ scanl' step = scanlM' (\a b -> return (step a b))
687711#if __GLASGOW_HASKELL__ != 802
688712-- GHC 8.2.2 crashes with this code, when used with "stack"
689713filter :: (IsStream t, Monad m) => (a -> Bool) -> t m a -> t m a
690−filter p m = fromStreamD $ D.filter p $ toStreamD m
714+filter p m = fromStreamS $ S.filter p $ toStreamS m
691715#else
692716filter :: IsStream t => (a -> Bool) -> t m a -> t m a
693717filter = K.filter
@@ -698,14 +722,14 @@ filter = K.filter
698722-- @since 0.1.0
699723{-# INLINE take #-}
700724take :: (IsStream t, Monad m) => Int -> t m a -> t m a
701−take n m = fromStreamD $ D.take n $ toStreamD m
725+take n m = fromStreamS $ S.take n $ toStreamS m
702726
703727-- | End the stream as soon as the predicate fails on an element.
704728--
705729-- @since 0.1.0
706730{-# INLINE takeWhile #-}
707731takeWhile :: (IsStream t, Monad m) => (a -> Bool) -> t m a -> t m a
708−takeWhile p m = fromStreamD $ D.takeWhile p $ toStreamD m
732+takeWhile p m = fromStreamS $ S.takeWhile p $ toStreamS m
709733
710734-- | Same as 'takeWhile' but with a monadic predicate.
711735--
@@ -719,7 +743,7 @@ takeWhileM p m = fromStreamD $ D.takeWhileM p $ toStreamD m
719743-- @since 0.1.0
720744{-# INLINE drop #-}
721745drop :: (IsStream t, Monad m) => Int -> t m a -> t m a
722−drop n m = fromStreamD $ D.drop n $ toStreamD m
746+drop n m = fromStreamS $ S.drop n $ toStreamS m
723747
724748-- | Drop elements in the stream as long as the predicate succeeds and then
725749-- take the rest of the stream.
@@ -727,7 +751,7 @@ drop n m = fromStreamD $ D.drop n $ toStreamD m
727751-- @since 0.1.0
728752{-# INLINE dropWhile #-}
729753dropWhile :: (IsStream t, Monad m) => (a -> Bool) -> t m a -> t m a
730−dropWhile p m = fromStreamD $ D.dropWhile p $ toStreamD m
754+dropWhile p m = fromStreamS $ S.dropWhile p $ toStreamS m
731755
732756-- | Same as 'dropWhile' but with a monadic predicate.
733757--
@@ -791,7 +815,7 @@ sequence = K.sequence
791815-- @since 0.3.0
792816{-# INLINE mapMaybe #-}
793817mapMaybe :: (IsStream t, Monad m) => (a -> Maybe b) -> t m a -> t m b
794−mapMaybe f m = fromStreamD $ D.mapMaybe f $ toStreamD m
818+mapMaybe f m = fromStreamS $ S.mapMaybe f $ toStreamS m
795819
796820-- | Like 'mapMaybe' but maps a monadic function.
797821--
src/Streamly/Streams/StreamK.hs+16
@@ -60,6 +60,8 @@ module Streamly.Streams.StreamK
6060 , yield
6161 , yieldM
6262 , fromFoldable
63+ , fromList
64+ , fromStreamK
6365
6466 -- * Elimination
6567 -- ** General Folds
@@ -82,6 +84,7 @@ module Streamly.Streams.StreamK
8284
8385 -- ** Conversions
8486 , toList
87+ , toStreamK
8588
8689 -- * Transformation
8790 -- ** By folding (scans)
@@ -360,6 +363,7 @@ unfoldrM step = go
360363-- Faster than yieldM because there is no bind. Usually we can construct a
361364-- stream from a pure value using "pure" in an applicative, however in case of
362365-- Zip streams pure creates an infinite stream.
366+--
363367-- | Create a singleton stream from a pure value. In monadic streams, 'pure' or
364368-- 'return' can be used in place of 'yield', however, in Zip applicative
365369-- streams 'pure' is equivalent to 'repeat'.
@@ -407,6 +411,14 @@ repeat a = let x = cons a x in x
407411fromFoldable :: (IsStream t, Foldable f) => f a -> t m a
408412fromFoldable = Prelude.foldr cons nil
409413
414+{-# INLINE fromList #-}
415+fromList :: IsStream t => [a] -> t m a
416+fromList = fromFoldable
417+
418+{-# INLINE fromStreamK #-}
419+fromStreamK :: Stream m a -> Stream m a
420+fromStreamK = id
421+
410422-------------------------------------------------------------------------------
411423-- Elimination by Folding
412424-------------------------------------------------------------------------------
@@ -554,6 +566,10 @@ mapM_ f m = go (toStream m)
554566toList :: (IsStream t, Monad m) => t m a -> m [a]
555567toList = foldr (:) []
556568
569+{-# INLINE toStreamK #-}
570+toStreamK :: Stream m a -> Stream m a
571+toStreamK = id
572+
557573-------------------------------------------------------------------------------
558574-- Transformation by folding (Scans)
559575-------------------------------------------------------------------------------
streamly.cabal+8
@@ -97,6 +97,11 @@ flag no-fusion
9797 manual: True
9898 default: False
9999
100+flag streamk
101+ description: Use CPS style streams when possible
102+ manual: True
103+ default: False
104+
100105flag examples
101106 description: Build including examples
102107 manual: True
@@ -146,6 +151,9 @@ library
146151 default-language: Haskell2010
147152 ghc-options: -Wall
148153
154+ if flag(streamk)
155+ cpp-options: -DUSE_STREAMK_ONLY
156+
149157 if flag(no-fusion)
150158 cpp-options: -DDISABLE_FUSION
151159