on master help sign in
rename unstream et. al. and make them polymorphic

rename: unStream to foldStream unStreamShared to foldStreamShared unStreamSVar to foldStreamSVar Change the order of arguments to match the standard fold convention. Make them polymorphic so as to make them more convenient to use without having to always use fromStream/toStream. TBD: check performance impact

commit2ba5f01d8c3cd22508cb72247cbf525a9573fc7a authorHarendra Kumar <harendra.kumar@gmail.com> dateTue 11 Dec 2018, 20:01 (8 years ago) parent183325e
12 files changed+453−464
src/Streamly/Prelude.hs+12−12 src/Streamly/SVar.hs+1−1 src/Streamly/Streams/Ahead.hs+35−36 src/Streamly/Streams/Async.hs+32−43 src/Streamly/Streams/Combinators.hs+12−12 src/Streamly/Streams/Parallel.hs+19−26 src/Streamly/Streams/SVar.hs+7−6 src/Streamly/Streams/Serial.hs+30−42 src/Streamly/Streams/StreamD.hs+2−2 src/Streamly/Streams/StreamK.hs+161−165 src/Streamly/Streams/StreamKType.hs+132−109 src/Streamly/Streams/Zip.hs+10−10
src/Streamly/Prelude.hs+12−12
@@ -840,9 +840,9 @@ iterate step = fromStream . go
840840iterateM :: (IsStream t, MonadAsync m) => (a -> m a) -> a -> t m a
841841iterateM step = go
842842 where
843− go s = fromStream $ K.mkStream $ \svr stp sng yld -> do
843+ go s = K.mkStream $ \st stp sng yld -> do
844844 next <- step s
845− K.unStreamShared (toStream (return s |: go next)) svr stp sng yld
845+ K.foldStreamShared st stp sng yld (return s |: go next)
846846
847847------------------------------------------------------------------------------
848848-- Conversions
@@ -894,7 +894,7 @@ each = K.fromFoldable
894894--
895895-- @since 0.1.0
896896fromHandle :: (IsStream t, MonadIO m) => IO.Handle -> t m String
897−fromHandle h = fromStream go
897+fromHandle h = go
898898 where
899899 go = K.mkStream $ \_ stp _ yld -> do
900900 eof <- liftIO $ IO.hIsEOF h
@@ -1443,13 +1443,13 @@ toList = P.toList
14431443--
14441444-- @since 0.1.0
14451445toHandle :: MonadIO m => IO.Handle -> SerialT m String -> m ()
1446−toHandle h m = go (toStream m)
1446+toHandle h m = go m
14471447 where
14481448 go m1 =
14491449 let stop = return ()
14501450 single a = liftIO (IO.hPutStrLn h a)
14511451 yieldk a r = liftIO (IO.hPutStrLn h a) >> go r
1452− in K.unStream m1 defState stop single yieldk
1452+ in K.foldStream defState stop single yieldk m1
14531453
14541454------------------------------------------------------------------------------
14551455-- Transformation by Folding (Scans)
@@ -1768,14 +1768,14 @@ mapMaybeMSerial f m = fromStreamD $ D.mapMaybeM f $ toStreamD m
17681768--
17691769-- @since 0.1.1
17701770reverse :: (IsStream t) => t m a -> t m a
1771−reverse m = fromStream $ go K.nil (toStream m)
1771+reverse m = go K.nil m
17721772 where
17731773 go rev rest = K.mkStream $ \st stp sng yld ->
1774− let runIt x = K.unStream x st stp sng yld
1774+ let runIt x = K.foldStream st stp sng yld x
17751775 stop = runIt rev
17761776 single a = runIt $ a `K.cons` rev
17771777 yieldk a r = runIt $ go (a `K.cons` rev) r
1778− in K.unStream rest st stop single yieldk
1778+ in K.foldStream st stop single yieldk rest
17791779
17801780------------------------------------------------------------------------------
17811781-- Transformation by Inserting
@@ -1986,10 +1986,10 @@ merge = mergeBy compare
19861986-- @since 0.6.0
19871987mergeAsyncBy :: (IsStream t, MonadAsync m)
19881988 => (a -> a -> Ordering) -> t m a -> t m a -> t m a
1989−mergeAsyncBy f m1 m2 = K.fromStream $ K.mkStream $ \st stp sng yld -> do
1989+mergeAsyncBy f m1 m2 = K.mkStream $ \st stp sng yld -> do
19901990 ma <- mkAsync' st m1
19911991 mb <- mkAsync' st m2
1992− K.unStream (K.toStream (K.mergeBy f ma mb)) st stp sng yld
1992+ K.foldStream st stp sng yld (K.mergeBy f ma mb)
19931993
19941994-- | Like 'mergeByM' but merges concurrently (i.e. both the elements being
19951995-- merged are generated concurrently).
@@ -1997,7 +1997,7 @@ mergeAsyncBy f m1 m2 = K.fromStream $ K.mkStream $ \st stp sng yld -> do
19971997-- @since 0.6.0
19981998mergeAsyncByM :: (IsStream t, MonadAsync m)
19991999 => (a -> a -> m Ordering) -> t m a -> t m a -> t m a
2000−mergeAsyncByM f m1 m2 = K.fromStream $ K.mkStream $ \st stp sng yld -> do
2000+mergeAsyncByM f m1 m2 = K.mkStream $ \st stp sng yld -> do
20012001 ma <- mkAsync' st m1
20022002 mb <- mkAsync' st m2
2003− K.unStream (K.toStream (K.mergeByM f ma mb)) st stp sng yld
2003+ K.foldStream st stp sng yld (K.mergeByM f ma mb)
src/Streamly/SVar.hs+1−1
@@ -434,7 +434,7 @@ defState = State
434434-- results in slightly better perf for zip/zipM but the performance of scan
435435-- worsens a lot, it does not fuse.
436436--
437−-- This has a side effect of clearing the SVar and yieldLimit, therefore it
437+-- XXX This has a side effect of clearing the SVar and yieldLimit, therefore it
438438-- should not be used to convert from the same type to the same type, unless
439439-- you want to clear the SVar. For clearing the SVar you should be using the
440440-- appropriate unStream functions instead.
src/Streamly/Streams/Ahead.hs+35−36
@@ -48,8 +48,8 @@ import Streamly.Streams.SVar (fromSVar)
4848import Streamly.Streams.Serial (map)
4949import Streamly.SVar
5050import Streamly.Streams.StreamK
51− (IsStream(..), Stream, mkStream, unStream, unStreamShared,
52− runStreamSVar)
51+ (IsStream(..), Stream, mkStream, foldStream, foldStreamShared,
52+ foldStreamSVar, unShare)
5353import qualified Streamly.Streams.StreamK as K
5454
5555import Prelude hiding (map)
@@ -298,9 +298,10 @@ processHeap q heap st sv winfo entry sno stopping = loopHeap sno entry
298298 let stop = do
299299 liftIO (incrementYieldLimit sv)
300300 nextHeap seqNo
301− runStreamSVar sv r st stop
301+ foldStreamSVar sv st stop
302302 (singleStreamFromHeap seqNo)
303303 (yieldStreamFromHeap seqNo)
304+ r
304305 else liftIO $ do
305306 let ent = Entry seqNo (AheadEntryStream r)
306307 liftIO $ requeueOnHeapTop heap ent seqNo
@@ -348,9 +349,10 @@ processWithoutToken q heap st sv winfo m seqNo = do
348349 -- we stop.
349350 toHeap AheadEntryNull
350351
351− runStreamSVar sv m st stop
352+ foldStreamSVar sv st stop
352353 (toHeap . AheadEntryPure)
353354 (\a r -> toHeap $ AheadEntryStream $ K.cons a r)
355+ m
354356
355357 where
356358
@@ -408,7 +410,7 @@ processWithToken q heap st sv winfo action sno = do
408410 liftIO (incrementYieldLimit sv)
409411 loopWithToken (sno + 1)
410412
411− runStreamSVar sv action st stop (singleOutput sno) (yieldOutput sno)
413+ foldStreamSVar sv st stop (singleOutput sno) (yieldOutput sno) action
412414
413415 where
414416
@@ -431,9 +433,10 @@ processWithToken q heap st sv winfo action sno = do
431433 let stop = do
432434 liftIO (incrementYieldLimit sv)
433435 loopWithToken (seqNo + 1)
434− runStreamSVar sv r st stop
436+ foldStreamSVar sv st stop
435437 (singleOutput seqNo)
436438 (yieldOutput seqNo)
439+ r
437440 else do
438441 let ent = Entry seqNo (AheadEntryStream r)
439442 liftIO $ requeueOnHeapTop heap ent seqNo
@@ -460,9 +463,10 @@ processWithToken q heap st sv winfo action sno = do
460463 let stop = do
461464 liftIO (incrementYieldLimit sv)
462465 loopWithToken (seqNo + 1)
463− runStreamSVar sv m st stop
466+ foldStreamSVar sv st stop
464467 (singleOutput seqNo)
465468 (yieldOutput seqNo)
469+ m
466470 else
467471 -- To avoid a race when another thread puts something
468472 -- on the heap and goes away, the consumer will not get
@@ -543,32 +547,37 @@ workLoopAhead q heap st sv winfo = do
543547
544548-- The only difference between forkSVarAsync and this is that we run the left
545549-- computation without a shared SVar.
546−forkSVarAhead :: MonadAsync m => Stream m a -> Stream m a -> Stream m a
550+forkSVarAhead :: (IsStream t, MonadAsync m) => t m a -> t m a -> t m a
547551forkSVarAhead m1 m2 = mkStream $ \st stp sng yld -> do
548− sv <- newAheadVar st (concurrently m1 m2) workLoopAhead
549− unStream (fromSVar sv) st stp sng yld
552+ sv <- newAheadVar st (concurrently (toStream m1) (toStream m2))
553+ workLoopAhead
554+ foldStream st stp sng yld (fromSVar sv)
550555 where
551556 concurrently ma mb = mkStream $ \st stp sng yld -> do
552557 liftIO $ enqueue (fromJust $ streamVar st) mb
553− unStream ma st stp sng yld
558+ foldStream st stp sng yld ma
554559
555−{-# INLINE aheadS #-}
556−aheadS :: MonadAsync m => Stream m a -> Stream m a -> Stream m a
557−aheadS m1 m2 = mkStream $ \st stp sng yld ->
560+-- | Polymorphic version of the 'Semigroup' operation '<>' of 'AheadT'.
561+-- Merges two streams sequentially but with concurrent lookahead.
562+--
563+-- @since 0.3.0
564+{-# INLINE ahead #-}
565+ahead :: (IsStream t, MonadAsync m) => t m a -> t m a -> t m a
566+ahead m1 m2 = mkStream $ \st stp sng yld ->
558567 case streamVar st of
559568 Just sv | svarStyle sv == AheadVar -> do
560− liftIO $ enqueue sv m2
569+ liftIO $ enqueue sv (toStream m2)
561570 -- Always run the left side on a new SVar to avoid complexity in
562571 -- sequencing results. This means the left side cannot further
563572 -- split into more ahead computations on the same SVar.
564− unStream m1 st stp sng yld
565− _ -> unStreamShared (forkSVarAhead m1 m2) st stp sng yld
573+ foldStream st stp sng yld m1
574+ _ -> foldStreamShared st stp sng yld (forkSVarAhead m1 m2)
566575
567576-- | XXX we can implement it more efficienty by directly implementing instead
568577-- of combining streams using ahead.
569578{-# INLINE consMAhead #-}
570−consMAhead :: MonadAsync m => m a -> Stream m a -> Stream m a
571−consMAhead m r = K.yieldM m `aheadS` r
579+consMAhead :: (IsStream t, MonadAsync m) => m a -> t m a -> t m a
580+consMAhead m r = K.yieldM m `ahead` r
572581
573582------------------------------------------------------------------------------
574583-- AheadT
@@ -639,7 +648,7 @@ instance IsStream AheadT where
639648
640649 {-# INLINE consM #-}
641650 {-# SPECIALIZE consM :: IO a -> AheadT IO a -> AheadT IO a #-}
642− consM m r = fromStream $ consMAhead m (toStream r)
651+ consM = consMAhead
643652
644653 {-# INLINE (|:) #-}
645654 {-# SPECIALIZE (|:) :: IO a -> AheadT IO a -> AheadT IO a #-}
@@ -649,15 +658,6 @@ instance IsStream AheadT where
649658-- Semigroup
650659------------------------------------------------------------------------------
651660
652−-- | Polymorphic version of the 'Semigroup' operation '<>' of 'AheadT'.
653−-- Merges two streams sequentially but with concurrent lookahead.
654−--
655−-- @since 0.3.0
656−{-# INLINE ahead #-}
657−ahead :: (IsStream t, MonadAsync m) => t m a -> t m a -> t m a
658−ahead m1 m2 = fromStream $ mkStream $ \st stp sng yld ->
659− unStreamShared (aheadS (toStream m1) (toStream m2)) st stp sng yld
660−
661661instance MonadAsync m => Semigroup (AheadT m a) where
662662 (<>) = ahead
663663
@@ -673,6 +673,8 @@ instance MonadAsync m => Monoid (AheadT m a) where
673673-- Monad
674674------------------------------------------------------------------------------
675675
676+-- XXX use bindWith instead
677+
676678{-# INLINE aheadbind #-}
677679aheadbind
678680 :: MonadAsync m
@@ -683,13 +685,10 @@ aheadbind m f = go m
683685 where
684686 go g =
685687 mkStream $ \st stp sng yld ->
686− let runShared x = unStreamShared x st stp sng yld
687− runIsolated x = unStream x st stp sng yld
688−
689− single a = runIsolated $ f a
690− yieldk a r = runShared $
691− K.unShare (f a) `aheadS` go r
692− in unStream g st stp single yieldk
688+ let foldShared = foldStreamShared st stp sng yld
689+ single a = foldShared $ unShare (f a)
690+ yieldk a r = foldShared $ unShare (f a) `ahead` go r
691+ in foldStream (adaptState st) stp single yieldk g
693692
694693instance MonadAsync m => Monad (AheadT m) where
695694 return = pure
src/Streamly/Streams/Async.hs+32−43
@@ -58,8 +58,8 @@ import Streamly.Streams.SVar (fromSVar)
5858import Streamly.Streams.Serial (map)
5959import Streamly.SVar
6060import Streamly.Streams.StreamK
61− (IsStream(..), Stream, mkStream, unStream, adapt, unStreamShared,
62− runStreamSVar)
61+ (IsStream(..), Stream, mkStream, foldStream, adapt, foldStreamShared,
62+ foldStreamSVar)
6363import qualified Streamly.Streams.StreamK as K
6464
6565#include "Instances.hs"
@@ -84,7 +84,7 @@ workLoopLIFO q st sv winfo = run
8484 work <- dequeue
8585 case work of
8686 Nothing -> liftIO $ sendStop sv winfo
87− Just m -> runStreamSVar sv m st run single yieldk
87+ Just m -> foldStreamSVar sv st run single yieldk m
8888
8989 single a = do
9090 res <- liftIO $ sendYield sv winfo (ChildYield a)
@@ -93,7 +93,7 @@ workLoopLIFO q st sv winfo = run
9393 yieldk a r = do
9494 res <- liftIO $ sendYield sv winfo (ChildYield a)
9595 if res
96− then runStreamSVar sv r st run single yieldk
96+ then foldStreamSVar sv st run single yieldk r
9797 else liftIO $ do
9898 enqueueLIFO sv q r
9999 sendStop sv winfo
@@ -134,7 +134,7 @@ workLoopLIFOLimited q st sv winfo = run
134134 if yieldLimitOk
135135 then do
136136 let stop = liftIO (incrementYieldLimit sv) >> run
137− runStreamSVar sv m st stop single yieldk
137+ foldStreamSVar sv st stop single yieldk m
138138 -- Avoid any side effects, undo the yield limit decrement if we
139139 -- never yielded anything.
140140 else liftIO $ do
@@ -153,7 +153,7 @@ workLoopLIFOLimited q st sv winfo = run
153153 yieldLimitOk <- liftIO $ decrementYieldLimit sv
154154 let stop = liftIO (incrementYieldLimit sv) >> run
155155 if res && yieldLimitOk
156− then runStreamSVar sv r st stop single yieldk
156+ then foldStreamSVar sv st stop single yieldk r
157157 else liftIO $ do
158158 incrementYieldLimit sv
159159 enqueueLIFO sv q r
@@ -185,7 +185,7 @@ workLoopFIFO q st sv winfo = run
185185 work <- liftIO $ tryPopR q
186186 case work of
187187 Nothing -> liftIO $ sendStop sv winfo
188− Just m -> runStreamSVar sv m st run single yieldk
188+ Just m -> foldStreamSVar sv st run single yieldk m
189189
190190 single a = do
191191 res <- liftIO $ sendYield sv winfo (ChildYield a)
@@ -194,7 +194,7 @@ workLoopFIFO q st sv winfo = run
194194 yieldk a r = do
195195 res <- liftIO $ sendYield sv winfo (ChildYield a)
196196 if res
197− then runStreamSVar sv r st run single yieldk
197+ then foldStreamSVar sv st run single yieldk r
198198 else liftIO $ do
199199 enqueueFIFO sv q r
200200 sendStop sv winfo
@@ -220,7 +220,7 @@ workLoopFIFOLimited q st sv winfo = run
220220 if yieldLimitOk
221221 then do
222222 let stop = liftIO (incrementYieldLimit sv) >> run
223− runStreamSVar sv m st stop single yieldk
223+ foldStreamSVar sv st stop single yieldk m
224224 else liftIO $ do
225225 enqueueFIFO sv q m
226226 incrementYieldLimit sv
@@ -235,7 +235,7 @@ workLoopFIFOLimited q st sv winfo = run
235235 yieldLimitOk <- liftIO $ decrementYieldLimit sv
236236 let stop = liftIO (incrementYieldLimit sv) >> run
237237 if res && yieldLimitOk
238− then runStreamSVar sv r st stop single yieldk
238+ then foldStreamSVar sv st stop single yieldk r
239239 else liftIO $ do
240240 incrementYieldLimit sv
241241 enqueueFIFO sv q r
@@ -528,36 +528,33 @@ newWAsyncVar st m = do
528528-- composition and vice-versa we create a new SVar to isolate the scheduling
529529-- of the two.
530530
531−forkSVarAsync :: MonadAsync m
532− => SVarStyle -> Stream m a -> Stream m a -> Stream m a
531+forkSVarAsync :: (IsStream t, MonadAsync m)
532+ => SVarStyle -> t m a -> t m a -> t m a
533533forkSVarAsync style m1 m2 = mkStream $ \st stp sng yld -> do
534534 sv <- case style of
535− AsyncVar -> newAsyncVar st (concurrently m1 m2)
536− WAsyncVar -> newWAsyncVar st (concurrently m1 m2)
535+ AsyncVar -> newAsyncVar st (concurrently (toStream m1) (toStream m2))
536+ WAsyncVar -> newWAsyncVar st (concurrently (toStream m1) (toStream m2))
537537 _ -> error "illegal svar type"
538− unStream (fromSVar sv) st stp sng yld
538+ foldStream st stp sng yld $ fromSVar sv
539539 where
540540 concurrently ma mb = mkStream $ \st stp sng yld -> do
541541 liftIO $ enqueue (fromJust $ streamVar st) mb
542− unStreamShared ma st stp sng yld
542+ foldStreamShared st stp sng yld ma
543543
544544{-# INLINE joinStreamVarAsync #-}
545−joinStreamVarAsync :: MonadAsync m
546− => SVarStyle -> Stream m a -> Stream m a -> Stream m a
545+joinStreamVarAsync :: (IsStream t, MonadAsync m)
546+ => SVarStyle -> t m a -> t m a -> t m a
547547joinStreamVarAsync style m1 m2 = mkStream $ \st stp sng yld ->
548548 case streamVar st of
549− Just sv | svarStyle sv == style ->
550− liftIO (enqueue sv m2) >> unStreamShared m1 st stp sng yld
551− _ -> unStreamShared (forkSVarAsync style m1 m2) st stp sng yld
549+ Just sv | svarStyle sv == style -> do
550+ liftIO $ enqueue sv (toStream m2)
551+ foldStreamShared st stp sng yld m1
552+ _ -> foldStreamShared st stp sng yld (forkSVarAsync style m1 m2)
552553
553554------------------------------------------------------------------------------
554555-- Semigroup and Monoid style compositions for parallel actions
555556------------------------------------------------------------------------------
556557
557−{-# INLINE asyncS #-}
558−asyncS :: MonadAsync m => Stream m a -> Stream m a -> Stream m a
559−asyncS = joinStreamVarAsync AsyncVar
560−
561558-- | Polymorphic version of the 'Semigroup' operation '<>' of 'AsyncT'.
562559-- Merges two streams possibly concurrently, preferring the
563560-- elements from the left one when available.
@@ -565,9 +562,7 @@ asyncS = joinStreamVarAsync AsyncVar
565562-- @since 0.2.0
566563{-# INLINE async #-}
567564async :: (IsStream t, MonadAsync m) => t m a -> t m a -> t m a
568−async m1 m2 = fromStream $ mkStream $ \st stp sng yld ->
569− unStreamShared (joinStreamVarAsync AsyncVar (toStream m1) (toStream m2))
570− st stp sng yld
565+async = joinStreamVarAsync AsyncVar
571566
572567-- | Same as 'async'.
573568--
@@ -580,8 +575,8 @@ async m1 m2 = fromStream $ mkStream $ \st stp sng yld ->
580575-- | XXX we can implement it more efficienty by directly implementing instead
581576-- of combining streams using async.
582577{-# INLINE consMAsync #-}
583−consMAsync :: MonadAsync m => m a -> Stream m a -> Stream m a
584−consMAsync m r = K.yieldM m `asyncS` r
578+consMAsync :: (IsStream t, MonadAsync m) => m a -> t m a -> t m a
579+consMAsync m r = K.yieldM m `async` r
585580
586581------------------------------------------------------------------------------
587582-- AsyncT
@@ -657,7 +652,7 @@ instance IsStream AsyncT where
657652
658653 {-# INLINE consM #-}
659654 {-# SPECIALIZE consM :: IO a -> AsyncT IO a -> AsyncT IO a #-}
660− consM m r = fromStream $ consMAsync m (toStream r)
655+ consM = consMAsync
661656
662657 {-# INLINE (|:) #-}
663658 {-# SPECIALIZE (|:) :: IO a -> AsyncT IO a -> AsyncT IO a #-}
@@ -684,7 +679,7 @@ instance MonadAsync m => Monoid (AsyncT m a) where
684679
685680instance MonadAsync m => Monad (AsyncT m) where
686681 return = pure
687− (AsyncT m) >>= f = AsyncT $ K.bindWith asyncS m (getAsyncT . f)
682+ (>>=) = K.bindWith async
688683
689684------------------------------------------------------------------------------
690685-- Other instances
@@ -697,15 +692,11 @@ MONAD_COMMON_INSTANCES(AsyncT, MONADPARALLEL)
697692-- WAsyncT
698693------------------------------------------------------------------------------
699694
700−{-# INLINE wAsyncS #-}
701−wAsyncS :: MonadAsync m => Stream m a -> Stream m a -> Stream m a
702−wAsyncS = joinStreamVarAsync WAsyncVar
703−
704695-- | XXX we can implement it more efficienty by directly implementing instead
705696-- of combining streams using wAsync.
706697{-# INLINE consMWAsync #-}
707−consMWAsync :: MonadAsync m => m a -> Stream m a -> Stream m a
708−consMWAsync m r = K.yieldM m `wAsyncS` r
698+consMWAsync :: (IsStream t, MonadAsync m) => m a -> t m a -> t m a
699+consMWAsync m r = K.yieldM m `wAsync` r
709700
710701-- | Polymorphic version of the 'Semigroup' operation '<>' of 'WAsyncT'.
711702-- Merges two streams concurrently choosing elements from both fairly.
@@ -713,8 +704,7 @@ consMWAsync m r = K.yieldM m `wAsyncS` r
713704-- @since 0.2.0
714705{-# INLINE wAsync #-}
715706wAsync :: (IsStream t, MonadAsync m) => t m a -> t m a -> t m a
716−wAsync m1 m2 = fromStream $ mkStream $ \st stp sng yld ->
717− unStreamShared (wAsyncS (toStream m1) (toStream m2)) st stp sng yld
707+wAsync = joinStreamVarAsync WAsyncVar
718708
719709-- | Wide async composition or async composition with breadth first traversal.
720710-- The Semigroup instance of 'WAsyncT' concurrently /traverses/ the composed
@@ -784,7 +774,7 @@ instance IsStream WAsyncT where
784774
785775 {-# INLINE consM #-}
786776 {-# SPECIALIZE consM :: IO a -> WAsyncT IO a -> WAsyncT IO a #-}
787− consM m r = fromStream $ consMWAsync m (toStream r)
777+ consM = consMWAsync
788778
789779 {-# INLINE (|:) #-}
790780 {-# SPECIALIZE (|:) :: IO a -> WAsyncT IO a -> WAsyncT IO a #-}
@@ -811,8 +801,7 @@ instance MonadAsync m => Monoid (WAsyncT m a) where
811801
812802instance MonadAsync m => Monad (WAsyncT m) where
813803 return = pure
814− (WAsyncT m) >>= f =
815− WAsyncT $ K.bindWith wAsyncS m (getWAsyncT . f)
804+ (>>=) = K.bindWith wAsync
816805
817806------------------------------------------------------------------------------
818807-- Other instances
src/Streamly/Streams/Combinators.hs+12−12
@@ -52,8 +52,8 @@ import Streamly.Streams.Serial (SerialT)
5252-- @since 0.4.0
5353{-# INLINE_NORMAL maxThreads #-}
5454maxThreads :: IsStream t => Int -> t m a -> t m a
55−maxThreads n m = fromStream $ mkStream $ \st stp sng yld ->
56− unStreamShared (toStream m) (setMaxThreads n st) stp sng yld
55+maxThreads n m = mkStream $ \st stp sng yld ->
56+ foldStreamShared (setMaxThreads n st) stp sng yld m
5757
5858{-
5959{-# RULES "maxThreadsSerial serial" maxThreads = maxThreadsSerial #-}
@@ -77,8 +77,8 @@ maxThreadsSerial _ = id
7777-- @since 0.4.0
7878{-# INLINE_NORMAL maxBuffer #-}
7979maxBuffer :: IsStream t => Int -> t m a -> t m a
80−maxBuffer n m = fromStream $ mkStream $ \st stp sng yld ->
81− unStreamShared (toStream m) (setMaxBuffer n st) stp sng yld
80+maxBuffer n m = mkStream $ \st stp sng yld ->
81+ foldStreamShared (setMaxBuffer n st) stp sng yld m
8282
8383{-
8484{-# RULES "maxBuffer serial" maxBuffer = maxBufferSerial #-}
@@ -101,7 +101,7 @@ maxBufferSerial _ = id
101101-- @since 0.5.0
102102{-# INLINE_NORMAL rate #-}
103103rate :: IsStream t => Maybe Rate -> t m a -> t m a
104−rate r m = fromStream $ mkStream $ \st stp sng yld ->
104+rate r m = mkStream $ \st stp sng yld ->
105105 case r of
106106 Just (Rate low goal _ _) | goal < low ->
107107 error "rate: Target rate cannot be lower than minimum rate."
@@ -109,7 +109,7 @@ rate r m = fromStream $ mkStream $ \st stp sng yld ->
109109 error "rate: Target rate cannot be greater than maximum rate."
110110 Just (Rate low _ high _) | low > high ->
111111 error "rate: Minimum rate cannot be greater than maximum rate."
112− _ -> unStreamShared (toStream m) (setStreamRate r st) stp sng yld
112+ _ -> foldStreamShared (setStreamRate r st) stp sng yld m
113113
114114-- XXX implement for serial streams as well, as a simple delay
115115
@@ -181,8 +181,8 @@ constRate r = rate (Just $ Rate r r r 0)
181181--
182182{-# INLINE_NORMAL _serialLatency #-}
183183_serialLatency :: IsStream t => Int -> t m a -> t m a
184−_serialLatency n m = fromStream $ mkStream $ \st stp sng yld ->
185− unStreamShared (toStream m) (setStreamLatency n st) stp sng yld
184+_serialLatency n m = mkStream $ \st stp sng yld ->
185+ foldStreamShared (setStreamLatency n st) stp sng yld m
186186
187187{-
188188{-# RULES "serialLatency serial" _serialLatency = serialLatencySerial #-}
@@ -196,8 +196,8 @@ serialLatencySerial _ = id
196196-- inherited by everything in enclosed scope.
197197{-# INLINE_NORMAL maxYields #-}
198198maxYields :: IsStream t => Maybe Int64 -> t m a -> t m a
199−maxYields n m = fromStream $ mkStream $ \st stp sng yld ->
200− unStreamShared (toStream m) (setYieldLimit n st) stp sng yld
199+maxYields n m = mkStream $ \st stp sng yld ->
200+ foldStreamShared (setYieldLimit n st) stp sng yld m
201201
202202{-# RULES "maxYields serial" maxYields = maxYieldsSerial #-}
203203maxYieldsSerial :: Maybe Int64 -> SerialT m a -> SerialT m a
@@ -212,5 +212,5 @@ printState st = liftIO $ do
212212
213213-- | Print debug information about an SVar when the stream ends
214214inspectMode :: IsStream t => t m a -> t m a
215−inspectMode m = fromStream $ mkStream $ \st stp sng yld ->
216− unStreamShared (toStream m) (setInspectMode st) stp sng yld
215+inspectMode m = mkStream $ \st stp sng yld ->
216+ foldStreamShared (setInspectMode st) stp sng yld m
src/Streamly/Streams/Parallel.hs+19−26
@@ -49,8 +49,8 @@ import Prelude hiding (map)
4949import Streamly.Streams.SVar (fromSVar)
5050import Streamly.Streams.Serial (map)
5151import Streamly.SVar
52−import Streamly.Streams.StreamK (IsStream(..), Stream, mkStream, unStream,
53− unStreamShared, adapt)
52+import Streamly.Streams.StreamK (IsStream(..), Stream, mkStream, foldStream,
53+ foldStreamShared, adapt)
5454import qualified Streamly.Streams.StreamK as K
5555
5656#include "Instances.hs"
@@ -63,7 +63,7 @@ import qualified Streamly.Streams.StreamK as K
6363runOne
6464 :: MonadIO m
6565 => State Stream m a -> Stream m a -> Maybe WorkerInfo -> m ()
66−runOne st m winfo = unStreamShared m st stop single yieldk
66+runOne st m winfo = foldStreamShared st stop single yieldk m
6767
6868 where
6969
@@ -88,32 +88,28 @@ runOne st m winfo = unStreamShared m st stop single yieldk
8888 >> withLimitCheck (void $ liftIO $ mrun $ runOne st r winfo)
8989
9090{-# NOINLINE forkSVarPar #-}
91−forkSVarPar :: MonadAsync m => Stream m a -> Stream m a -> Stream m a
91+forkSVarPar :: (IsStream t, MonadAsync m) => t m a -> t m a -> t m a
9292forkSVarPar m r = mkStream $ \st stp sng yld -> do
9393 sv <- newParallelVar st
94− pushWorkerPar sv (runOne st{streamVar = Just sv} m)
95− pushWorkerPar sv (runOne st{streamVar = Just sv} r)
96− unStream (fromSVar sv) st stp sng yld
94+ pushWorkerPar sv (runOne st{streamVar = Just sv} $ toStream m)
95+ pushWorkerPar sv (runOne st{streamVar = Just sv} $ toStream r)
96+ foldStream st stp sng yld (fromSVar sv)
9797
9898{-# INLINE joinStreamVarPar #-}
99−joinStreamVarPar :: MonadAsync m
100− => SVarStyle -> Stream m a -> Stream m a -> Stream m a
99+joinStreamVarPar :: (IsStream t, MonadAsync m)
100+ => SVarStyle -> t m a -> t m a -> t m a
101101joinStreamVarPar style m1 m2 = mkStream $ \st stp sng yld ->
102102 case streamVar st of
103103 Just sv | svarStyle sv == style -> do
104− pushWorkerPar sv (runOne st m1)
105− unStreamShared m2 st stp sng yld
106− _ -> unStreamShared (forkSVarPar m1 m2) st stp sng yld
107−
108−{-# INLINE parallelStream #-}
109−parallelStream :: MonadAsync m => Stream m a -> Stream m a -> Stream m a
110−parallelStream = joinStreamVarPar ParallelVar
104+ pushWorkerPar sv (runOne st $ toStream m1)
105+ foldStreamShared st stp sng yld m2
106+ _ -> foldStreamShared st stp sng yld (forkSVarPar m1 m2)
111107
112108-- | XXX we can implement it more efficienty by directly implementing instead
113109-- of combining streams using parallel.
114110{-# INLINE consMParallel #-}
115−consMParallel :: MonadAsync m => m a -> Stream m a -> Stream m a
116−consMParallel m r = K.yieldM m `parallelStream` r
111+consMParallel :: (IsStream t, MonadAsync m) => m a -> t m a -> t m a
112+consMParallel m r = K.yieldM m `parallel` r
117113
118114-- | Polymorphic version of the 'Semigroup' operation '<>' of 'ParallelT'
119115-- Merges two streams concurrently.
@@ -121,9 +117,7 @@ consMParallel m r = K.yieldM m `parallelStream` r
121117-- @since 0.2.0
122118{-# INLINE parallel #-}
123119parallel :: (IsStream t, MonadAsync m) => t m a -> t m a -> t m a
124−parallel m1 m2 = fromStream $ mkStream $ \st stp sng yld ->
125− unStreamShared (parallelStream (toStream m1) (toStream m2))
126− st stp sng yld
120+parallel = joinStreamVarPar ParallelVar
127121
128122------------------------------------------------------------------------------
129123-- Convert a stream to parallel
@@ -141,10 +135,10 @@ mkParallel m = do
141135
142136{-# INLINE applyWith #-}
143137applyWith :: (IsStream t, MonadAsync m) => (t m a -> t m b) -> t m a -> t m b
144−applyWith f m = fromStream $ mkStream $ \st stp sng yld -> do
138+applyWith f m = mkStream $ \st stp sng yld -> do
145139 sv <- newParallelVar (adaptState st)
146140 pushWorkerPar sv (runOne st{streamVar = Just sv} (toStream m))
147− unStream (toStream $ f $ fromSVar sv) st stp sng yld
141+ foldStream st stp sng yld $ f $ fromSVar sv
148142
149143------------------------------------------------------------------------------
150144-- Stream runner concurrent function application
@@ -346,7 +340,7 @@ instance IsStream ParallelT where
346340
347341 {-# INLINE consM #-}
348342 {-# SPECIALIZE consM :: IO a -> ParallelT IO a -> ParallelT IO a #-}
349− consM m r = fromStream $ consMParallel m (toStream r)
343+ consM = consMParallel
350344
351345 {-# INLINE (|:) #-}
352346 {-# SPECIALIZE (|:) :: IO a -> ParallelT IO a -> ParallelT IO a #-}
@@ -373,8 +367,7 @@ instance MonadAsync m => Monoid (ParallelT m a) where
373367
374368instance MonadAsync m => Monad (ParallelT m) where
375369 return = pure
376− (ParallelT m) >>= f
377− = ParallelT $ K.bindWith parallelStream m (getParallelT . f)
370+ (>>=) = K.bindWith parallel
378371
379372------------------------------------------------------------------------------
380373-- Other instances
src/Streamly/Streams/SVar.hs+7−6
@@ -43,7 +43,7 @@ fromStreamVar sv = mkStream $ \st stp sng yld -> do
4343 -- Reversing the output is important to guarantee that we process the
4444 -- outputs in the same order as they were generated by the constituent
4545 -- streams.
46− unStream (processEvents $ reverse list) st stp sng yld
46+ foldStream st stp sng yld $ processEvents $ reverse list
4747
4848 where
4949
@@ -59,7 +59,7 @@ fromStreamVar sv = mkStream $ \st stp sng yld -> do
5959 done <- postProcess sv
6060 if done
6161 then allDone stp
62− else unStream (fromStreamVar sv) st stp sng yld
62+ else foldStream st stp sng yld $ fromStreamVar sv
6363
6464 processEvents (ev : es) = mkStream $ \st stp sng yld -> do
6565 let rest = processEvents es
@@ -68,23 +68,24 @@ fromStreamVar sv = mkStream $ \st stp sng yld -> do
6868 ChildStop tid e -> do
6969 accountThread sv tid
7070 case e of
71− Nothing -> unStream rest st stp sng yld
71+ Nothing -> foldStream st stp sng yld rest
7272 Just ex ->
7373 case fromException ex of
7474 Just ThreadAbort ->
75− unStream rest st stp sng yld
75+ foldStream st stp sng yld rest
7676 Nothing -> liftIO (cleanupSVar sv) >> throwM ex
7777
7878{-# INLINE fromSVar #-}
7979fromSVar :: (MonadAsync m, IsStream t) => SVar Stream m a -> t m a
8080fromSVar sv =
81− fromStream $ mkStream $ \st stp sng yld -> do
81+ mkStream $ \st stp sng yld -> do
8282 ref <- liftIO $ newIORef ()
8383 _ <- liftIO $ mkWeakIORef ref hook
8484 -- We pass a copy of sv to fromStreamVar, so that we know that it has
8585 -- no other references, when that copy gets garbage collected "ref"
8686 -- will get garbage collected and our hook will be called.
87− unStreamShared (fromStreamVar sv{svarRef = Just ref}) st stp sng yld
87+ foldStreamShared st stp sng yld $
88+ fromStream $ fromStreamVar sv{svarRef = Just ref}
8889 where
8990
9091 hook = do
src/Streamly/Streams/Serial.hs+30−42
@@ -24,7 +24,7 @@ module Streamly.Streams.Serial
2424 SerialT
2525 , StreamT -- deprecated
2626 , Serial
27− , serial
27+ , K.serial
2828 , serially
2929
3030 -- * Serial interleaving stream
@@ -60,8 +60,9 @@ import Text.Read (Lexeme(Ident), lexP, parens, prec, readPrec, readListPrec,
6060 readListPrecDefault)
6161import Prelude hiding (map, mapM)
6262
63+import Streamly.SVar (adaptState)
6364import Streamly.Streams.StreamK (IsStream(..), adapt, Stream, mkStream,
64− unStream)
65+ foldStream)
6566import qualified Streamly.Streams.Prelude as P
6667import qualified Streamly.Streams.StreamK as K
6768import qualified Streamly.Streams.StreamD as D
@@ -156,39 +157,28 @@ instance IsStream SerialT where
156157 {-# INLINE consM #-}
157158 {-# SPECIALIZE consM :: IO a -> SerialT IO a -> SerialT IO a #-}
158159 consM :: Monad m => m a -> SerialT m a -> SerialT m a
159− consM m r = fromStream $ K.consMSerial m (toStream r)
160+ consM = K.consMSerial
160161
161162 {-# INLINE (|:) #-}
162163 {-# SPECIALIZE (|:) :: IO a -> SerialT IO a -> SerialT IO a #-}
163164 (|:) :: Monad m => m a -> SerialT m a -> SerialT m a
164− m |: r = fromStream $ K.consMSerial m (toStream r)
165−
166−------------------------------------------------------------------------------
167−-- Semigroup
168−------------------------------------------------------------------------------
169−
170−-- | Polymorphic version of the 'Semigroup' operation '<>' of 'SerialT'.
171−-- Appends two streams sequentially, yielding all elements from the first
172−-- stream, and then all elements from the second stream.
173−--
174−-- @since 0.2.0
175−{-# INLINE serial #-}
176−serial :: IsStream t => t m a -> t m a -> t m a
177−serial m1 m2 = fromStream $ mkStream $ \st stp sng yld ->
178− unStream (K.serial (toStream m1) (toStream m2))
179− st stp sng yld
165+ (|:) = K.consMSerial
180166
181167------------------------------------------------------------------------------
182168-- Monad
183169------------------------------------------------------------------------------
184170
171+-- XXX if foldStreamShared/unShare/adaptState are not efficient in serial case
172+-- we can use a rewrite rule for that for the serial case and then just use a
173+-- bindWith serial here.
174+--
185175instance Monad m => Monad (SerialT m) where
186176 return = pure
187− (SerialT m) >>= f = SerialT $ mkStream $ \st stp sng yld ->
188− let run x = unStream x st stp sng yld
189− single a = run $ toStream (f a)
190− yieldk a r = run $ toStream $ f a <> (fromStream r >>= f)
191− in unStream m st stp single yieldk
177+ m >>= f = mkStream $ \st stp sng yld ->
178+ let run x = foldStream st stp sng yld x
179+ single a = run $ f a
180+ yieldk a r = run $ f a <> (r >>= f)
181+ in foldStream (adaptState st) stp single yieldk m
192182
193183------------------------------------------------------------------------------
194184-- Other instances
@@ -293,34 +283,28 @@ instance IsStream WSerialT where
293283 {-# INLINE consM #-}
294284 {-# SPECIALIZE consM :: IO a -> WSerialT IO a -> WSerialT IO a #-}
295285 consM :: Monad m => m a -> WSerialT m a -> WSerialT m a
296− consM m r = fromStream $ K.consMSerial m (toStream r)
286+ consM = K.consMSerial
297287
298288 {-# INLINE (|:) #-}
299289 {-# SPECIALIZE (|:) :: IO a -> WSerialT IO a -> WSerialT IO a #-}
300290 (|:) :: Monad m => m a -> WSerialT m a -> WSerialT m a
301− m |: r = fromStream $ K.consMSerial m (toStream r)
291+ (|:) = K.consMSerial
302292
303293------------------------------------------------------------------------------
304294-- Semigroup
305295------------------------------------------------------------------------------
306296
307−{-# INLINE interleave #-}
308−interleave :: Stream m a -> Stream m a -> Stream m a
309−interleave m1 m2 = mkStream $ \st stp sng yld -> do
310− let stop = unStream m2 st stp sng yld
311− single a = yld a m2
312− yieldk a r = yld a (interleave m2 r)
313− unStream m1 st stop single yieldk
314−
315297-- | Polymorphic version of the 'Semigroup' operation '<>' of 'WSerialT'.
316298-- Interleaves two streams, yielding one element from each stream alternately.
317299--
318300-- @since 0.2.0
319301{-# INLINE wSerial #-}
320302wSerial :: IsStream t => t m a -> t m a -> t m a
321−wSerial m1 m2 = fromStream $ mkStream $ \st stp sng yld ->
322− unStream (interleave (toStream m1) (toStream m2))
323− st stp sng yld
303+wSerial m1 m2 = mkStream $ \st stp sng yld -> do
304+ let stop = foldStream st stp sng yld m2
305+ single a = yld a m2
306+ yieldk a r = yld a (wSerial m2 r)
307+ foldStream st stop single yieldk m1
324308
325309instance Semigroup (WSerialT m a) where
326310 (<>) = wSerial
@@ -347,13 +331,17 @@ instance Monoid (WSerialT m a) where
347331-- Monad
348332------------------------------------------------------------------------------
349333
334+-- XXX if foldStreamShared/unShare/adaptState are not efficient in serial case
335+-- we can use a rewrite rule for that for the serial case and then just use a
336+-- bindWith interleave here.
337+--
350338instance Monad m => Monad (WSerialT m) where
351339 return = pure
352− (WSerialT m) >>= f = WSerialT $ mkStream $ \st stp sng yld ->
353− let run x = unStream x st stp sng yld
354− single a = run $ toStream (f a)
355− yieldk a r = run $ toStream $ f a <> (fromStream r >>= f)
356− in unStream m st stp single yieldk
340+ m >>= f = mkStream $ \st stp sng yld ->
341+ let run x = foldStream st stp sng yld x
342+ single a = run $ f a
343+ yieldk a r = run $ f a <> (r >>= f)
344+ in foldStream (adaptState st) stp single yieldk m
357345
358346------------------------------------------------------------------------------
359347-- Other instances
src/Streamly/Streams/StreamD.hs+2−2
@@ -483,7 +483,7 @@ fromStreamK = Stream step
483483 let stop = return Stop
484484 single a = return $ Yield a K.nil
485485 yieldk a r = return $ Yield a r
486− in K.unStreamShared m1 gst stop single yieldk
486+ in K.foldStreamShared gst stop single yieldk m1
487487
488488{-# INLINE toStreamD #-}
489489toStreamD :: (K.IsStream t, Monad m) => t m a -> Stream m a
@@ -883,7 +883,7 @@ toStreamK (Stream step state) = go state
883883 r <- step gst st
884884 case r of
885885 Yield x s -> yld x (go s)
886− Skip s -> K.unStreamShared (go s) gst stp sng yld
886+ Skip s -> K.foldStreamShared gst stp sng yld $ go s
887887 Stop -> stp
888888
889889#ifndef DISABLE_FUSION
src/Streamly/Streams/StreamK.hs+161−165
@@ -6,6 +6,7 @@
66{-# LANGUAGE InstanceSigs #-}
77{-# LANGUAGE MultiParamTypeClasses #-}
88{-# LANGUAGE RankNTypes #-}
9+{-# LANGUAGE ScopedTypeVariables #-}
910{-# LANGUAGE UndecidableInstances #-} -- XXX
1011
1112-- |
@@ -33,17 +34,21 @@ module Streamly.Streams.StreamK
3334
3435 -- * The stream type
3536 , Stream
36− , unStream
37− , unStreamShared
38− , unShare
39− , runStreamSVar
4037
41− -- * Construction
38+ -- * Construction Primitives
4239 , mkStream
4340 , nil
4441 , cons
4542 , (.:)
4643
44+ -- * Elimination Primitives
45+ , foldStream
46+ , foldStreamShared
47+ , foldStreamSVar
48+
49+ -- * Transformation Primitives
50+ , unShare
51+
4752 -- * Asynchronous construction
4853 , nilK
4954 , yieldK
@@ -71,7 +76,6 @@ module Streamly.Streams.StreamK
7176
7277 -- * Elimination
7378 -- ** General Folds
74− , foldStream
7579 , foldr
7680 , foldrM
7781 , foldr1
@@ -174,9 +178,9 @@ import Streamly.Streams.StreamKType
174178
175179-- | Detach a stream from an SVar
176180{-# INLINE unShare #-}
177−unShare :: Stream m a -> Stream m a
181+unShare :: IsStream t => t m a -> t m a
178182unShare x = mkStream $ \st stp sng yld ->
179− unStream x st stp sng yld
183+ foldStream st stp sng yld x
180184
181185------------------------------------------------------------------------------
182186-- Construction
@@ -197,7 +201,7 @@ infixr 5 `cons`
197201--
198202-- @since 0.1.0
199203cons :: IsStream t => a -> t m a -> t m a
200−cons a r = fromStream $ mkStream $ \_ _ _ yld -> yld a (toStream r)
204+cons a r = mkStream $ \_ _ _ yld -> yld a r
201205
202206infixr 5 .:
203207
@@ -218,15 +222,15 @@ infixr 5 .:
218222
219223-- | Make an empty stream from a callback function.
220224nilK :: IsStream t => (forall r. m r -> m r) -> t m a
221−nilK k = fromStream $ mkStream $ \_ stp _ _ -> k stp
225+nilK k = mkStream $ \_ stp _ _ -> k stp
222226
223227-- | Make a singleton stream from a one shot callback function.
224228yieldK :: IsStream t => (forall r. (a -> m r) -> m r) -> t m a
225−yieldK k = fromStream $ mkStream $ \_ _ sng _ -> k sng
229+yieldK k = mkStream $ \_ _ sng _ -> k sng
226230
227231-- | Construct a stream from a callback function.
228232consK :: IsStream t => (forall r. (a -> m r) -> m r) -> t m a -> t m a
229−consK k r = fromStream $ mkStream $ \_ _ _ yld -> k (\x -> yld x (toStream r))
233+consK k r = mkStream $ \_ _ _ yld -> k (\x -> yld x r)
230234
231235-- XXX consK with concurrent callbacks
232236-- XXX Build a stream from a repeating callback function.
@@ -240,8 +244,8 @@ uncons :: (IsStream t, Monad m) => t m a -> m (Maybe (a, t m a))
240244uncons m =
241245 let stop = return Nothing
242246 single a = return (Just (a, nil))
243− yieldk a r = return (Just (a, fromStream r))
244− in unStream (toStream m) defState stop single yieldk
247+ yieldk a r = return (Just (a, r))
248+ in foldStream defState stop single yieldk m
245249
246250-------------------------------------------------------------------------------
247251-- Generation
@@ -249,7 +253,7 @@ uncons m =
249253
250254{-# INLINE unfoldr #-}
251255unfoldr :: IsStream t => (b -> Maybe (a, b)) -> b -> t m a
252−unfoldr step = fromStream . go
256+unfoldr step = go
253257 where
254258 go s = mkStream $ \_ stp _ yld ->
255259 case step s of
@@ -260,19 +264,19 @@ unfoldr step = fromStream . go
260264unfoldrM :: (IsStream t, MonadAsync m) => (b -> m (Maybe (a, b))) -> b -> t m a
261265unfoldrM step = go
262266 where
263− go s = fromStream $ mkStream $ \svr stp sng yld -> do
267+ go s = mkStream $ \st stp sng yld -> do
264268 mayb <- step s
265269 case mayb of
266270 Nothing -> stp
267271 Just (a, b) ->
268− unStreamShared (toStream (return a |: go b)) svr stp sng yld
272+ foldStreamShared st stp sng yld $ return a |: go b
269273
270274-------------------------------------------------------------------------------
271275-- Special generation
272276-------------------------------------------------------------------------------
273277
274278yield :: IsStream t => a -> t m a
275−yield a = fromStream $ mkStream $ \_ _ single _ -> single a
279+yield a = mkStream $ \_ _ single _ -> single a
276280
277281-- | Same as yieldM
278282--
@@ -325,8 +329,8 @@ fromList :: IsStream t => [a] -> t m a
325329fromList = fromFoldable
326330
327331{-# INLINE fromStreamK #-}
328−fromStreamK :: Stream m a -> Stream m a
329−fromStreamK = id
332+fromStreamK :: IsStream t => Stream m a -> t m a
333+fromStreamK = fromStream
330334
331335-------------------------------------------------------------------------------
332336-- Elimination by Folding
@@ -334,24 +338,24 @@ fromStreamK = id
334338
335339-- | Lazy right associative fold.
336340foldr :: (IsStream t, Monad m) => (a -> b -> b) -> b -> t m a -> m b
337−foldr step acc m = go (toStream m)
341+foldr step acc m = go m
338342 where
339343 go m1 =
340344 let stop = return acc
341345 single a = return (step a acc)
342346 yieldk a r = go r >>= \b -> return (step a b)
343− in unStream m1 defState stop single yieldk
347+ in foldStream defState stop single yieldk m1
344348
345349-- | Lazy right fold with a monadic step function.
346350{-# INLINE foldrM #-}
347351foldrM :: (IsStream t, Monad m) => (a -> b -> m b) -> b -> t m a -> m b
348−foldrM step acc m = go (toStream m)
352+foldrM step acc m = go m
349353 where
350354 go m1 =
351355 let stop = return acc
352356 single a = step a acc
353357 yieldk a r = go r >>= step a
354− in unStream m1 defState stop single yieldk
358+ in foldStream defState stop single yieldk m1
355359
356360{-# INLINE foldr1 #-}
357361foldr1 :: (IsStream t, Monad m) => (a -> a -> a) -> t m a -> m (Maybe a)
@@ -359,13 +363,13 @@ foldr1 step m = do
359363 r <- uncons m
360364 case r of
361365 Nothing -> return Nothing
362− Just (h, t) -> fmap Just (go h (toStream t))
366+ Just (h, t) -> fmap Just (go h t)
363367 where
364368 go p m1 =
365369 let stp = return p
366370 single a = return $ step a p
367371 yieldk a r = fmap (step p) (go a r)
368− in unStream m1 defState stp single yieldk
372+ in foldStream defState stp single yieldk m1
369373
370374-- | Strict left fold with an extraction function. Like the standard strict
371375-- left fold, but applies a user supplied extraction function (the third
@@ -374,28 +378,31 @@ foldr1 step m = do
374378--
375379-- Note that the accumulator is always evaluated including the initial value.
376380{-# INLINE foldx #-}
377−foldx :: (IsStream t, Monad m)
381+foldx :: forall t m a b x. (IsStream t, Monad m)
378382 => (x -> a -> x) -> x -> (x -> b) -> t m a -> m b
379−foldx step begin done m = get $ go (toStream m) begin
383+foldx step begin done m = get $ go m begin
380384 where
381385 {-# NOINLINE get #-}
386+ get :: t m x -> m b
382387 get m1 =
383388 -- XXX we are not strictly evaluating the accumulator here. Is this
384389 -- okay?
385390 let single = return . done
386− in unStreamShared m1 undefined undefined single undefined
391+ -- XXX this is foldSingleton. why foldStreamShared?
392+ in foldStreamShared undefined undefined single undefined m1
387393
388394 -- Note, this can be implemented by making a recursive call to "go",
389395 -- however that is more expensive because of unnecessary recursion
390396 -- that cannot be tail call optimized. Unfolding recursion explicitly via
391397 -- continuations is much more efficient.
398+ go :: t m a -> x -> t m x
392399 go m1 !acc = mkStream $ \_ _ sng yld ->
393400 let stop = sng acc
394401 single a = sng $ step acc a
395− yieldk a r =
396− let stream = go r (step acc a)
397− in unStream stream defState undefined sng yld
398− in unStream m1 defState stop single yieldk
402+ -- XXX this is foldNonEmptyStream
403+ yieldk a r = foldStream defState undefined sng yld $
404+ go r (step acc a)
405+ in foldStream defState stop single yieldk m1
399406
400407-- | Strict left associative fold.
401408{-# INLINE foldl' #-}
@@ -406,13 +413,13 @@ foldl' step begin = foldx step begin id
406413-- | Like 'foldx', but with a monadic step function.
407414foldxM :: (IsStream t, Monad m)
408415 => (x -> a -> m x) -> m x -> (x -> m b) -> t m a -> m b
409−foldxM step begin done m = go begin (toStream m)
416+foldxM step begin done m = go begin m
410417 where
411418 go !acc m1 =
412419 let stop = acc >>= done
413420 single a = acc >>= \b -> step b a >>= done
414421 yieldk a r = acc >>= \b -> step b a >>= \x -> go (return x) r
415− in unStream m1 defState stop single yieldk
422+ in foldStream defState stop single yieldk m1
416423
417424-- | Like 'foldl'' but with a monadic step function.
418425foldlM' :: (IsStream t, Monad m) => (b -> a -> m b) -> b -> t m a -> m b
@@ -424,13 +431,13 @@ foldlM' step begin = foldxM step (return begin) return
424431
425432{-# INLINE runStream #-}
426433runStream :: (Monad m, IsStream t) => t m a -> m ()
427−runStream m = go (toStream m)
434+runStream = go
428435 where
429436 go m1 =
430437 let stop = return ()
431438 single _ = return ()
432− yieldk _ r = go (toStream r)
433− in unStream m1 defState stop single yieldk
439+ yieldk _ r = go r
440+ in foldStream defState stop single yieldk m1
434441
435442{-# INLINE null #-}
436443null :: (IsStream t, Monad m) => t m a -> m Bool
@@ -438,7 +445,7 @@ null m =
438445 let stop = return True
439446 single _ = return False
440447 yieldk _ _ = return False
441− in unStream (toStream m) defState stop single yieldk
448+ in foldStream defState stop single yieldk m
442449
443450{-# INLINE head #-}
444451head :: (IsStream t, Monad m) => t m a -> m (Maybe a)
@@ -446,69 +453,69 @@ head m =
446453 let stop = return Nothing
447454 single a = return (Just a)
448455 yieldk a _ = return (Just a)
449− in unStream (toStream m) defState stop single yieldk
456+ in foldStream defState stop single yieldk m
450457
451458{-# INLINE tail #-}
452459tail :: (IsStream t, Monad m) => t m a -> m (Maybe (t m a))
453460tail m =
454461 let stop = return Nothing
455462 single _ = return $ Just nil
456− yieldk _ r = return $ Just $ fromStream r
457− in unStream (toStream m) defState stop single yieldk
463+ yieldk _ r = return $ Just r
464+ in foldStream defState stop single yieldk m
458465
459466{-# INLINE init #-}
460467init :: (IsStream t, Monad m) => t m a -> m (Maybe (t m a))
461−init m = go1 (toStream m)
468+init m = go1 m
462469 where
463470 go1 m1 = do
464471 r <- uncons m1
465472 case r of
466473 Nothing -> return Nothing
467− Just (h, t) -> return . Just . fromStream $ go h t
474+ Just (h, t) -> return . Just $ go h t
468475 go p m1 = mkStream $ \_ stp sng yld ->
469476 let single _ = sng p
470477 yieldk a x = yld p $ go a x
471− in unStream m1 defState stp single yieldk
478+ in foldStream defState stp single yieldk m1
472479
473480{-# INLINE elem #-}
474481elem :: (IsStream t, Monad m, Eq a) => a -> t m a -> m Bool
475−elem e m = go (toStream m)
482+elem e m = go m
476483 where
477484 go m1 =
478485 let stop = return False
479486 single a = return (a == e)
480487 yieldk a r = if a == e then return True else go r
481− in unStream m1 defState stop single yieldk
488+ in foldStream defState stop single yieldk m1
482489
483490{-# INLINE notElem #-}
484491notElem :: (IsStream t, Monad m, Eq a) => a -> t m a -> m Bool
485−notElem e m = go (toStream m)
492+notElem e m = go m
486493 where
487494 go m1 =
488495 let stop = return True
489496 single a = return (a /= e)
490497 yieldk a r = if a == e then return False else go r
491− in unStream m1 defState stop single yieldk
498+ in foldStream defState stop single yieldk m1
492499
493500all :: (IsStream t, Monad m) => (a -> Bool) -> t m a -> m Bool
494−all p m = go (toStream m)
501+all p m = go m
495502 where
496503 go m1 =
497504 let single a | p a = return True
498505 | otherwise = return False
499506 yieldk a r | p a = go r
500507 | otherwise = return False
501− in unStream m1 defState (return True) single yieldk
508+ in foldStream defState (return True) single yieldk m1
502509
503510any :: (IsStream t, Monad m) => (a -> Bool) -> t m a -> m Bool
504−any p m = go (toStream m)
511+any p m = go m
505512 where
506513 go m1 =
507514 let single a | p a = return True
508515 | otherwise = return False
509516 yieldk a r | p a = return True
510517 | otherwise = go r
511− in unStream m1 defState (return False) single yieldk
518+ in foldStream defState (return False) single yieldk m1
512519
513520-- | Extract the last element of the stream, if any.
514521{-# INLINE last #-}
@@ -517,13 +524,13 @@ last = foldx (\_ y -> Just y) Nothing id
517524
518525{-# INLINE minimum #-}
519526minimum :: (IsStream t, Monad m, Ord a) => t m a -> m (Maybe a)
520−minimum m = go Nothing (toStream m)
527+minimum m = go Nothing m
521528 where
522529 go Nothing m1 =
523530 let stop = return Nothing
524531 single a = return (Just a)
525532 yieldk a r = go (Just a) r
526− in unStream m1 defState stop single yieldk
533+ in foldStream defState stop single yieldk m1
527534
528535 go (Just res) m1 =
529536 let stop = return (Just res)
@@ -535,19 +542,19 @@ minimum m = go Nothing (toStream m)
535542 if res <= a
536543 then go (Just res) r
537544 else go (Just a) r
538− in unStream m1 defState stop single yieldk
545+ in foldStream defState stop single yieldk m1
539546
540547{-# INLINE minimumBy #-}
541548minimumBy
542549 :: (IsStream t, Monad m)
543550 => (a -> a -> Ordering) -> t m a -> m (Maybe a)
544−minimumBy cmp m = go Nothing (toStream m)
551+minimumBy cmp m = go Nothing m
545552 where
546553 go Nothing m1 =
547554 let stop = return Nothing
548555 single a = return (Just a)
549556 yieldk a r = go (Just a) r
550− in unStream m1 defState stop single yieldk
557+ in foldStream defState stop single yieldk m1
551558
552559 go (Just res) m1 =
553560 let stop = return (Just res)
@@ -557,17 +564,17 @@ minimumBy cmp m = go Nothing (toStream m)
557564 yieldk a r = case cmp res a of
558565 GT -> go (Just a) r
559566 _ -> go (Just res) r
560− in unStream m1 defState stop single yieldk
567+ in foldStream defState stop single yieldk m1
561568
562569{-# INLINE maximum #-}
563570maximum :: (IsStream t, Monad m, Ord a) => t m a -> m (Maybe a)
564−maximum m = go Nothing (toStream m)
571+maximum m = go Nothing m
565572 where
566573 go Nothing m1 =
567574 let stop = return Nothing
568575 single a = return (Just a)
569576 yieldk a r = go (Just a) r
570− in unStream m1 defState stop single yieldk
577+ in foldStream defState stop single yieldk m1
571578
572579 go (Just res) m1 =
573580 let stop = return (Just res)
@@ -579,17 +586,17 @@ maximum m = go Nothing (toStream m)
579586 if res <= a
580587 then go (Just a) r
581588 else go (Just res) r
582− in unStream m1 defState stop single yieldk
589+ in foldStream defState stop single yieldk m1
583590
584591{-# INLINE maximumBy #-}
585592maximumBy :: (IsStream t, Monad m) => (a -> a -> Ordering) -> t m a -> m (Maybe a)
586−maximumBy cmp m = go Nothing (toStream m)
593+maximumBy cmp m = go Nothing m
587594 where
588595 go Nothing m1 =
589596 let stop = return Nothing
590597 single a = return (Just a)
591598 yieldk a r = go (Just a) r
592− in unStream m1 defState stop single yieldk
599+ in foldStream defState stop single yieldk m1
593600
594601 go (Just res) m1 =
595602 let stop = return (Just res)
@@ -599,11 +606,11 @@ maximumBy cmp m = go Nothing (toStream m)
599606 yieldk a r = case cmp res a of
600607 GT -> go (Just res) r
601608 _ -> go (Just a) r
602− in unStream m1 defState stop single yieldk
609+ in foldStream defState stop single yieldk m1
603610
604611{-# INLINE (!!) #-}
605612(!!) :: (IsStream t, Monad m) => t m a -> Int -> m (Maybe a)
606−m !! i = go i (toStream m)
613+m !! i = go i m
607614 where
608615 go n m1 =
609616 let single a | n == 0 = return $ Just a
@@ -611,22 +618,22 @@ m !! i = go i (toStream m)
611618 yieldk a x | n < 0 = return Nothing
612619 | n == 0 = return $ Just a
613620 | otherwise = go (n - 1) x
614− in unStream m1 defState (return Nothing) single yieldk
621+ in foldStream defState (return Nothing) single yieldk m1
615622
616623{-# INLINE lookup #-}
617624lookup :: (IsStream t, Monad m, Eq a) => a -> t m (a, b) -> m (Maybe b)
618−lookup e m = go (toStream m)
625+lookup e m = go m
619626 where
620627 go m1 =
621628 let single (a, b) | a == e = return $ Just b
622629 | otherwise = return Nothing
623630 yieldk (a, b) x | a == e = return $ Just b
624631 | otherwise = go x
625− in unStream m1 defState (return Nothing) single yieldk
632+ in foldStream defState (return Nothing) single yieldk m1
626633
627634{-# INLINE findM #-}
628635findM :: (IsStream t, Monad m) => (a -> m Bool) -> t m a -> m (Maybe a)
629−findM p m = go (toStream m)
636+findM p m = go m
630637 where
631638 go m1 =
632639 let single a = do
@@ -635,7 +642,7 @@ findM p m = go (toStream m)
635642 yieldk a x = do
636643 b <- p a
637644 if b then return $ Just a else go x
638− in unStream m1 defState (return Nothing) single yieldk
645+ in foldStream defState (return Nothing) single yieldk m1
639646
640647{-# INLINE find #-}
641648find :: (IsStream t, Monad m) => (a -> Bool) -> t m a -> m (Maybe a)
@@ -643,14 +650,15 @@ find p = findM (return . p)
643650
644651{-# INLINE findIndices #-}
645652findIndices :: IsStream t => (a -> Bool) -> t m a -> t m Int
646−findIndices p = fromStream . go 0 . toStream
653+findIndices p = go 0
647654 where
648655 go offset m1 = mkStream $ \st stp sng yld ->
649656 let single a | p a = sng offset
650657 | otherwise = stp
651658 yieldk a x | p a = yld offset $ go (offset + 1) x
652− | otherwise = unStream (go (offset + 1) x) st stp sng yld
653− in unStream m1 st stp single yieldk
659+ | otherwise = foldStream (adaptState st) stp sng yld $
660+ go (offset + 1) x
661+ in foldStream (adaptState st) stp single yieldk m1
654662
655663------------------------------------------------------------------------------
656664-- Map and Fold
@@ -659,13 +667,13 @@ findIndices p = fromStream . go 0 . toStream
659667-- | Apply a monadic action to each element of the stream and discard the
660668-- output of the action.
661669mapM_ :: (IsStream t, Monad m) => (a -> m b) -> t m a -> m ()
662−mapM_ f m = go (toStream m)
670+mapM_ f m = go m
663671 where
664672 go m1 =
665673 let stop = return ()
666674 single a = void (f a)
667675 yieldk a r = f a >> go r
668− in unStream m1 defState stop single yieldk
676+ in foldStream defState stop single yieldk m1
669677
670678------------------------------------------------------------------------------
671679-- Converting folds
@@ -686,14 +694,14 @@ toStreamK = id
686694{-# INLINE scanx #-}
687695scanx :: IsStream t => (x -> a -> x) -> x -> (x -> b) -> t m a -> t m b
688696scanx step begin done m =
689− cons (done begin) $ fromStream $ go (toStream m) begin
697+ cons (done begin) $ go m begin
690698 where
691699 go m1 !acc = mkStream $ \st stp sng yld ->
692700 let single a = sng (done $ step acc a)
693701 yieldk a r =
694702 let s = step acc a
695703 in yld (done s) (go r s)
696− in unStream m1 st stp single yieldk
704+ in foldStream (adaptState st) stp single yieldk m1
697705
698706{-# INLINE scanl' #-}
699707scanl' :: IsStream t => (b -> a -> b) -> b -> t m a -> t m b
@@ -705,58 +713,58 @@ scanl' step begin = scanx step begin id
705713
706714{-# INLINE filter #-}
707715filter :: IsStream t => (a -> Bool) -> t m a -> t m a
708−filter p m = fromStream $ go (toStream m)
716+filter p m = go m
709717 where
710718 go m1 = mkStream $ \st stp sng yld ->
711719 let single a | p a = sng a
712720 | otherwise = stp
713721 yieldk a r | p a = yld a (go r)
714− | otherwise = unStream r st stp single yieldk
715− in unStream m1 st stp single yieldk
722+ | otherwise = foldStream st stp single yieldk r
723+ in foldStream st stp single yieldk m1
716724
717725{-# INLINE take #-}
718726take :: IsStream t => Int -> t m a -> t m a
719−take n m = fromStream $ go n (toStream m)
727+take n m = go n m
720728 where
721729 go n1 m1 = mkStream $ \st stp sng yld ->
722730 let yieldk a r = yld a (go (n1 - 1) r)
723731 in if n1 <= 0
724732 then stp
725− else unStream m1 st stp sng yieldk
733+ else foldStream st stp sng yieldk m1
726734
727735{-# INLINE takeWhile #-}
728736takeWhile :: IsStream t => (a -> Bool) -> t m a -> t m a
729−takeWhile p m = fromStream $ go (toStream m)
737+takeWhile p m = go m
730738 where
731739 go m1 = mkStream $ \st stp sng yld ->
732740 let single a | p a = sng a
733741 | otherwise = stp
734742 yieldk a r | p a = yld a (go r)
735743 | otherwise = stp
736− in unStream m1 st stp single yieldk
744+ in foldStream st stp single yieldk m1
737745
738746drop :: IsStream t => Int -> t m a -> t m a
739−drop n m = fromStream $ mkStream $ \st stp sng yld ->
740− unStream (go n (toStream m)) st stp sng yld
747+drop n m = mkStream $ \st stp sng yld ->
748+ foldStream st stp sng yld $ go n m
741749 where
742750 go n1 m1 = mkStream $ \st stp sng yld ->
743751 let single _ = stp
744− yieldk _ r = (unStream $ go (n1 - 1) r) st stp sng yld
752+ yieldk _ r = foldStream st stp sng yld $ go (n1 - 1) r
745753 -- Somehow "<=" check performs better than a ">"
746754 in if n1 <= 0
747− then unStream m1 st stp sng yld
748− else unStream m1 st stp single yieldk
755+ then foldStream st stp sng yld m1
756+ else foldStream st stp single yieldk m1
749757
750758{-# INLINE dropWhile #-}
751759dropWhile :: IsStream t => (a -> Bool) -> t m a -> t m a
752−dropWhile p m = fromStream $ go (toStream m)
760+dropWhile p m = go m
753761 where
754762 go m1 = mkStream $ \st stp sng yld ->
755763 let single a | p a = stp
756764 | otherwise = sng a
757− yieldk a r | p a = unStream r st stp single yieldk
765+ yieldk a r | p a = foldStream st stp single yieldk r
758766 | otherwise = yld a r
759− in unStream m1 st stp single yieldk
767+ in foldStream st stp single yieldk m1
760768
761769-------------------------------------------------------------------------------
762770-- Mapping
@@ -766,23 +774,23 @@ dropWhile p m = fromStream $ go (toStream m)
766774-- other stream types to overload it.
767775{-# INLINE mapM #-}
768776mapM :: (IsStream t, MonadAsync m) => (a -> m b) -> t m a -> t m b
769−mapM f m = go (toStream m)
777+mapM f m = go m
770778 where
771− go m1 = fromStream $ mkStream $ \st stp sng yld ->
779+ go m1 = mkStream $ \st stp sng yld ->
772780 let single a = f a >>= sng
773− yieldk a r = unStreamShared (toStream (f a |: go r)) st stp sng yld
774− in unStream m1 st stp single yieldk
781+ yieldk a r = foldStreamShared st stp sng yld $ f a |: go r
782+ in foldStream (adaptState st) stp single yieldk m1
775783
776784-- Be careful when modifying this, this uses a consM (|:) deliberately to allow
777785-- other stream types to overload it.
778786{-# INLINE sequence #-}
779787sequence :: (IsStream t, MonadAsync m) => t m (m a) -> t m a
780−sequence m = go (toStream m)
788+sequence m = go m
781789 where
782− go m1 = fromStream $ mkStream $ \st stp sng yld ->
790+ go m1 = mkStream $ \st stp sng yld ->
783791 let single ma = ma >>= sng
784− yieldk ma r = unStreamShared (toStream $ ma |: go r) st stp sng yld
785− in unStream m1 st stp single yieldk
792+ yieldk ma r = foldStreamShared st stp sng yld $ ma |: go r
793+ in foldStream (adaptState st) stp single yieldk m1
786794
787795-------------------------------------------------------------------------------
788796-- Inserting
@@ -790,19 +798,19 @@ sequence m = go (toStream m)
790798
791799{-# INLINE intersperseM #-}
792800intersperseM :: (IsStream t, MonadAsync m) => m a -> t m a -> t m a
793−intersperseM a m = fromStream $ prependingStart (toStream m)
801+intersperseM a m = prependingStart m
794802 where
795803 prependingStart m1 = mkStream $ \st stp sng yld ->
796− let yieldk i x = unStreamShared (return i |: go x) st stp sng yld
797− in unStream m1 st stp sng yieldk
798− go m2 = fromStream $ mkStream $ \st stp sng yld ->
799− let single i = unStreamShared (a |: yield i) st stp sng yld
800− yieldk i x = unStreamShared (a |: return i |: go x) st stp sng yld
801− in unStream m2 st stp single yieldk
804+ let yieldk i x = foldStreamShared st stp sng yld $ return i |: go x
805+ in foldStream st stp sng yieldk m1
806+ go m2 = mkStream $ \st stp sng yld ->
807+ let single i = foldStreamShared st stp sng yld $ a |: yield i
808+ yieldk i x = foldStreamShared st stp sng yld $ a |: return i |: go x
809+ in foldStream st stp single yieldk m2
802810
803811{-# INLINE insertBy #-}
804812insertBy :: IsStream t => (a -> a -> Ordering) -> a -> t m a -> t m a
805−insertBy cmp x m = fromStream $ go (toStream m)
813+insertBy cmp x m = go m
806814 where
807815 go m1 = mkStream $ \st _ _ yld ->
808816 let single a = case cmp x a of
@@ -812,7 +820,7 @@ insertBy cmp x m = fromStream $ go (toStream m)
812820 yieldk a r = case cmp x a of
813821 GT -> yld a (go r)
814822 _ -> yld x (a `cons` r)
815− in unStream m1 st stop single yieldk
823+ in foldStream st stop single yieldk m1
816824
817825------------------------------------------------------------------------------
818826-- Deleting
@@ -820,14 +828,14 @@ insertBy cmp x m = fromStream $ go (toStream m)
820828
821829{-# INLINE deleteBy #-}
822830deleteBy :: IsStream t => (a -> a -> Bool) -> a -> t m a -> t m a
823−deleteBy eq x m = fromStream $ go (toStream m)
831+deleteBy eq x m = go m
824832 where
825833 go m1 = mkStream $ \st stp sng yld ->
826834 let single a = if eq x a then stp else sng a
827835 yieldk a r = if eq x a
828− then unStream r st stp sng yld
836+ then foldStream st stp sng yld r
829837 else yld a (go r)
830− in unStream m1 st stp single yieldk
838+ in foldStream st stp single yieldk m1
831839
832840-------------------------------------------------------------------------------
833841-- Map and Filter
@@ -835,70 +843,66 @@ deleteBy eq x m = fromStream $ go (toStream m)
835843
836844{-# INLINE mapMaybe #-}
837845mapMaybe :: IsStream t => (a -> Maybe b) -> t m a -> t m b
838−mapMaybe f m = go (toStream m)
846+mapMaybe f m = go m
839847 where
840− go m1 = fromStream $ mkStream $ \st stp sng yld ->
848+ go m1 = mkStream $ \st stp sng yld ->
841849 let single a = case f a of
842850 Just b -> sng b
843851 Nothing -> stp
844852 yieldk a r = case f a of
845− Just b -> yld b (toStream $ go r)
846− Nothing -> unStream r st stp single yieldk
847− in unStream m1 st stp single yieldk
853+ Just b -> yld b $ go r
854+ Nothing -> foldStream (adaptState st) stp single yieldk r
855+ in foldStream (adaptState st) stp single yieldk m1
848856
849857------------------------------------------------------------------------------
850858-- Serial Zipping
851859------------------------------------------------------------------------------
852860
853−{-# INLINE zipWithS #-}
854−zipWithS :: (a -> b -> c) -> Stream m a -> Stream m b -> Stream m c
855−zipWithS f = go
861+-- | Zip two streams serially using a pure zipping function.
862+--
863+-- @since 0.1.0
864+{-# INLINABLE zipWith #-}
865+zipWith :: IsStream t => (a -> b -> c) -> t m a -> t m b -> t m c
866+zipWith f = go
856867 where
857868 go mx my = mkStream $ \st stp sng yld -> do
858869 let merge a ra =
859870 let single2 b = sng (f a b)
860871 yield2 b rb = yld (f a b) (go ra rb)
861− in unStream my st stp single2 yield2
872+ in foldStream (adaptState st) stp single2 yield2 my
862873 let single1 a = merge a nil
863874 yield1 = merge
864− unStream mx st stp single1 yield1
865−
866−-- | Zip two streams serially using a pure zipping function.
867−--
868−-- @since 0.1.0
869−{-# INLINABLE zipWith #-}
870−zipWith :: IsStream t => (a -> b -> c) -> t m a -> t m b -> t m c
871−zipWith f m1 m2 = fromStream $ zipWithS f (toStream m1) (toStream m2)
875+ foldStream (adaptState st) stp single1 yield1 mx
872876
873877-- | Zip two streams serially using a monadic zipping function.
874878--
875879-- @since 0.1.0
876880zipWithM :: (IsStream t, Monad m) => (a -> b -> m c) -> t m a -> t m b -> t m c
877−zipWithM f m1 m2 = fromStream $ go (toStream m1) (toStream m2)
881+zipWithM f m1 m2 = go m1 m2
878882 where
879883 go mx my = mkStream $ \st stp sng yld -> do
880884 let merge a ra =
881− let runIt x = unStream x st stp sng yld
885+ let runIt x = foldStream st stp sng yld x
882886 single2 b = f a b >>= sng
883887 yield2 b rb = f a b >>= \x -> runIt (x `cons` go ra rb)
884− in unStream my st stp single2 yield2
888+ in foldStream (adaptState st) stp single2 yield2 my
885889 let single1 a = merge a nil
886890 yield1 = merge
887− unStream mx st stp single1 yield1
891+ foldStream (adaptState st) stp single1 yield1 mx
888892
889893------------------------------------------------------------------------------
890894-- Merging
891895------------------------------------------------------------------------------
892896
893−{-# INLINE mergeByS #-}
894−mergeByS
895− :: Monad m
896− => (a -> a -> m Ordering) -> Stream m a -> Stream m a -> Stream m a
897−mergeByS cmp = go
897+{-# INLINE mergeByM #-}
898+mergeByM
899+ :: (IsStream t, Monad m)
900+ => (a -> a -> m Ordering) -> t m a -> t m a -> t m a
901+mergeByM cmp = go
898902 where
899903 go mx my = mkStream $ \st stp sng yld -> do
900904 let mergeWithY a ra =
901− let stop2 = unStream mx st stp sng yld
905+ let stop2 = foldStream st stp sng yld mx
902906 single2 b = do
903907 r <- cmp a b
904908 case r of
@@ -909,17 +913,11 @@ mergeByS cmp = go
909913 case r of
910914 GT -> yld b (go (a `cons` ra) rb)
911915 _ -> yld a (go ra (b `cons` rb))
912− in unStream my st stop2 single2 yield2
913− let stopX = unStream my st stp sng yld
916+ in foldStream st stop2 single2 yield2 my
917+ let stopX = foldStream st stp sng yld my
914918 singleX a = mergeWithY a nil
915919 yieldX = mergeWithY
916− unStream mx st stopX singleX yieldX
917−
918−{-# INLINABLE mergeByM #-}
919−mergeByM
920− :: (IsStream t, Monad m)
921− => (a -> a -> m Ordering) -> t m a -> t m a -> t m a
922−mergeByM f m1 m2 = fromStream $ mergeByS f (toStream m1) (toStream m2)
920+ foldStream st stopX singleX yieldX mx
923921
924922{-# INLINABLE mergeBy #-}
925923mergeBy
@@ -937,14 +935,14 @@ the m = do
937935 r <- uncons m
938936 case r of
939937 Nothing -> return Nothing
940− Just (h, t) -> go h (toStream t)
938+ Just (h, t) -> go h t
941939 where
942940 go h m1 =
943941 let single a | h == a = return $ Just h
944942 | otherwise = return Nothing
945943 yieldk a r | h == a = go h r
946944 | otherwise = return Nothing
947− in unStream m1 defState (return $ Just h) single yieldk
945+ in foldStream defState (return $ Just h) single yieldk m1
948946
949947-------------------------------------------------------------------------------
950948-- Bind utility
@@ -952,20 +950,19 @@ the m = do
952950
953951{-# INLINE bindWith #-}
954952bindWith
955− :: (forall c. Stream m c -> Stream m c -> Stream m c)
956− -> Stream m a
957− -> (a -> Stream m b)
958− -> Stream m b
953+ :: IsStream t
954+ => (forall c. t m c -> t m c -> t m c)
955+ -> t m a
956+ -> (a -> t m b)
957+ -> t m b
959958bindWith par m1 f = go m1
960959 where
961960 go m =
962961 mkStream $ \st stp sng yld ->
963− let runShared x = unStreamShared x st stp sng yld
964− runIsolated x = unStream x st stp sng yld
965−
966− single a = runIsolated $ f a
967− yieldk a r = runShared $ unShare (f a) `par` go r
968− in unStream m st stp single yieldk
962+ let foldShared = foldStreamShared st stp sng yld
963+ single a = foldShared $ unShare (f a)
964+ yieldk a r = foldShared $ unShare (f a) `par` go r
965+ in foldStream (adaptState st) stp single yieldk m
969966
970967------------------------------------------------------------------------------
971968-- Alternative & MonadPlus
@@ -973,8 +970,8 @@ bindWith par m1 f = go m1
973970
974971_alt :: Stream m a -> Stream m a -> Stream m a
975972_alt m1 m2 = mkStream $ \st stp sng yld ->
976− let stop = unStream m2 st stp sng yld
977− in unStream m1 st stop sng yld
973+ let stop = foldStream st stp sng yld m2
974+ in foldStream st stop sng yld m1
978975
979976------------------------------------------------------------------------------
980977-- MonadReader
@@ -985,7 +982,7 @@ withLocal f m =
985982 mkStream $ \st stp sng yld ->
986983 let single = local f . sng
987984 yieldk a r = local f $ yld a (withLocal f r)
988− in unStream m st (local f stp) single yieldk
985+ in foldStream st (local f stp) single yieldk m
989986
990987------------------------------------------------------------------------------
991988-- MonadError
@@ -1003,4 +1000,3 @@ withCatchError m h =
10031000 yieldk a r = yld a (withCatchError r h)
10041001 in handle $ run m
10051002-}
1006−
src/Streamly/Streams/StreamKType.hs+132−109
@@ -31,22 +31,23 @@ module Streamly.Streams.StreamKType
3131
3232 -- * The stream type
3333 , Stream ()
34− , Streaming
3534
3635 -- * Construction
37− , consMSerial
3836 , mkStream
3937
4038 -- * Elimination
41− , unStream
42− , unStreamShared
4339 , foldStream
44− , runStreamSVar
40+ , foldStreamShared
41+ , foldStreamSVar
4542
43+ -- instances
44+ , consMSerial
4645 , nil
4746 , serial
4847 , map
4948 , yieldM
49+
50+ , Streaming -- deprecated
5051 )
5152where
5253
@@ -58,36 +59,6 @@ import Prelude hiding (map)
5859
5960import Streamly.SVar
6061
61−------------------------------------------------------------------------------
62−-- The basic stream type
63−------------------------------------------------------------------------------
64−
65−-- | The type @Stream m a@ represents a monadic stream of values of type 'a'
66−-- constructed using actions in monad 'm'. It uses stop, singleton and yield
67−-- continuations equivalent to the following direct style type:
68−--
69−-- @
70−-- data Stream m a = Stop | Singleton a | Yield a (Stream m a)
71−-- @
72−--
73−-- To facilitate parallel composition we maintain a local state in an 'SVar'
74−-- that is shared across and is used for synchronization of the streams being
75−-- composed.
76−--
77−-- The singleton case can be expressed in terms of stop and yield but we have
78−-- it as a separate case to optimize composition operations for streams with
79−-- single element. We build singleton streams in the implementation of 'pure'
80−-- for Applicative and Monad, and in 'lift' for MonadTrans.
81−--
82−newtype Stream m a =
83− MkStream (forall r.
84− State Stream m a -- state
85− -> m r -- stop
86− -> (a -> m r) -- singleton
87− -> (a -> Stream m a -> m r) -- yield
88− -> m r
89− )
90−
9162------------------------------------------------------------------------------
9263-- Types that can behave as a Stream
9364------------------------------------------------------------------------------
@@ -95,6 +66,9 @@ newtype Stream m a =
9566infixr 5 `consM`
9667infixr 5 |:
9768
69+-- XXX Use a different SVar based on the stream type. But we need to make sure
70+-- that we do not lose performance due to polymorphism.
71+--
9872-- | Class of types that can represent a stream of elements of some type 'a' in
9973-- some monad 'm'.
10074--
@@ -149,42 +123,64 @@ type Streaming = IsStream
149123-- Type adapting combinators
150124-------------------------------------------------------------------------------
151125
126+-- XXX Move/reset the State here by reconstructing the stream with cleared
127+-- state. Can we make sure we do not do that when t1 = t2? If we do this then
128+-- we do not need to do that explicitly using svarStyle. It would act as
129+-- unShare when the stream type is the same.
130+--
152131-- | Adapt any specific stream type to any other specific stream type.
153132--
154133-- @since 0.1.0
155134adapt :: (IsStream t1, IsStream t2) => t1 m a -> t2 m a
156135adapt = fromStream . toStream
157136
158−-------------------------------------------------------------------------------
159−-- Instances
160−-------------------------------------------------------------------------------
161−
162−{-# INLINE consMSerial #-}
163−consMSerial :: (Monad m) => m a -> Stream m a -> Stream m a
164−consMSerial m r = MkStream $ \_ _ _ yld -> m >>= \a -> yld a r
165−
166−-------------------------------------------------------------------------------
167−-- IsStream Stream
168−-------------------------------------------------------------------------------
169−
170−instance IsStream Stream where
171− toStream = id
172− fromStream = id
173−
174− {-# INLINE consM #-}
175− {-# SPECIALIZE consM :: IO a -> Stream IO a -> Stream IO a #-}
176− consM :: Monad m => m a -> Stream m a -> Stream m a
177− consM = consMSerial
137+------------------------------------------------------------------------------
138+-- Basic stream type
139+------------------------------------------------------------------------------
178140
179− {-# INLINE (|:) #-}
180− {-# SPECIALIZE (|:) :: IO a -> Stream IO a -> Stream IO a #-}
181− (|:) :: Monad m => m a -> Stream m a -> Stream m a
182− (|:) = consMSerial
141+-- | The type @Stream m a@ represents a monadic stream of values of type 'a'
142+-- constructed using actions in monad 'm'. It uses stop, singleton and yield
143+-- continuations equivalent to the following direct style type:
144+--
145+-- @
146+-- data Stream m a = Stop | Singleton a | Yield a (Stream m a)
147+-- @
148+--
149+-- To facilitate parallel composition we maintain a local state in an 'SVar'
150+-- that is shared across and is used for synchronization of the streams being
151+-- composed.
152+--
153+-- The singleton case can be expressed in terms of stop and yield but we have
154+-- it as a separate case to optimize composition operations for streams with
155+-- single element. We build singleton streams in the implementation of 'pure'
156+-- for Applicative and Monad, and in 'lift' for MonadTrans.
157+--
158+-- XXX remove the Stream type parameter from State as it is always constant.
159+-- We can remove it from SVar as well
160+--
161+newtype Stream m a =
162+ MkStream (forall r.
163+ State Stream m a -- state
164+ -> m r -- stop
165+ -> (a -> m r) -- singleton
166+ -> (a -> Stream m a -> m r) -- yield
167+ -> m r
168+ )
183169
184170------------------------------------------------------------------------------
185171-- Building a stream
186172------------------------------------------------------------------------------
187173
174+-- XXX The State is always parameterized by "Stream" which means State is not
175+-- different for different stream types. So we have to manually make sure that
176+-- when converting from one stream to another we migrate the state correctly.
177+-- This can be fixed if we use a different SVar type for different streams.
178+-- Currently we always use "SVar Stream" and therefore a different State type
179+-- parameterized by that stream.
180+--
181+-- XXX change the order of arguments to match the standard fold function
182+-- convention i.e. st yield single stop.
183+--
188184-- | Build a stream from an 'SVar', a stop continuation, a singleton stream
189185-- continuation and a yield continuation.
190186mkStream:: IsStream t
@@ -198,45 +194,31 @@ mkStream k = fromStream $ MkStream $ \st stp sng yld ->
198194 let yieldk a r = yld a (toStream r)
199195 in k st stp sng yieldk
200196
201−-- | An empty stream.
202−--
203−-- @
204−-- > toList nil
205−-- []
206−-- @
207−--
208−-- @since 0.1.0
209−nil :: IsStream t => t m a
210−nil = fromStream $ mkStream $ \_ stp _ _ -> stp
211−
212197------------------------------------------------------------------------------
213198-- Folding a stream
214199------------------------------------------------------------------------------
215200
216−-- Run a stream in detached mode i.e. not joining an SVar
217−{-# INLINE unStream #-}
218−unStream ::
219− Stream m a
220− -> State Stream m b -- state
221− -> m r -- stop
222− -> (a -> m r) -- singleton
223− -> (a -> Stream m a -> m r) -- yield
201+-- | Fold a stream by providing an SVar, a stop continuation, a singleton
202+-- continuation and a yield continuation. The stream would share the current
203+-- SVar passed via the State.
204+{-# INLINE foldStreamShared #-}
205+foldStreamShared
206+ :: IsStream t
207+ => State Stream m a
224208 -> m r
225−unStream (MkStream runner) st = runner (adaptState st)
226−
227−-- | Like unstream, but passes a shared SVar across continuations.
228−{-# INLINE unStreamShared #-}
229−unStreamShared ::
230− Stream m a
231− -> State Stream m a -- state
232− -> m r -- stop
233− -> (a -> m r) -- singleton
234− -> (a -> Stream m a -> m r) -- yield
209+ -> (a -> m r)
210+ -> (a -> t m a -> m r)
211+ -> t m a
235212 -> m r
236−unStreamShared (MkStream runner) st stp sng yld = runner st stp sng yld
213+foldStreamShared st stp sng yld m =
214+ let yieldk a x = yld a (fromStream x)
215+ MkStream k = toStream m
216+ in k st stp sng yieldk
237217
238−-- | Fold a stream by providing an SVar, a stop continuation, a singleton
239−-- continuation and a yield continuation.
218+-- | Fold a stream by providing a State, stop continuation, a singleton
219+-- continuation and a yield continuation. The stream will not use the SVar
220+-- passed via State.
221+{-# INLINE foldStream #-}
240222foldStream
241223 :: IsStream t
242224 => State Stream m a
@@ -245,41 +227,71 @@ foldStream
245227 -> (a -> t m a -> m r)
246228 -> t m a
247229 -> m r
248−foldStream st blank single step m =
249− let yieldk a x = step a (fromStream x)
250− in unStreamShared (toStream m) st blank single yieldk
230+foldStream st stp sng yld m =
231+ let yieldk a x = yld a (fromStream x)
232+ MkStream k = toStream m
233+ in k (adaptState st) stp sng yieldk
251234
252235-- Run the stream using a run function associated with the SVar that runs the
253236-- streams with a captured snapshot of the monadic state.
254−{-# INLINE runStreamSVar #-}
255−runStreamSVar
256− :: MonadIO m
237+{-# INLINE foldStreamSVar #-}
238+foldStreamSVar
239+ :: (IsStream t, MonadIO m)
257240 => SVar Stream m a
258− -> Stream m a
259241 -> State Stream m a -- state
260242 -> m r -- stop
261243 -> (a -> m r) -- singleton
262− -> (a -> Stream m a -> m r) -- yield
244+ -> (a -> t m a -> m r) -- yield
245+ -> t m a
263246 -> m ()
264−runStreamSVar sv m st stp sng yld =
247+foldStreamSVar sv st stp sng yld m =
265248 let mrun = runInIO $ svarMrun sv
266− in void $ liftIO $ mrun $ unStreamShared m st stp sng yld
249+ in void $ liftIO $ mrun $ foldStreamShared st stp sng yld m
250+
251+-------------------------------------------------------------------------------
252+-- Instances
253+-------------------------------------------------------------------------------
254+
255+{-# INLINE consMSerial #-}
256+consMSerial :: (IsStream t, Monad m) => m a -> t m a -> t m a
257+consMSerial m r = mkStream $ \_ _ _ yld -> m >>= \a -> yld a r
258+
259+-------------------------------------------------------------------------------
260+-- IsStream Stream
261+-------------------------------------------------------------------------------
262+
263+instance IsStream Stream where
264+ toStream = id
265+ fromStream = id
266+
267+ {-# INLINE consM #-}
268+ {-# SPECIALIZE consM :: IO a -> Stream IO a -> Stream IO a #-}
269+ consM :: Monad m => m a -> Stream m a -> Stream m a
270+ consM = consMSerial
271+
272+ {-# INLINE (|:) #-}
273+ {-# SPECIALIZE (|:) :: IO a -> Stream IO a -> Stream IO a #-}
274+ (|:) :: Monad m => m a -> Stream m a -> Stream m a
275+ (|:) = consMSerial
267276
268277------------------------------------------------------------------------------
269278-- Semigroup
270279------------------------------------------------------------------------------
271280
272−-- | Concatenates two streams sequentially i.e. the first stream is
273−-- exhausted completely before yielding any element from the second stream.
281+-- | Polymorphic version of the 'Semigroup' operation '<>' of 'SerialT'.
282+-- Appends two streams sequentially, yielding all elements from the first
283+-- stream, and then all elements from the second stream.
284+--
285+-- @since 0.2.0
274286{-# INLINE serial #-}
275−serial :: Stream m a -> Stream m a -> Stream m a
287+serial :: IsStream t => t m a -> t m a -> t m a
276288serial m1 m2 = go m1
277289 where
278290 go m = mkStream $ \st stp sng yld ->
279− let stop = unStream m2 st stp sng yld
291+ let stop = foldStream st stp sng yld m2
280292 single a = yld a m2
281293 yieldk a r = yld a (go r)
282− in unStream m st stop single yieldk
294+ in foldStream st stop single yieldk m
283295
284296instance Semigroup (Stream m a) where
285297 (<>) = serial
@@ -288,6 +300,17 @@ instance Semigroup (Stream m a) where
288300-- Monoid
289301------------------------------------------------------------------------------
290302
303+-- | An empty stream.
304+--
305+-- @
306+-- > toList nil
307+-- []
308+-- @
309+--
310+-- @since 0.1.0
311+nil :: IsStream t => t m a
312+nil = mkStream $ \_ stp _ _ -> stp
313+
291314instance Monoid (Stream m a) where
292315 mempty = nil
293316 mappend = (<>)
@@ -299,10 +322,10 @@ instance Monoid (Stream m a) where
299322
300323{-# INLINE map #-}
301324map :: (IsStream t, Monad m) => (a -> b) -> t m a -> t m b
302−map f m = fromStream $ mkStream $ \st stp sng yld ->
325+map f m = mkStream $ \st stp sng yld ->
303326 let single = sng . f
304− yieldk a r = yld (f a) (fmap f r)
305− in unStream (toStream m) st stp single yieldk
327+ yieldk a r = yld (f a) (map f r)
328+ in foldStream (adaptState st) stp single yieldk m
306329
307330instance Monad m => Functor (Stream m) where
308331 fmap = map
src/Streamly/Streams/Zip.hs+10−10
@@ -48,7 +48,7 @@ import Text.Read (Lexeme(Ident), lexP, parens, prec, readPrec, readListPrec,
4848 readListPrecDefault)
4949import Prelude hiding (map, repeat, zipWith)
5050
51−import Streamly.Streams.StreamK (IsStream(..), Stream, mkStream, unStream)
51+import Streamly.Streams.StreamK (IsStream(..), Stream, mkStream, foldStream)
5252import Streamly.Streams.Async (mkAsync')
5353import Streamly.Streams.Serial (map)
5454import Streamly.SVar (MonadAsync, adaptState)
@@ -113,12 +113,12 @@ instance IsStream ZipSerialM where
113113 {-# INLINE consM #-}
114114 {-# SPECIALIZE consM :: IO a -> ZipSerialM IO a -> ZipSerialM IO a #-}
115115 consM :: Monad m => m a -> ZipSerialM m a -> ZipSerialM m a
116− consM m r = fromStream $ K.consMSerial m (toStream r)
116+ consM = K.consMSerial
117117
118118 {-# INLINE (|:) #-}
119119 {-# SPECIALIZE (|:) :: IO a -> ZipSerialM IO a -> ZipSerialM IO a #-}
120120 (|:) :: Monad m => m a -> ZipSerialM m a -> ZipSerialM m a
121− m |: r = fromStream $ K.consMSerial m (toStream r)
121+ (|:) = K.consMSerial
122122
123123LIST_INSTANCES(ZipSerialM)
124124
@@ -127,7 +127,7 @@ instance Monad m => Functor (ZipSerialM m) where
127127
128128instance Monad m => Applicative (ZipSerialM m) where
129129 pure = ZipSerialM . K.repeat
130− m1 <*> m2 = fromStream $ K.zipWith id (toStream m1) (toStream m2)
130+ (<*>) = K.zipWith id
131131
132132FOLDABLE_INSTANCE(ZipSerialM)
133133TRAVERSABLE_INSTANCE(ZipSerialM)
@@ -142,10 +142,10 @@ TRAVERSABLE_INSTANCE(ZipSerialM)
142142-- @since 0.1.0
143143zipAsyncWith :: (IsStream t, MonadAsync m)
144144 => (a -> b -> c) -> t m a -> t m b -> t m c
145−zipAsyncWith f m1 m2 = fromStream $ mkStream $ \st stp sng yld -> do
145+zipAsyncWith f m1 m2 = mkStream $ \st stp sng yld -> do
146146 ma <- mkAsync' (adaptState st) m1
147147 mb <- mkAsync' (adaptState st) m2
148− unStream (toStream (K.zipWith f ma mb)) st stp sng yld
148+ foldStream st stp sng yld (K.zipWith f ma mb)
149149
150150-- | Like 'zipWithM' but zips concurrently i.e. both the streams being zipped
151151-- are generated concurrently.
@@ -153,10 +153,10 @@ zipAsyncWith f m1 m2 = fromStream $ mkStream $ \st stp sng yld -> do
153153-- @since 0.4.0
154154zipAsyncWithM :: (IsStream t, MonadAsync m)
155155 => (a -> b -> m c) -> t m a -> t m b -> t m c
156−zipAsyncWithM f m1 m2 = fromStream $ mkStream $ \st stp sng yld -> do
156+zipAsyncWithM f m1 m2 = mkStream $ \st stp sng yld -> do
157157 ma <- mkAsync' (adaptState st) m1
158158 mb <- mkAsync' (adaptState st) m2
159− unStream (toStream (K.zipWithM f ma mb)) st stp sng yld
159+ foldStream st stp sng yld (K.zipWithM f ma mb)
160160
161161------------------------------------------------------------------------------
162162-- Parallely Zipping Streams
@@ -206,12 +206,12 @@ instance IsStream ZipAsyncM where
206206 {-# INLINE consM #-}
207207 {-# SPECIALIZE consM :: IO a -> ZipAsyncM IO a -> ZipAsyncM IO a #-}
208208 consM :: Monad m => m a -> ZipAsyncM m a -> ZipAsyncM m a
209− consM m r = fromStream $ K.consMSerial m (toStream r)
209+ consM = K.consMSerial
210210
211211 {-# INLINE (|:) #-}
212212 {-# SPECIALIZE (|:) :: IO a -> ZipAsyncM IO a -> ZipAsyncM IO a #-}
213213 (|:) :: Monad m => m a -> ZipAsyncM m a -> ZipAsyncM m a
214− m |: r = fromStream $ K.consMSerial m (toStream r)
214+ (|:) = K.consMSerial
215215
216216instance Monad m => Functor (ZipAsyncM m) where
217217 fmap = map