on master help sign in
Merge pull request #65 from composewell/stream-type

Include singleton as a continuation in stream type

commite1325ad8b17bad3892b72e0d087aba8a21824958 authorHarendra Kumar <harendra.kumar@gmail.com> dateSun 22 Apr 2018, 00:06 (8 years ago) parentac7a4ab66efe33
3 files changed+281−329
src/Streamly/Core.hs+72−113 src/Streamly/Prelude.hs+131−137 src/Streamly/Streams.hs+78−79
src/Streamly/Core.hs+72−113
@@ -25,6 +25,7 @@ module Streamly.Core
2525 , Stream (..)
2626
2727 -- * Construction
28+ , singleton
2829 , cons
2930 , repeat
3031 , nil
@@ -145,91 +146,43 @@ data SVar m a =
145146-- The stream type
146147------------------------------------------------------------------------------
147148
148−-- TBD use a functor instead of the bare type a?
149−
150149-- | The type 'Stream m a' represents a monadic stream of values of type 'a'
151−-- constructed using actions in monad 'm'. It uses a stop continuation and a
152−-- yield continuation. You can consider it a rough equivalent of direct style
153−-- type:
154−--
155−-- data Stream m a = Stop | Yield a (Maybe (Stream m a))
156−--
157−-- Our goal is to be able to represent finite as well as infinite streams and
158−-- being able to compose a large number of small streams efficiently. In
159−-- addition we want to compose streams in parallel, to facilitate that we
160−-- maintain a local state in an SVar that is shared across and is used for
161−-- synchronization of the streams being composed.
162−--
163−-- Using this type, there are two ways to indicate the end of a stream, one is
164−-- by calling the stop continuation and the other one is by yielding the last
165−-- value along with 'Nothing' as the rest of the stream.
166−--
167−-- Why do we have this redundancy? Why can't we use (a -> Stream m a -> m r) as
168−-- the type of the yield continuation and always use the stop continuation to
169−-- indicate the end of the stream? The reason is that when we compose a large
170−-- number of short or singleton streams then using the stop continuation
171−-- becomes expensive, just to know that there is no next element we have to
172−-- call the continuation, introducing an indirection, it seems when using CPS
173−-- GHC is not able to optimize this out as efficiently as it can be in direct
174−-- style because of the function call involved. In direct style it will just be
175−-- a constructor check and a memory access instead of a function call. So we
176−-- could use:
177−--
178−-- data Stream m a = Stop | Yield a (Stream m a)
150+-- constructed using actions in monad 'm'. It uses stop, singleton and yield
151+-- continuations equivalent to the following direct style type:
179152--
180−-- In CPS style, when we use the 'Maybe' argument of yield to indicate the end
181−-- then just like direct style we can figure out that there is no next element
182−-- without a function call.
153+-- data Stream m a = Stop | Singleton a | Yield a (Stream m a)
183154--
184−-- Then why not get rid of the stop continuation and use only yield to indicate
185−-- the end of stream? The answer is, in that case to indicate the end of the
186−-- stream we would have to yield at least one element so there is no way to
187−-- represent an empty stream.
155+-- To facilitate parallel composition we maintain a local state in an SVar that
156+-- is shared across and is used for synchronization of the streams being
157+-- composed.
188158--
189−-- Whenever we make a singleton stream or in general when we build a stream
190−-- strictly i.e. when we know all the elements of the stream in advance we can
191−-- use the last yield to indicate the end of the stream, because we know in
192−-- advance at the time of the last yield that the stream is ending. We build
193−-- singleton streams in the implementation of 'pure' for Applicative and Monad,
194−-- and in 'lift' for MonadTrans, in these places we use yield with 'Nothing' to
195−-- indicate the end of the stream. Note that, the only advantage of Maybe is
196−-- when we have to build a large number of singleton or short streams. For
197−-- larger streams anyway the overhead of a separate stop continuation is not
198−-- significant. This could be significant when we breakdown a large stream into
199−-- its elements, process them in some way and then recompose it from the
200−-- pieces. Zipping streams is one such example. Zipping with streamly is the
201−-- fastest among all streaming libraries.
202−--
203−-- However in a lazy computation we cannot know in advance that the stream is
204−-- ending therefore we cannot use 'Maybe', we use the stop continuation in that
205−-- case. For example when building a stream from a lazy container using a right
206−-- fold.
159+-- The singleton case can be expressed in terms of stop and yield but we have
160+-- it as a separate case to optimize composition operations for streams with
161+-- single element. We build singleton streams in the implementation of 'pure'
162+-- for Applicative and Monad, and in 'lift' for MonadTrans.
207163--
208164newtype Stream m a =
209165 Stream {
210166 runStream :: forall r.
211− Maybe (SVar m a) -- local state
212− -> m r -- stop
213− -> (a -> Maybe (Stream m a) -> m r) -- yield
167+ Maybe (SVar m a) -- local state
168+ -> m r -- stop
169+ -> (a -> m r) -- singleton
170+ -> (a -> Stream m a -> m r) -- yield
214171 -> m r
215172 }
216173
217−-- | A monad that can perform concurrent or parallel IO operations. Streams
218−-- that can be composed concurrently require the underlying monad to be
219−-- 'MonadParallel'.
220−type MonadParallel m = (MonadIO m, MonadBaseControl IO m, MonadThrow m)
174+nil :: Stream m a
175+nil = Stream $ \_ stp _ _ -> stp
221176
222−{-# DEPRECATED MonadAsync "Please use MonadParallel instead." #-}
223−type MonadAsync m = MonadParallel m
177+{-# INLINE singleton #-}
178+singleton :: a -> Stream m a
179+singleton a = Stream $ \_ _ single _ -> single a
224180
225−cons :: a -> Maybe (Stream m a) -> Stream m a
226−cons a r = Stream $ \_ _ yld -> yld a r
181+cons :: a -> Stream m a -> Stream m a
182+cons a r = Stream $ \_ _ _ yld -> yld a r
227183
228184repeat :: a -> Stream m a
229−repeat a = let x = cons a (Just x) in x
230−
231−nil :: Stream m a
232−nil = Stream $ \_ stp _ -> stp
185+repeat a = let x = cons a x in x
233186
234187------------------------------------------------------------------------------
235188-- Composing streams
@@ -249,11 +202,11 @@ nil = Stream $ \_ stp _ -> stp
249202serial :: Stream m a -> Stream m a -> Stream m a
250203serial m1 m2 = go m1
251204 where
252− go (Stream m) = Stream $ \_ stp yld ->
253− let stop = (runStream m2) Nothing stp yld
254− yield a Nothing = yld a (Just m2)
255− yield a (Just r) = yld a (Just (go r))
256− in m Nothing stop yield
205+ go (Stream m) = Stream $ \_ stp sng yld ->
206+ let stop = (runStream m2) Nothing stp sng yld
207+ single a = yld a m2
208+ yield a r = yld a (go r)
209+ in m Nothing stop single yield
257210
258211instance Semigroup (Stream m a) where
259212 (<>) = serial
@@ -271,16 +224,24 @@ instance Monoid (Stream m a) where
271224------------------------------------------------------------------------------
272225
273226coserial :: Stream m a -> Stream m a -> Stream m a
274−coserial m1 m2 = Stream $ \_ stp yld -> do
275− let stop = (runStream m2) Nothing stp yld
276− yield a Nothing = yld a (Just m2)
277− yield a (Just r) = yld a (Just (coserial m2 r))
278− (runStream m1) Nothing stop yield
227+coserial m1 m2 = Stream $ \_ stp sng yld -> do
228+ let stop = (runStream m2) Nothing stp sng yld
229+ single a = yld a m2
230+ yield a r = yld a (coserial m2 r)
231+ (runStream m1) Nothing stop single yield
279232
280233------------------------------------------------------------------------------
281234-- Spawning threads and collecting result in streamed fashion
282235------------------------------------------------------------------------------
283236
237+-- | A monad that can perform concurrent or parallel IO operations. Streams
238+-- that can be composed concurrently require the underlying monad to be
239+-- 'MonadParallel'.
240+type MonadParallel m = (MonadIO m, MonadBaseControl IO m, MonadThrow m)
241+
242+{-# DEPRECATED MonadAsync "Please use MonadParallel instead." #-}
243+type MonadAsync m = MonadParallel m
244+
284245{-# INLINE doFork #-}
285246doFork :: MonadBaseControl IO m
286247 => m ()
@@ -322,11 +283,11 @@ runqueueLIFO sv q = run
322283 work <- dequeue
323284 case work of
324285 Nothing -> sendStop sv
325− Just m -> (runStream m) (Just sv) run yield
286+ Just m -> (runStream m) (Just sv) run single yield
326287
327288 sendit a = send sv (ChildYield a)
328− yield a Nothing = sendit a >> run
329− yield a (Just r) = sendit a >> (runStream r) (Just sv) run yield
289+ single a = sendit a >> run
290+ yield a r = sendit a >> (runStream r) (Just sv) run single yield
330291
331292 dequeue = liftIO $ atomicModifyIORefCAS q $ \case
332293 [] -> ([], Nothing)
@@ -345,12 +306,12 @@ runqueueFIFO sv q = run
345306 work <- dequeue
346307 case work of
347308 Nothing -> sendStop sv
348− Just m -> (runStream m) (Just sv) run yield
309+ Just m -> (runStream m) (Just sv) run single yield
349310
350311 dequeue = liftIO $ tryPopR q
351312 sendit a = send sv (ChildYield a)
352− yield a Nothing = sendit a >> run
353− yield a (Just r) = sendit a >> liftIO (enqueueFIFO q r) >> run
313+ single a = sendit a >> run
314+ yield a r = sendit a >> liftIO (enqueueFIFO q r) >> run
354315
355316-- Thread tracking is needed for two reasons:
356317--
@@ -406,7 +367,7 @@ sendWorkerWait sv = do
406367-- | Pull a stream from an SVar.
407368{-# NOINLINE fromStreamVar #-}
408369fromStreamVar :: MonadParallel m => SVar m a -> Stream m a
409−fromStreamVar sv = Stream $ \_ stp yld -> do
370+fromStreamVar sv = Stream $ \_ stp sng yld -> do
410371 -- XXX if reading the IORef is costly we can use a flag in the SVar to
411372 -- indicate we are done.
412373 done <- allThreadsDone sv
@@ -419,7 +380,7 @@ fromStreamVar sv = Stream $ \_ stp yld -> do
419380 -- To avoid lock overhead we read all events at once instead of reading
420381 -- one at a time. We just reverse the list to process the events in the
421382 -- order they arrived. Maybe we can use a queue instead?
422− (runStream $ processEvents (reverse list)) Nothing stp yld
383+ (runStream $ processEvents (reverse list)) Nothing stp sng yld
423384
424385 where
425386
@@ -430,15 +391,15 @@ fromStreamVar sv = Stream $ \_ stp yld -> do
430391 throwM e
431392
432393 {-# INLINE processEvents #-}
433− processEvents [] = Stream $ \_ stp yld -> do
394+ processEvents [] = Stream $ \_ stp sng yld -> do
434395 done <- allThreadsDone sv
435396 if not done
436− then (runStream (fromStreamVar sv)) Nothing stp yld
397+ then (runStream (fromStreamVar sv)) Nothing stp sng yld
437398 else stp
438399
439− processEvents (ev : es) = Stream $ \_ stp yld -> do
440− let continue = (runStream (processEvents es)) Nothing stp yld
441− yield a = yld a (Just (processEvents es))
400+ processEvents (ev : es) = Stream $ \_ stp sng yld -> do
401+ let continue = (runStream (processEvents es)) Nothing stp sng yld
402+ yield a = yld a (processEvents es)
442403
443404 case ev of
444405 ChildYield a -> yield a
@@ -567,9 +528,9 @@ toStreamVar sv m = do
567528{-# NOINLINE withNewSVar2 #-}
568529withNewSVar2 :: MonadParallel m
569530 => SVarStyle -> Stream m a -> Stream m a -> Stream m a
570−withNewSVar2 style m1 m2 = Stream $ \_ stp yld -> do
531+withNewSVar2 style m1 m2 = Stream $ \_ stp sng yld -> do
571532 sv <- newStreamVar2 style m1 m2
572− (runStream (fromStreamVar sv)) Nothing stp yld
533+ (runStream (fromStreamVar sv)) Nothing stp sng yld
573534
574535-- | Join two computations on the currently running 'SVar' queue for concurrent
575536-- execution. The 'SVarStyle' required by the current composition context is
@@ -602,11 +563,11 @@ withNewSVar2 style m1 m2 = Stream $ \_ stp yld -> do
602563{-# INLINE joinStreamVar2 #-}
603564joinStreamVar2 :: MonadParallel m
604565 => SVarStyle -> Stream m a -> Stream m a -> Stream m a
605−joinStreamVar2 style m1 m2 = Stream $ \st stp yld ->
606− case st of
566+joinStreamVar2 style m1 m2 = Stream $ \svr stp sng yld ->
567+ case svr of
607568 Just sv | svarStyle sv == style ->
608− liftIO ((enqueue sv) m2) >> (runStream m1) st stp yld
609− _ -> (runStream (withNewSVar2 style m1 m2)) Nothing stp yld
569+ liftIO ((enqueue sv) m2) >> (runStream m1) svr stp sng yld
570+ _ -> (runStream (withNewSVar2 style m1 m2)) Nothing stp sng yld
610571
611572------------------------------------------------------------------------------
612573-- Semigroup and Monoid style compositions for parallel actions
@@ -646,10 +607,9 @@ instance Monad m => Monad (Stream m) where
646607------------------------------------------------------------------------------
647608
648609alt :: Stream m a -> Stream m a -> Stream m a
649−alt m1 m2 = Stream $ \_ stp yld ->
650− let stop = runStream m2 Nothing stp yld
651− yield = yld
652− in runStream m1 Nothing stop yield
610+alt m1 m2 = Stream $ \_ stp sng yld ->
611+ let stop = runStream m2 Nothing stp sng yld
612+ in runStream m1 Nothing stop sng yld
653613
654614instance MonadParallel m => Alternative (Stream m) where
655615 empty = nil
@@ -664,7 +624,7 @@ instance MonadParallel m => MonadPlus (Stream m) where
664624-------------------------------------------------------------------------------
665625
666626instance MonadTrans Stream where
667− lift mx = Stream $ \_ _ yld -> mx >>= (\a -> (yld a Nothing))
627+ lift mx = Stream $ \_ _ single _ -> mx >>= single
668628
669629instance (MonadBase b m, Monad m) => MonadBase b (Stream m) where
670630 liftBase = liftBaseDefault
@@ -682,18 +642,17 @@ instance MonadThrow m => MonadThrow (Stream m) where
682642-- XXX handle and test cross thread state transfer
683643instance MonadError e m => MonadError e (Stream m) where
684644 throwError = lift . throwError
685− catchError m h = Stream $ \st stp yld ->
686− let handle r = r `catchError` \e -> (runStream (h e)) st stp yld
687− yield a Nothing = yld a Nothing
688− yield a (Just r) = yld a (Just (catchError r h))
689− in handle $ (runStream m) st stp yield
645+ catchError m h = Stream $ \svr stp sng yld ->
646+ let handle r = r `catchError` \e -> (runStream (h e)) svr stp sng yld
647+ yield a r = yld a (catchError r h)
648+ in handle $ (runStream m) svr stp sng yield
690649
691650instance MonadReader r m => MonadReader r (Stream m) where
692651 ask = lift ask
693− local f m = Stream $ \st stp yld ->
694− let yield a Nothing = local f $ yld a Nothing
695− yield a (Just r) = local f $ yld a (Just (local f r))
696− in (runStream m) st (local f stp) yield
652+ local f m = Stream $ \svr stp sng yld ->
653+ let single = local f . sng
654+ yield a r = local f $ yld a (local f r)
655+ in (runStream m) svr (local f stp) single yield
697656
698657instance MonadState s m => MonadState s (Stream m) where
699658 get = lift get
src/Streamly/Prelude.hs+131−137
@@ -114,20 +114,20 @@ import Streamly.Streams
114114unfoldr :: IsStream t => (b -> Maybe (a, b)) -> b -> t m a
115115unfoldr step = fromStream . go
116116 where
117− go s = Stream $ \_ stp yld ->
117+ go s = Stream $ \_ stp _ yld ->
118118 case step s of
119119 Nothing -> stp
120− Just (a, b) -> yld a (Just (go b))
120+ Just (a, b) -> yld a (go b)
121121
122122-- | Build a Stream by unfolding monadic steps starting from a seed.
123123unfoldrM :: (IsStream t, Monad m) => (b -> m (Maybe (a, b))) -> b -> t m a
124124unfoldrM step = fromStream . go
125125 where
126− go s = Stream $ \_ stp yld -> do
126+ go s = Stream $ \_ stp _ yld -> do
127127 mayb <- step s
128128 case mayb of
129129 Nothing -> stp
130− Just (a, b) -> yld a (Just (go b))
130+ Just (a, b) -> yld a (go b)
131131
132132-- | Construct a stream from a 'Foldable' container.
133133{-# INLINE fromFoldable #-}
@@ -144,27 +144,27 @@ each = fromFoldable
144144iterate :: IsStream t => (a -> a) -> a -> t m a
145145iterate step = fromStream . go
146146 where
147− go s = S.cons s (Just (go (step s)))
147+ go s = S.cons s (go (step s))
148148
149149-- | Iterate a monadic function from a seed value, streaming the results forever
150150iterateM :: (IsStream t, Monad m) => (a -> m a) -> a -> t m a
151151iterateM step = fromStream . go
152152 where
153− go s = Stream $ \_ _ yld -> do
153+ go s = Stream $ \_ _ _ yld -> do
154154 a <- step s
155− yld s (Just (go a))
155+ yld s (go a)
156156
157157-- | Read lines from an IO Handle into a stream of Strings.
158158fromHandle :: (IsStream t, MonadIO m) => IO.Handle -> t m String
159159fromHandle h = fromStream go
160160 where
161− go = Stream $ \_ stp yld -> do
161+ go = Stream $ \_ stp _ yld -> do
162162 eof <- liftIO $ IO.hIsEOF h
163163 if eof
164164 then stp
165165 else do
166166 str <- liftIO $ IO.hGetLine h
167− yld str (Just go)
167+ yld str go
168168
169169------------------------------------------------------------------------------
170170-- Elimination
@@ -181,9 +181,9 @@ foldr step acc m = go (toStream m)
181181 where
182182 go m1 =
183183 let stop = return acc
184− yield a Nothing = return (step a acc)
185− yield a (Just x) = go x >>= \b -> return (step a b)
186− in (S.runStream m1) Nothing stop yield
184+ single a = return (step a acc)
185+ yield a r = go r >>= \b -> return (step a b)
186+ in (S.runStream m1) Nothing stop single yield
187187
188188-- | Lazy right fold with a monadic step function. For example, to fold a
189189-- stream into a list:
@@ -198,9 +198,9 @@ foldrM step acc m = go (toStream m)
198198 where
199199 go m1 =
200200 let stop = return acc
201− yield a Nothing = step a acc
202− yield a (Just x) = (go x) >>= (step a)
203− in (S.runStream m1) Nothing stop yield
201+ single a = step a acc
202+ yield a r = go r >>= step a
203+ in (S.runStream m1) Nothing stop single yield
204204
205205-- | Strict left scan with an extraction function. Like 'scanl'', but applies a
206206-- user supplied extraction function (the third argument) at each step. This is
@@ -210,13 +210,12 @@ foldrM step acc m = go (toStream m)
210210scanx :: IsStream t => (x -> a -> x) -> x -> (x -> b) -> t m a -> t m b
211211scanx step begin done m = cons (done begin) $ fromStream $ go (toStream m) begin
212212 where
213− go m1 !acc = Stream $ \_ stp yld ->
214− let stop = stp
215− yield a Nothing = yld (done $ step acc a) Nothing
216− yield a (Just x) =
213+ go m1 !acc = Stream $ \_ stp sng yld ->
214+ let single a = sng (done $ step acc a)
215+ yield a r =
217216 let s = step acc a
218− in yld (done s) (Just (go x s))
219− in S.runStream m1 Nothing stop yield
217+ in yld (done s) (go r s)
218+ in S.runStream m1 Nothing stp single yield
220219
221220{-# DEPRECATED scan "Please use scanx instead." #-}
222221scan :: IsStream t => (x -> a -> x) -> x -> (x -> b) -> t m a -> t m b
@@ -240,22 +239,20 @@ foldx step begin done m = get $ go (toStream m) begin
240239 where
241240 {-# NOINLINE get #-}
242241 get m1 =
243− let yield a Nothing = return $ done a
244− yield _ _ = undefined
245− in (S.runStream m1) Nothing undefined yield
242+ let single = return . done
243+ in (S.runStream m1) Nothing undefined single undefined
246244
247245 -- Note, this can be implemented by making a recursive call to "go",
248246 -- however that is more expensive because of unnecessary recursion
249247 -- that cannot be tail call optimized. Unfolding recursion explicitly via
250248 -- continuations is much more efficient.
251− go m1 !acc = Stream $ \_ _ yld ->
252− let stop = yld acc Nothing
249+ go m1 !acc = Stream $ \_ _ sng yld ->
250+ let stop = sng acc
251+ single a = sng $ step acc a
253252 yield a r =
254− let s = step acc a
255− in case r of
256− Nothing -> yld s Nothing
257− Just x -> (S.runStream (go x s)) Nothing undefined yld
258− in (S.runStream m1) Nothing stop yield
253+ let stream = go r (step acc a)
254+ in (S.runStream stream) Nothing undefined sng yld
255+ in (S.runStream m1) Nothing stop single yield
259256
260257{-# DEPRECATED foldl "Please use foldx instead." #-}
261258foldl :: Monad m => (x -> a -> x) -> x -> (x -> b) -> SerialT m a -> m b
@@ -273,9 +270,9 @@ foldxM step begin done m = go begin (toStream m)
273270 where
274271 go !acc m1 =
275272 let stop = acc >>= done
276− yield a Nothing = acc >>= \b -> step b a >>= done
277− yield a (Just x) = acc >>= \b -> go (step b a) x
278− in (S.runStream m1) Nothing stop yield
273+ single a = acc >>= \b -> step b a >>= done
274+ yield a r = acc >>= \b -> go (step b a) r
275+ in (S.runStream m1) Nothing stop single yield
279276
280277{-# DEPRECATED foldlM "Please use foldxM instead." #-}
281278foldlM :: Monad m => (x -> a -> m x) -> m x -> (x -> m b) -> SerialT m a -> m b
@@ -291,9 +288,9 @@ foldlM' step begin m = foldxM step (return begin) return m
291288uncons :: (IsStream t, Monad m) => SerialT m a -> m (Maybe (a, t m a))
292289uncons m =
293290 let stop = return Nothing
294− yield a Nothing = return (Just (a, nil))
295− yield a (Just x) = return (Just (a, fromStream x))
296− in (S.runStream (toStream m)) Nothing stop yield
291+ single a = return (Just (a, nil))
292+ yield a r = return (Just (a, fromStream r))
293+ in (S.runStream (toStream m)) Nothing stop single yield
297294
298295-- | Write a stream of Strings to an IO Handle.
299296toHandle :: MonadIO m => IO.Handle -> SerialT m String -> m ()
@@ -301,9 +298,9 @@ toHandle h m = go (toStream m)
301298 where
302299 go m1 =
303300 let stop = return ()
304− yield a Nothing = liftIO (IO.hPutStrLn h a)
305− yield a (Just x) = liftIO (IO.hPutStrLn h a) >> go x
306− in (S.runStream m1) Nothing stop yield
301+ single a = liftIO (IO.hPutStrLn h a)
302+ yield a r = liftIO (IO.hPutStrLn h a) >> go r
303+ in (S.runStream m1) Nothing stop single yield
307304
308305------------------------------------------------------------------------------
309306-- Special folds
@@ -319,46 +316,45 @@ toList = foldrM (\a xs -> return (a : xs)) []
319316take :: IsStream t => Int -> t m a -> t m a
320317take n m = fromStream $ go n (toStream m)
321318 where
322− go n1 m1 = Stream $ \ctx stp yld ->
323− let yield a Nothing = yld a Nothing
324− yield a (Just x) = yld a (Just (go (n1 - 1) x))
325− in if n1 <= 0 then stp else (S.runStream m1) ctx stp yield
319+ go n1 m1 = Stream $ \ctx stp sng yld ->
320+ let yield a r = yld a (go (n1 - 1) r)
321+ in if n1 <= 0 then stp else (S.runStream m1) ctx stp sng yield
326322
327323-- | Include only those elements that pass a predicate.
328324{-# INLINE filter #-}
329325filter :: IsStream t => (a -> Bool) -> t m a -> t m a
330326filter p m = fromStream $ go (toStream m)
331327 where
332− go m1 = Stream $ \ctx stp yld ->
333− let yield a Nothing | p a = yld a Nothing
334− | otherwise = stp
335− yield a (Just x) | p a = yld a (Just (go x))
336− | otherwise = (S.runStream x) ctx stp yield
337− in (S.runStream m1) ctx stp yield
328+ go m1 = Stream $ \ctx stp sng yld ->
329+ let single a | p a = sng a
330+ | otherwise = stp
331+ yield a r | p a = yld a (go r)
332+ | otherwise = (S.runStream r) ctx stp single yield
333+ in (S.runStream m1) ctx stp single yield
338334
339335-- | End the stream as soon as the predicate fails on an element.
340336{-# INLINE takeWhile #-}
341337takeWhile :: IsStream t => (a -> Bool) -> t m a -> t m a
342338takeWhile p m = fromStream $ go (toStream m)
343339 where
344− go m1 = Stream $ \ctx stp yld ->
345− let yield a Nothing | p a = yld a Nothing
346− | otherwise = stp
347− yield a (Just x) | p a = yld a (Just (go x))
348− | otherwise = stp
349− in (S.runStream m1) ctx stp yield
340+ go m1 = Stream $ \ctx stp sng yld ->
341+ let single a | p a = sng a
342+ | otherwise = stp
343+ yield a r | p a = yld a (go r)
344+ | otherwise = stp
345+ in (S.runStream m1) ctx stp single yield
350346
351347-- | Discard first 'n' elements from the stream and take the rest.
352348drop :: IsStream t => Int -> t m a -> t m a
353349drop n m = fromStream $ go n (toStream m)
354350 where
355− go n1 m1 = Stream $ \ctx stp yld ->
356− let yield _ Nothing = stp
357− yield _ (Just x) = (S.runStream $ go (n1 - 1) x) ctx stp yld
351+ go n1 m1 = Stream $ \ctx stp sng yld ->
352+ let single _ = stp
353+ yield _ r = (S.runStream $ go (n1 - 1) r) ctx stp sng yld
358354 -- Somehow "<=" check performs better than a ">"
359355 in if n1 <= 0
360− then (S.runStream m1) ctx stp yld
361− else (S.runStream m1) ctx stp yield
356+ then (S.runStream m1) ctx stp sng yld
357+ else (S.runStream m1) ctx stp single yield
362358
363359-- | Drop elements in the stream as long as the predicate succeeds and then
364360-- take the rest of the stream.
@@ -366,34 +362,34 @@ drop n m = fromStream $ go n (toStream m)
366362dropWhile :: IsStream t => (a -> Bool) -> t m a -> t m a
367363dropWhile p m = fromStream $ go (toStream m)
368364 where
369− go m1 = Stream $ \ctx stp yld ->
370− let yield a Nothing | p a = stp
371− | otherwise = yld a Nothing
372− yield a (Just x) | p a = (S.runStream x) ctx stp yield
373− | otherwise = yld a (Just x)
374− in (S.runStream m1) ctx stp yield
365+ go m1 = Stream $ \ctx stp sng yld ->
366+ let single a | p a = stp
367+ | otherwise = sng a
368+ yield a r | p a = (S.runStream r) ctx stp single yield
369+ | otherwise = yld a r
370+ in (S.runStream m1) ctx stp single yield
375371
376372-- | Determine whether all elements of a stream satisfy a predicate.
377373all :: Monad m => (a -> Bool) -> SerialT m a -> m Bool
378374all p m = go (toStream m)
379375 where
380376 go m1 =
381− let yield a Nothing | p a = return True
382− | otherwise = return False
383− yield a (Just x) | p a = go x
384− | otherwise = return False
385− in (S.runStream m1) Nothing (return True) yield
377+ let single a | p a = return True
378+ | otherwise = return False
379+ yield a r | p a = go r
380+ | otherwise = return False
381+ in (S.runStream m1) Nothing (return True) single yield
386382
387383-- | Determine whether any of the elements of a stream satisfy a predicate.
388384any :: Monad m => (a -> Bool) -> SerialT m a -> m Bool
389385any p m = go (toStream m)
390386 where
391387 go m1 =
392− let yield a Nothing | p a = return True
393− | otherwise = return False
394− yield a (Just x) | p a = return True
395− | otherwise = go x
396− in (S.runStream m1) Nothing (return False) yield
388+ let single a | p a = return True
389+ | otherwise = return False
390+ yield a r | p a = return True
391+ | otherwise = go r
392+ in (S.runStream m1) Nothing (return False) single yield
397393
398394-- | Determine the sum of all elements of a stream of numbers
399395sum :: (Monad m, Num a) => SerialT m a -> m a
@@ -407,16 +403,17 @@ product = foldl (*) 1 id
407403head :: Monad m => SerialT m a -> m (Maybe a)
408404head m =
409405 let stop = return Nothing
406+ single a = return (Just a)
410407 yield a _ = return (Just a)
411− in (S.runStream (toStream m)) Nothing stop yield
408+ in (S.runStream (toStream m)) Nothing stop single yield
412409
413410-- | Extract all but the first element of the stream, if any.
414411tail :: (IsStream t, Monad m) => SerialT m a -> m (Maybe (t m a))
415412tail m =
416− let stop = return Nothing
417− yield _ Nothing = return $ Just nil
418− yield _ (Just t) = return $ Just $ fromStream t
419− in (S.runStream (toStream m)) Nothing stop yield
413+ let stop = return Nothing
414+ single _ = return $ Just nil
415+ yield _ r = return $ Just $ fromStream r
416+ in (S.runStream (toStream m)) Nothing stop single yield
420417
421418-- | Extract the last element of the stream, if any.
422419{-# INLINE last #-}
@@ -427,28 +424,29 @@ last = foldl (\_ y -> Just y) Nothing id
427424null :: Monad m => SerialT m a -> m Bool
428425null m =
429426 let stop = return True
427+ single _ = return False
430428 yield _ _ = return False
431− in (S.runStream (toStream m)) Nothing stop yield
429+ in (S.runStream (toStream m)) Nothing stop single yield
432430
433431-- | Determine whether an element is present in the stream.
434432elem :: (Monad m, Eq a) => a -> SerialT m a -> m Bool
435433elem e m = go (toStream m)
436434 where
437435 go m1 =
438− let stop = return False
439− yield a Nothing = return (a == e)
440− yield a (Just x) = if a == e then return True else go x
441− in (S.runStream m1) Nothing stop yield
436+ let stop = return False
437+ single a = return (a == e)
438+ yield a r = if a == e then return True else go r
439+ in (S.runStream m1) Nothing stop single yield
442440
443441-- | Determine whether an element is not present in the stream.
444442notElem :: (Monad m, Eq a) => a -> SerialT m a -> m Bool
445443notElem e m = go (toStream m)
446444 where
447445 go m1 =
448− let stop = return True
449− yield a Nothing = return (a /= e)
450− yield a (Just x) = if a == e then return False else go x
451− in (S.runStream m1) Nothing stop yield
446+ let stop = return True
447+ single a = return (a /= e)
448+ yield a r = if a == e then return False else go r
449+ in (S.runStream m1) Nothing stop single yield
452450
453451-- | Determine the length of the stream.
454452length :: Monad m => SerialT m a -> m Int
@@ -457,28 +455,27 @@ length = foldl (\n _ -> n + 1) 0 id
457455-- | Returns the elements of the stream in reverse order.
458456-- The stream must be finite.
459457reverse :: (IsStream t) => t m a -> t m a
460−reverse m = fromStream $ go Nothing (toStream m)
458+reverse m = fromStream $ go S.nil (toStream m)
461459 where
462− go rev rest = Stream $ \svr stp yld ->
463− let stop = case rev of
464− Nothing -> stp
465− Just str -> S.runStream str svr stp yld
466− yield a Nothing = S.runStream (a `S.cons` rev) svr stp yld
467− yield a (Just x) = S.runStream (go (Just $ a `S.cons` rev) x) svr stp yld
468− in S.runStream rest svr stop yield
460+ go rev rest = Stream $ \svr stp sng yld ->
461+ let run x = S.runStream x svr stp sng yld
462+ stop = run rev
463+ single a = run $ a `S.cons` rev
464+ yield a r = run $ go (a `S.cons` rev) r
465+ in S.runStream rest svr stop single yield
469466
470467-- XXX replace the recursive "go" with continuation
471468-- | Determine the minimum element in a stream.
472469minimum :: (Monad m, Ord a) => SerialT m a -> m (Maybe a)
473470minimum m = go Nothing (toStream m)
474471 where
475− go r m1 =
476− let stop = return r
477− yield a Nothing = return $ min_ a r
478− yield a (Just x) = go (min_ a r) x
479− in (S.runStream m1) Nothing stop yield
472+ go res m1 =
473+ let stop = return res
474+ single a = return $ min_ a res
475+ yield a r = go (min_ a res) r
476+ in (S.runStream m1) Nothing stop single yield
480477
481− min_ a r = case r of
478+ min_ a res = case res of
482479 Nothing -> Just a
483480 Just e -> Just $ min a e
484481
@@ -487,13 +484,13 @@ minimum m = go Nothing (toStream m)
487484maximum :: (Monad m, Ord a) => SerialT m a -> m (Maybe a)
488485maximum m = go Nothing (toStream m)
489486 where
490− go r m1 =
491− let stop = return r
492− yield a Nothing = return $ max_ a r
493− yield a (Just x) = go (max_ a r) x
494− in (S.runStream m1) Nothing stop yield
487+ go res m1 =
488+ let stop = return res
489+ single a = return $ max_ a res
490+ yield a r = go (max_ a res) r
491+ in (S.runStream m1) Nothing stop single yield
495492
496− max_ a r = case r of
493+ max_ a res = case res of
497494 Nothing -> Just a
498495 Just e -> Just $ max a e
499496
@@ -509,11 +506,10 @@ maximum m = go Nothing (toStream m)
509506mapM :: (IsStream t, Monad m) => (a -> m b) -> t m a -> t m b
510507mapM f m = fromStream $ go (toStream m)
511508 where
512− go m1 = Stream $ \_ stp yld ->
513− let stop = stp
514− yield a Nothing = f a >>= \b -> yld b Nothing
515− yield a (Just x) = f a >>= \b -> yld b (Just (go x))
516− in (S.runStream m1) Nothing stop yield
509+ go m1 = Stream $ \_ stp sng yld ->
510+ let single a = f a >>= sng
511+ yield a r = f a >>= \b -> yld b (go r)
512+ in (S.runStream m1) Nothing stp single yield
517513
518514-- | Apply a monadic action to each element of the stream and discard the
519515-- output of the action.
@@ -522,29 +518,28 @@ mapM_ f m = go (toStream m)
522518 where
523519 go m1 =
524520 let stop = return ()
525− yield a Nothing = void (f a)
526− yield a (Just x) = f a >> go x
527− in (S.runStream m1) Nothing stop yield
521+ single a = void (f a)
522+ yield a r = f a >> go r
523+ in (S.runStream m1) Nothing stop single yield
528524
529525-- | Reduce a stream of monadic actions to a stream of the output of those
530526-- actions.
531527sequence :: (IsStream t, Monad m) => t m (m a) -> t m a
532528sequence m = fromStream $ go (toStream m)
533529 where
534− go m1 = Stream $ \_ stp yld ->
535− let stop = stp
536− yield a Nothing = a >>= \b -> yld b Nothing
537− yield a (Just x) = a >>= \b -> yld b (Just (go x))
538− in (S.runStream m1) Nothing stop yield
530+ go m1 = Stream $ \_ stp sng yld ->
531+ let single ma = ma >>= sng
532+ yield ma r = ma >>= \b -> yld b (go r)
533+ in (S.runStream m1) Nothing stp single yield
539534
540535-- | Generate a stream by performing an action @n@ times.
541536replicateM :: (IsStream t, Monad m) => Int -> m a -> t m a
542537replicateM n m = fromStream $ go n
543538 where
544− go cnt = Stream $ \_ stp yld ->
539+ go cnt = Stream $ \_ stp _ yld ->
545540 if cnt <= 0
546541 then stp
547− else m >>= \a -> yld a (Just $ go (cnt - 1))
542+ else m >>= \a -> yld a (go (cnt - 1))
548543
549544------------------------------------------------------------------------------
550545-- Serially Zipping Streams
@@ -554,16 +549,15 @@ replicateM n m = fromStream $ go n
554549zipWithM :: IsStream t => (a -> b -> t m c) -> t m a -> t m b -> t m c
555550zipWithM f m1 m2 = fromStream $ go (toStream m1) (toStream m2)
556551 where
557− go mx my = Stream $ \_ stp yld -> do
552+ go mx my = Stream $ \_ stp sng yld -> do
558553 let merge a ra =
559− let yield2 b Nothing = (S.runStream (g a b)) Nothing stp yld
560− yield2 b (Just rb) =
561− (S.runStream (g a b <> go ra rb)) Nothing stp yld
562− in (S.runStream my) Nothing stp yield2
563− let yield1 a Nothing = merge a S.nil
564− yield1 a (Just ra) = merge a ra
565− (S.runStream mx) Nothing stp yield1
566− g a b = toStream $ f a b
554+ let run x = S.runStream x Nothing stp sng yld
555+ single2 b = run $ toStream (f a b)
556+ yield2 b rb = run $ toStream (f a b) <> go ra rb
557+ in (S.runStream my) Nothing stp single2 yield2
558+ let single1 a = merge a S.nil
559+ yield1 a ra = merge a ra
560+ (S.runStream mx) Nothing stp single1 yield1
567561
568562------------------------------------------------------------------------------
569563-- Parallely Zipping Streams
@@ -573,10 +567,10 @@ zipWithM f m1 m2 = fromStream $ go (toStream m1) (toStream m2)
573567-- concurrently) using a monadic zipping function.
574568zipParallelWithM :: (IsStream t, MonadParallel m)
575569 => (a -> b -> t m c) -> t m a -> t m b -> t m c
576−zipParallelWithM f m1 m2 = fromStream $ Stream $ \_ stp yld -> do
570+zipParallelWithM f m1 m2 = fromStream $ Stream $ \_ stp sng yld -> do
577571 ma <- async m1
578572 mb <- async m2
579− (S.runStream (toStream (zipWithM f ma mb))) Nothing stp yld
573+ (S.runStream (toStream (zipWithM f ma mb))) Nothing stp sng yld
580574
581575{-# DEPRECATED zipAsyncWithM "Please use zipParallelWithM instead." #-}
582576zipAsyncWithM :: (IsStream t, MonadParallel m)
src/Streamly/Streams.hs+78−79
@@ -114,6 +114,7 @@ import Control.Monad.Trans.Class (MonadTrans)
114114import Data.Semigroup (Semigroup(..))
115115import Prelude hiding (zipWith)
116116import Streamly.Core ( MonadParallel, Stream(Stream)
117+ , singleton
117118 , SVar, SVarStyle(..)
118119 , SVarTag(..), SVarSched(..))
119120import qualified Streamly.Core as S
@@ -151,7 +152,7 @@ infixr 5 `cons`
151152-- [1,2,3]
152153-- @
153154cons :: IsStream t => a -> t m a -> t m a
154−cons a r = fromStream $ S.cons a (Just (toStream r))
155+cons a r = fromStream $ S.cons a (toStream r)
155156
156157infixr 5 .:
157158
@@ -191,18 +192,18 @@ infixr 5 .:
191192-- represent an "empty" stream.
192193streamBuild :: IsStream t
193194 => (forall r. Maybe (SVar m a)
194− -> (a -> Maybe (t m a) -> m r)
195+ -> (a -> t m a -> m r)
196+ -> (a -> m r)
195197 -> m r
196198 -> m r)
197199 -> t m a
198−streamBuild k = fromStream $ Stream $ \sv stp yld ->
199− let yield a Nothing = yld a Nothing
200− yield a (Just r) = yld a (Just (toStream r))
201− in k sv yield stp
200+streamBuild k = fromStream $ Stream $ \svr stp sng yld ->
201+ let yield a r = yld a (toStream r)
202+ in k svr yield sng stp
202203
203204-- | Build a singleton stream from a callback function.
204205fromCallback :: IsStream t => (forall r. (a -> m r) -> m r) -> t m a
205−fromCallback k = fromStream $ Stream $ \_ _ yld -> k (\a -> yld a Nothing)
206+fromCallback k = fromStream $ Stream $ \_ _ sng _ -> k sng
206207
207208-- | Read an SVar to get a stream.
208209fromSVar :: (MonadParallel m, IsStream t) => SVar m a -> t m a
@@ -215,12 +216,17 @@ fromSVar sv = fromStream $ S.fromStreamVar sv
215216-- | Fold a stream using its church encoding. The second argument is the "step"
216217-- function consuming an element and the remaining stream, if any. The third
217218-- argument is for consuming an "empty" stream that yields nothing.
218−streamFold :: IsStream t
219− => Maybe (SVar m a) -> (a -> Maybe (t m a) -> m r) -> m r -> t m a -> m r
220−streamFold sv step blank m =
221− let yield a Nothing = step a Nothing
222− yield a (Just x) = step a (Just (fromStream x))
223− in (S.runStream (toStream m)) sv blank yield
219+streamFold
220+ :: IsStream t
221+ => Maybe (SVar m a)
222+ -> (a -> t m a -> m r)
223+ -> (a -> m r)
224+ -> m r
225+ -> t m a
226+ -> m r
227+streamFold svr step single blank m =
228+ let yield a x = step a (fromStream x)
229+ in (S.runStream (toStream m)) svr blank single yield
224230
225231-- | Run a streaming composition, discard the results. By default it interprets
226232-- the stream as 'SerialT', to run other types of streams use the type adapting
@@ -230,9 +236,9 @@ runStream m = go (toStream m)
230236 where
231237 go m1 =
232238 let stop = return ()
233− yield _ Nothing = stop
234− yield _ (Just x) = go x
235− in (S.runStream m1) Nothing stop yield
239+ single _ = return ()
240+ yield _ r = go r
241+ in (S.runStream m1) Nothing stop single yield
236242
237243-- | Same as 'runStream'
238244{-# Deprecated runStreaming "Please use runStream instead." #-}
@@ -354,18 +360,18 @@ serial m1 m2 = fromStream $ S.serial (toStream m1) (toStream m2)
354360
355361instance Monad m => Monad (SerialT m) where
356362 return = pure
357− (SerialT (Stream m)) >>= f = SerialT $ Stream $ \_ stp yld ->
358− let run x = (S.runStream x) Nothing stp yld
359− yield a Nothing = run $ toStream (f a)
360− yield a (Just r) = run $ toStream $ f a <> (fromStream r >>= f)
361− in m Nothing stp yield
363+ (SerialT (Stream m)) >>= f = SerialT $ Stream $ \_ stp sng yld ->
364+ let run x = (S.runStream x) Nothing stp sng yld
365+ single a = run $ toStream (f a)
366+ yield a r = run $ toStream $ f a <> (fromStream r >>= f)
367+ in m Nothing stp single yield
362368
363369------------------------------------------------------------------------------
364370-- Applicative
365371------------------------------------------------------------------------------
366372
367373instance Monad m => Applicative (SerialT m) where
368− pure a = SerialT $ S.cons a Nothing
374+ pure = SerialT . singleton
369375 (<*>) = ap
370376
371377------------------------------------------------------------------------------
@@ -373,11 +379,10 @@ instance Monad m => Applicative (SerialT m) where
373379------------------------------------------------------------------------------
374380
375381instance Monad m => Functor (SerialT m) where
376− fmap f (SerialT (Stream m)) = SerialT $ Stream $ \_ stp yld ->
377− let yield a Nothing = yld (f a) Nothing
378− yield a (Just r) = yld (f a)
379− (Just (getSerialT (fmap f (SerialT r))))
380− in m Nothing stp yield
382+ fmap f m = fromStream $ Stream $ \_ stp sng yld ->
383+ let single = sng . f
384+ yield a r = yld (f a) (toStream $ fmap f (SerialT r))
385+ in (S.runStream (toStream m)) Nothing stp single yield
381386
382387------------------------------------------------------------------------------
383388-- Num
@@ -501,18 +506,18 @@ infixr 5 <=>
501506
502507instance Monad m => Monad (CoserialT m) where
503508 return = pure
504− (CoserialT (Stream m)) >>= f = CoserialT $ Stream $ \_ stp yld ->
505− let run x = (S.runStream x) Nothing stp yld
506− yield a Nothing = run $ toStream (f a)
507− yield a (Just r) = run $ toStream $ f a <> (fromStream r >>= f)
508− in m Nothing stp yield
509+ (CoserialT (Stream m)) >>= f = CoserialT $ Stream $ \_ stp sng yld ->
510+ let run x = (S.runStream x) Nothing stp sng yld
511+ single a = run $ toStream (f a)
512+ yield a r = run $ toStream $ f a <> (fromStream r >>= f)
513+ in m Nothing stp single yield
509514
510515------------------------------------------------------------------------------
511516-- Applicative
512517------------------------------------------------------------------------------
513518
514519instance Monad m => Applicative (CoserialT m) where
515− pure a = CoserialT $ S.cons a Nothing
520+ pure = CoserialT . singleton
516521 (<*>) = ap
517522
518523------------------------------------------------------------------------------
@@ -520,11 +525,10 @@ instance Monad m => Applicative (CoserialT m) where
520525------------------------------------------------------------------------------
521526
522527instance Monad m => Functor (CoserialT m) where
523− fmap f (CoserialT (Stream m)) = CoserialT $ Stream $ \_ stp yld ->
524− let yield a Nothing = yld (f a) Nothing
525− yield a (Just r) =
526− yld (f a) (Just (getCoserialT (fmap f (CoserialT r))))
527− in m Nothing stp yield
528+ fmap f m = fromStream $ Stream $ \_ stp sng yld ->
529+ let single = sng . f
530+ yield a r = yld (f a) (toStream $ fmap f (CoserialT r))
531+ in (S.runStream (toStream m)) Nothing stp single yield
528532
529533------------------------------------------------------------------------------
530534-- Num
@@ -666,24 +670,23 @@ parbind
666670parbind par m f = go m
667671 where
668672 go (Stream g) =
669− Stream $ \ctx stp yld ->
670− let run x = (S.runStream x) ctx stp yld
671− yield a Nothing = run $ f a
672− yield a (Just r) = run $ f a `par` go r
673− in g Nothing stp yield
673+ Stream $ \ctx stp sng yld ->
674+ let run x = (S.runStream x) ctx stp sng yld
675+ single a = run $ f a
676+ yield a r = run $ f a `par` go r
677+ in g Nothing stp single yield
674678
675679instance MonadParallel m => Monad (CoparallelT m) where
676680 return = pure
677− (CoparallelT m) >>= f = CoparallelT $ parbind par m g
678− where g x = getCoparallelT (f x)
679− par = S.joinStreamVar2 (SVarStyle Conjunction LIFO)
681+ (CoparallelT m) >>= f = CoparallelT $ parbind par m (getCoparallelT . f)
682+ where par = S.joinStreamVar2 (SVarStyle Conjunction LIFO)
680683
681684------------------------------------------------------------------------------
682685-- Applicative
683686------------------------------------------------------------------------------
684687
685688instance MonadParallel m => Applicative (CoparallelT m) where
686− pure a = CoparallelT $ S.cons a Nothing
689+ pure = CoparallelT . singleton
687690 (<*>) = ap
688691
689692------------------------------------------------------------------------------
@@ -691,10 +694,10 @@ instance MonadParallel m => Applicative (CoparallelT m) where
691694------------------------------------------------------------------------------
692695
693696instance Monad m => Functor (CoparallelT m) where
694− fmap f (CoparallelT (Stream m)) = CoparallelT $ Stream $ \_ stp yld ->
695− let yield a Nothing = yld (f a) Nothing
696− yield a (Just r) = yld (f a) (Just (getCoparallelT (fmap f (CoparallelT r))))
697− in m Nothing stp yield
697+ fmap f m = fromStream $ Stream $ \_ stp sng yld ->
698+ let single = sng . f
699+ yield a r = yld (f a) (toStream $ fmap f (CoparallelT r))
700+ in (S.runStream (toStream m)) Nothing stp single yield
698701
699702------------------------------------------------------------------------------
700703-- Num
@@ -817,16 +820,15 @@ instance MonadParallel m => Semigroup (ParallelT m a) where
817820
818821instance MonadParallel m => Monad (ParallelT m) where
819822 return = pure
820− (ParallelT m) >>= f = ParallelT $ parbind par m g
821− where g x = getParallelT (f x)
822− par = S.joinStreamVar2 (SVarStyle Conjunction FIFO)
823+ (ParallelT m) >>= f = ParallelT $ parbind par m (getParallelT . f)
824+ where par = S.joinStreamVar2 (SVarStyle Conjunction FIFO)
823825
824826------------------------------------------------------------------------------
825827-- Applicative
826828------------------------------------------------------------------------------
827829
828830instance MonadParallel m => Applicative (ParallelT m) where
829− pure a = ParallelT $ S.cons a Nothing
831+ pure = ParallelT . singleton
830832 (<*>) = ap
831833
832834------------------------------------------------------------------------------
@@ -834,11 +836,10 @@ instance MonadParallel m => Applicative (ParallelT m) where
834836------------------------------------------------------------------------------
835837
836838instance Monad m => Functor (ParallelT m) where
837− fmap f (ParallelT (Stream m)) = ParallelT $ Stream $ \_ stp yld ->
838− let yield a Nothing = yld (f a) Nothing
839− yield a (Just r) = yld (f a)
840− (Just (getParallelT (fmap f (ParallelT r))))
841− in m Nothing stp yield
839+ fmap f m = fromStream $ Stream $ \_ stp sng yld ->
840+ let single = sng . f
841+ yield a r = yld (f a) (toStream $ fmap f (ParallelT r))
842+ in (S.runStream (toStream m)) Nothing stp single yield
842843
843844------------------------------------------------------------------------------
844845-- Num
@@ -892,14 +893,14 @@ instance (MonadParallel m, Floating a) => Floating (ParallelT m a) where
892893zipWith :: IsStream t => (a -> b -> c) -> t m a -> t m b -> t m c
893894zipWith f m1 m2 = fromStream $ go (toStream m1) (toStream m2)
894895 where
895− go mx my = Stream $ \_ stp yld -> do
896+ go mx my = Stream $ \_ stp sng yld -> do
896897 let merge a ra =
897− let yield2 b Nothing = yld (f a b) Nothing
898− yield2 b (Just rb) = yld (f a b) (Just (go ra rb))
899− in (S.runStream my) Nothing stp yield2
900− let yield1 a Nothing = merge a S.nil
901− yield1 a (Just ra) = merge a ra
902− (S.runStream mx) Nothing stp yield1
898+ let single2 b = sng (f a b)
899+ yield2 b rb = yld (f a b) (go ra rb)
900+ in (S.runStream my) Nothing stp single2 yield2
901+ let single1 a = merge a S.nil
902+ yield1 a ra = merge a ra
903+ (S.runStream mx) Nothing stp single1 yield1
903904
904905-- | The applicative instance of 'ZipSerial' zips a number of streams serially
905906-- i.e. it produces one element from each stream serially and then zips all
@@ -928,11 +929,10 @@ type ZipStream = ZipSerial
928929deriving instance MonadParallel m => Alternative (ZipSerial m)
929930
930931instance Monad m => Functor (ZipSerial m) where
931− fmap f (ZipSerial (Stream m)) = ZipSerial $ Stream $ \_ stp yld ->
932− let yield a Nothing = yld (f a) Nothing
933− yield a (Just r) = yld (f a)
934− (Just (getZipSerial (fmap f (ZipSerial r))))
935− in m Nothing stp yield
932+ fmap f m = fromStream $ Stream $ \_ stp sng yld ->
933+ let single = sng . f
934+ yield a r = yld (f a) (toStream $ fmap f (ZipSerial r))
935+ in (S.runStream (toStream m)) Nothing stp single yield
936936
937937instance Monad m => Applicative (ZipSerial m) where
938938 pure = ZipSerial . S.repeat
@@ -990,10 +990,10 @@ instance (Monad m, Floating a) => Floating (ZipSerial m a) where
990990-- generated concurrently) using a pure zipping function.
991991zipParallelWith :: (IsStream t, MonadParallel m)
992992 => (a -> b -> c) -> t m a -> t m b -> t m c
993−zipParallelWith f m1 m2 = fromStream $ Stream $ \_ stp yld -> do
993+zipParallelWith f m1 m2 = fromStream $ Stream $ \_ stp sng yld -> do
994994 ma <- async m1
995995 mb <- async m2
996− (S.runStream (toStream (zipWith f ma mb))) Nothing stp yld
996+ (S.runStream (toStream (zipWith f ma mb))) Nothing stp sng yld
997997
998998{-# DEPRECATED zipAsyncWith "Please use zipParallelWith instead." #-}
999999zipAsyncWith :: (IsStream t, MonadParallel m)
@@ -1025,11 +1025,10 @@ type ZipAsync = ZipParallel
10251025deriving instance MonadParallel m => Alternative (ZipParallel m)
10261026
10271027instance Monad m => Functor (ZipParallel m) where
1028− fmap f (ZipParallel (Stream m)) = ZipParallel $ Stream $ \_ stp yld ->
1029− let yield a Nothing = yld (f a) Nothing
1030− yield a (Just r) = yld (f a)
1031− (Just (getZipParallel (fmap f (ZipParallel r))))
1032− in m Nothing stp yield
1028+ fmap f m = fromStream $ Stream $ \_ stp sng yld ->
1029+ let single = sng . f
1030+ yield a r = yld (f a) (toStream $ fmap f (ZipParallel r))
1031+ in (S.runStream (toStream m)) Nothing stp single yield
10331032
10341033instance MonadParallel m => Applicative (ZipParallel m) where
10351034 pure = ZipParallel . S.repeat