1{-# LANGUAGE BangPatterns #-}
3{-# LANGUAGE ConstraintKinds #-}
4{-# LANGUAGE FlexibleContexts #-}
5{-# LANGUAGE FlexibleInstances #-}
6{-# LANGUAGE InstanceSigs #-}
7{-# LANGUAGE LambdaCase #-}
8{-# LANGUAGE MagicHash #-}
9{-# LANGUAGE MultiParamTypeClasses #-}
10{-# LANGUAGE RankNTypes #-}
11{-# LANGUAGE UnboxedTuples #-}
12{-# LANGUAGE UndecidableInstances #-} -- XXX
15-- Module : Streamly.Streams.StreamK
16-- Copyright : (c) 2017 Harendra Kumar
19-- Maintainer : harendra.kumar@gmail.com
20-- Stability : experimental
24-- Continuation passing style (CPS) stream implementation. The symbol 'K' below
25-- denotes a function as well as a Kontinuation.
28-- import qualified Streamly.Streams.StreamK as K
31module Streamly.Streams.StreamK
33 -- * A class for streams
46 -- * Asynchronous construction
59 -- ** Specialized Generation
80 -- ** Specialized Folds
105 -- ** By folding (scans)
131 -- * Semigroup Style Composition
140 , Streaming -- deprecated
145import Control.Monad (void)
146import Control.Monad.Reader.Class (MonadReader(..))
147import Control.Monad.Trans.Class (MonadTrans(lift))
148import Data.Semigroup (Semigroup(..))
150 hiding (foldl, foldr, last, map, mapM, mapM_, repeat, sequence,
151 take, filter, all, any, takeWhile, drop, dropWhile, minimum,
152 maximum, elem, notElem, null, head, tail, init, zipWith, lookup,
154import qualified Prelude
158------------------------------------------------------------------------------
159-- The basic stream type
160------------------------------------------------------------------------------
162-- | The type @Stream m a@ represents a monadic stream of values of type 'a'
163-- constructed using actions in monad 'm'. It uses stop, singleton and yield
164-- continuations equivalent to the following direct style type:
167-- data Stream m a = Stop | Singleton a | Yield a (Stream m a)
170-- To facilitate parallel composition we maintain a local state in an 'SVar'
171-- that is shared across and is used for synchronization of the streams being
174-- The singleton case can be expressed in terms of stop and yield but we have
175-- it as a separate case to optimize composition operations for streams with
176-- single element. We build singleton streams in the implementation of 'pure'
177-- for Applicative and Monad, and in 'lift' for MonadTrans.
181 unStream :: forall r.
182 State Stream m a -- state
184 -> (a -> m r) -- singleton
185 -> (a -> Stream m a -> m r) -- yield
189------------------------------------------------------------------------------
190-- Types that can behave as a Stream
191------------------------------------------------------------------------------
196-- | Class of types that can represent a stream of elements of some type 'a' in
200class IsStream t where
201 toStream :: t m a -> Stream m a
202 fromStream :: Stream m a -> t m a
203 -- | Constructs a stream by adding a monadic action at the head of an
204 -- existing stream. For example:
207 -- > toList $ getLine \`consM` getLine \`consM` nil
213 -- /Concurrent (do not use 'parallely' to construct infinite streams)/
216 consM :: MonadAsync m => m a -> t m a -> t m a
217 -- | Operator equivalent of 'consM'. We can read it as "@parallel colon@"
218 -- to remember that @|@ comes before ':'.
221 -- > toList $ getLine |: getLine |: nil
228 -- let delay = threadDelay 1000000 >> print 1
229 -- runStream $ serially $ delay |: delay |: delay |: nil
230 -- runStream $ parallely $ delay |: delay |: delay |: nil
233 -- /Concurrent (do not use 'parallely' to construct infinite streams)/
236 (|:) :: MonadAsync m => m a -> t m a -> t m a
237 -- We can define (|:) just as 'consM' but it is defined explicitly for each
238 -- type because we want to use SPECIALIZE pragma on the definition.
240-- | Same as 'IsStream'.
243{-# DEPRECATED Streaming "Please use IsStream instead." #-}
244type Streaming = IsStream
246-------------------------------------------------------------------------------
247-- Type adapting combinators
248-------------------------------------------------------------------------------
250-- | Adapt any specific stream type to any other specific stream type.
253adapt :: (IsStream t1, IsStream t2) => t1 m a -> t2 m a
254adapt = fromStream . toStream
256------------------------------------------------------------------------------
258------------------------------------------------------------------------------
260-- | Build a stream from an 'SVar', a stop continuation, a singleton stream
261-- continuation and a yield continuation.
263 => (forall r. State Stream m a
266 -> (a -> t m a -> m r)
269mkStream k = fromStream $ Stream $ \st stp sng yld ->
270 let yieldk a r = yld a (toStream r)
271 in k (rstState st) stp sng yieldk
273------------------------------------------------------------------------------
275------------------------------------------------------------------------------
285nil :: IsStream t => t m a
286nil = fromStream $ Stream $ \_ stp _ _ -> stp
290-- faster than consM because there is no bind.
291-- | Construct a stream by adding a pure value at the head of an existing
292-- stream. For serial streams this is the same as @(return a) \`consM` r@ but
293-- more efficient. For concurrent streams this is not concurrent whereas
294-- 'consM' is concurrent. For example:
297-- > toList $ 1 \`cons` 2 \`cons` 3 \`cons` nil
302cons :: IsStream t => a -> t m a -> t m a
303cons a r = fromStream $ Stream $ \_ _ _ yld -> yld a (toStream r)
307-- | Operator equivalent of 'cons'.
310-- > toList $ 1 .: 2 .: 3 .: nil
315(.:) :: IsStream t => a -> t m a -> t m a
318{-# INLINE consMSerial #-}
319consMSerial :: (Monad m) => m a -> Stream m a -> Stream m a
320consMSerial m r = Stream $ \_ _ _ yld -> m >>= \a -> yld a r
322------------------------------------------------------------------------------
323-- Asynchronous construction
324------------------------------------------------------------------------------
326-- | Make an empty stream from a callback function.
327nilK :: IsStream t => (forall r. m r -> m r) -> t m a
328nilK k = fromStream $ Stream $ \_ stp _ _ -> k stp
330-- | Make a singleton stream from a one shot callback function.
331yieldK :: IsStream t => (forall r. (a -> m r) -> m r) -> t m a
332yieldK k = fromStream $ Stream $ \_ _ sng _ -> k sng
334-- | Construct a stream from a callback function.
335consK :: IsStream t => (forall r. (a -> m r) -> m r) -> t m a -> t m a
336consK k r = fromStream $ Stream $ \_ _ _ yld -> k (\x -> yld x (toStream r))
338-- XXX consK with concurrent callbacks
339-- XXX Build a stream from a repeating callback function.
341-------------------------------------------------------------------------------
343-------------------------------------------------------------------------------
345instance IsStream Stream where
350 {-# SPECIALIZE consM :: IO a -> Stream IO a -> Stream IO a #-}
351 consM :: Monad m => m a -> Stream m a -> Stream m a
355 {-# SPECIALIZE (|:) :: IO a -> Stream IO a -> Stream IO a #-}
356 (|:) :: Monad m => m a -> Stream m a -> Stream m a
359-------------------------------------------------------------------------------
361-------------------------------------------------------------------------------
364uncons :: (IsStream t, Monad m) => t m a -> m (Maybe (a, t m a))
366 let stop = return Nothing
367 single a = return (Just (a, nil))
368 yieldk a r = return (Just (a, fromStream r))
369 in (unStream (toStream m)) defState stop single yieldk
371-------------------------------------------------------------------------------
373-------------------------------------------------------------------------------
375{-# INLINE unfoldr #-}
376unfoldr :: IsStream t => (b -> Maybe (a, b)) -> b -> t m a
377unfoldr step = fromStream . go
379 go s = Stream $ \_ stp _ yld ->
382 Just (a, b) -> yld a (go b)
384{-# INLINE unfoldrM #-}
385unfoldrM :: (IsStream t, MonadAsync m) => (b -> m (Maybe (a, b))) -> b -> t m a
388 go s = fromStream $ Stream $ \svr stp sng yld -> do
393 unStream (toStream (return a |: go b)) svr stp sng yld
395-------------------------------------------------------------------------------
397-------------------------------------------------------------------------------
399yield :: IsStream t => a -> t m a
400yield a = fromStream $ Stream $ \_ _ single _ -> single a
403yieldM :: (Monad m, IsStream t) => m a -> t m a
404yieldM m = fromStream $ Stream $ \_ _ single _ -> m >>= single
409{-# DEPRECATED once "Please use yieldM instead." #-}
411once :: (Monad m, IsStream t) => m a -> t m a
414-- | Generate an infinite stream by repeating a pure value.
417repeat :: IsStream t => a -> t m a
418repeat a = let x = cons a x in x
420-------------------------------------------------------------------------------
422-------------------------------------------------------------------------------
424-- | Construct a stream from a 'Foldable' containing pure values.
427{-# INLINE fromFoldable #-}
428fromFoldable :: (IsStream t, Foldable f) => f a -> t m a
429fromFoldable = Prelude.foldr cons nil
431{-# INLINE fromList #-}
432fromList :: IsStream t => [a] -> t m a
433fromList = fromFoldable
435{-# INLINE fromStreamK #-}
436fromStreamK :: Stream m a -> Stream m a
439-------------------------------------------------------------------------------
440-- Elimination by Folding
441-------------------------------------------------------------------------------
443-- | Fold a stream by providing an SVar, a stop continuation, a singleton
444-- continuation and a yield continuation.
450 -> (a -> t m a -> m r)
453foldStream st blank single step m =
454 let yieldk a x = step a (fromStream x)
455 in (unStream (toStream m)) st blank single yieldk
457-- | Lazy right associative fold.
458foldr :: (IsStream t, Monad m) => (a -> b -> b) -> b -> t m a -> m b
459foldr step acc m = go (toStream m)
462 let stop = return acc
463 single a = return (step a acc)
464 yieldk a r = go r >>= \b -> return (step a b)
465 in (unStream m1) defState stop single yieldk
467-- | Lazy right fold with a monadic step function.
469foldrM :: (IsStream t, Monad m) => (a -> b -> m b) -> b -> t m a -> m b
470foldrM step acc m = go (toStream m)
473 let stop = return acc
474 single a = step a acc
475 yieldk a r = go r >>= step a
476 in (unStream m1) defState stop single yieldk
479foldr1 :: (IsStream t, Monad m) => (a -> a -> a) -> t m a -> m (Maybe a)
483 Nothing -> return Nothing
484 Just (h, t) -> go h (toStream t) >>= return . Just
488 single a = return $ step a p
489 yieldk a r = go a r >>= return . (step p)
490 in unStream m1 defState stp single yieldk
492-- | Strict left fold with an extraction function. Like the standard strict
493-- left fold, but applies a user supplied extraction function (the third
494-- argument) to the folded value at the end. This is designed to work with the
495-- @foldl@ library. The suffix @x@ is a mnemonic for extraction.
497foldx :: (IsStream t, Monad m)
498 => (x -> a -> x) -> x -> (x -> b) -> t m a -> m b
499foldx step begin done m = get $ go (toStream m) begin
503 let single = return . done
504 in (unStream m1) undefined undefined single undefined
506 -- Note, this can be implemented by making a recursive call to "go",
507 -- however that is more expensive because of unnecessary recursion
508 -- that cannot be tail call optimized. Unfolding recursion explicitly via
509 -- continuations is much more efficient.
510 go m1 !acc = Stream $ \_ _ sng yld ->
512 single a = sng $ step acc a
514 let stream = go r (step acc a)
515 in (unStream stream) defState undefined sng yld
516 in (unStream m1) defState stop single yieldk
518-- | Strict left associative fold.
520foldl' :: (IsStream t, Monad m) => (b -> a -> b) -> b -> t m a -> m b
521foldl' step begin m = foldx step begin id m
523-- XXX replace the recursive "go" with explicit continuations.
524-- | Like 'foldx', but with a monadic step function.
525foldxM :: (IsStream t, Monad m)
526 => (x -> a -> m x) -> m x -> (x -> m b) -> t m a -> m b
527foldxM step begin done m = go begin (toStream m)
530 let stop = acc >>= done
531 single a = acc >>= \b -> step b a >>= done
532 yieldk a r = acc >>= \b -> step b a >>= \x -> go (return x) r
533 in (unStream m1) defState stop single yieldk
535-- | Like 'foldl'' but with a monadic step function.
536foldlM' :: (IsStream t, Monad m) => (b -> a -> m b) -> b -> t m a -> m b
537foldlM' step begin m = foldxM step (return begin) return m
539------------------------------------------------------------------------------
541------------------------------------------------------------------------------
543{-# INLINE runStream #-}
544runStream :: (Monad m, IsStream t) => t m a -> m ()
545runStream m = go (toStream m)
550 yieldk _ r = go (toStream r)
551 in unStream m1 defState stop single yieldk
554null :: (IsStream t, Monad m) => t m a -> m Bool
556 let stop = return True
557 single _ = return False
558 yieldk _ _ = return False
559 in unStream (toStream m) defState stop single yieldk
562head :: (IsStream t, Monad m) => t m a -> m (Maybe a)
564 let stop = return Nothing
565 single a = return (Just a)
566 yieldk a _ = return (Just a)
567 in unStream (toStream m) defState stop single yieldk
570tail :: (IsStream t, Monad m) => t m a -> m (Maybe (t m a))
572 let stop = return Nothing
573 single _ = return $ Just nil
574 yieldk _ r = return $ Just $ fromStream r
575 in unStream (toStream m) defState stop single yieldk
578init :: (IsStream t, Monad m) => t m a -> m (Maybe (t m a))
579init m = go1 (toStream m)
584 Nothing -> return Nothing
585 Just (h, t) -> return . Just . fromStream $ go h t
586 go p m1 = Stream $ \_ stp sng yld ->
588 yieldk a x = yld p $ go a x
589 in unStream m1 defState stp single yieldk
592elem :: (IsStream t, Monad m, Eq a) => a -> t m a -> m Bool
593elem e m = go (toStream m)
596 let stop = return False
597 single a = return (a == e)
598 yieldk a r = if a == e then return True else go r
599 in (unStream m1) defState stop single yieldk
601{-# INLINE notElem #-}
602notElem :: (IsStream t, Monad m, Eq a) => a -> t m a -> m Bool
603notElem e m = go (toStream m)
606 let stop = return True
607 single a = return (a /= e)
608 yieldk a r = if a == e then return False else go r
609 in (unStream m1) defState stop single yieldk
611all :: (IsStream t, Monad m) => (a -> Bool) -> t m a -> m Bool
612all p m = go (toStream m)
615 let single a | p a = return True
616 | otherwise = return False
617 yieldk a r | p a = go r
618 | otherwise = return False
619 in unStream m1 defState (return True) single yieldk
621any :: (IsStream t, Monad m) => (a -> Bool) -> t m a -> m Bool
622any p m = go (toStream m)
625 let single a | p a = return True
626 | otherwise = return False
627 yieldk a r | p a = return True
629 in unStream m1 defState (return False) single yieldk
631-- | Extract the last element of the stream, if any.
633last :: (IsStream t, Monad m) => t m a -> m (Maybe a)
634last = foldx (\_ y -> Just y) Nothing id
636{-# INLINE minimum #-}
637minimum :: (IsStream t, Monad m, Ord a) => t m a -> m (Maybe a)
638minimum m = go Nothing (toStream m)
641 let stop = return Nothing
642 single a = return (Just a)
643 yieldk a r = go (Just a) r
644 in unStream m1 defState stop single yieldk
647 let stop = return (Just res)
650 then return (Just res)
656 in unStream m1 defState stop single yieldk
658{-# INLINE maximum #-}
659maximum :: (IsStream t, Monad m, Ord a) => t m a -> m (Maybe a)
660maximum m = go Nothing (toStream m)
663 let stop = return Nothing
664 single a = return (Just a)
665 yieldk a r = go (Just a) r
666 in unStream m1 defState stop single yieldk
669 let stop = return (Just res)
673 else return (Just res)
678 in unStream m1 defState stop single yieldk
681lookup :: (IsStream t, Monad m, Eq a) => a -> t m (a, b) -> m (Maybe b)
682lookup e m = go (toStream m)
685 let single (a, b) | a == e = return $ Just b
686 | otherwise = return Nothing
687 yieldk (a, b) x | a == e = return $ Just b
689 in unStream m1 defState (return Nothing) single yieldk
692find :: (IsStream t, Monad m) => (a -> Bool) -> t m a -> m (Maybe a)
693find p m = go (toStream m)
696 let single a | p a = return $ Just a
697 | otherwise = return Nothing
698 yieldk a x | p a = return $ Just a
700 in unStream m1 defState (return Nothing) single yieldk
702{-# INLINE findIndices #-}
703findIndices :: IsStream t => (a -> Bool) -> t m a -> t m Int
704findIndices p = fromStream . go 0 . toStream
706 go offset m1 = Stream $ \st stp sng yld ->
707 let single a | p a = sng offset
709 yieldk a x | p a = yld offset $ go (offset + 1) x
710 | otherwise = unStream (go (offset + 1) x) st stp sng yld
711 in unStream m1 (rstState st) stp single yieldk
713------------------------------------------------------------------------------
715------------------------------------------------------------------------------
717-- | Apply a monadic action to each element of the stream and discard the
718-- output of the action.
719mapM_ :: (IsStream t, Monad m) => (a -> m b) -> t m a -> m ()
720mapM_ f m = go (toStream m)
724 single a = void (f a)
725 yieldk a r = f a >> go r
726 in (unStream m1) defState stop single yieldk
728------------------------------------------------------------------------------
730------------------------------------------------------------------------------
732{-# INLINABLE toList #-}
733toList :: (IsStream t, Monad m) => t m a -> m [a]
736{-# INLINE toStreamK #-}
737toStreamK :: Stream m a -> Stream m a
740-------------------------------------------------------------------------------
741-- Transformation by folding (Scans)
742-------------------------------------------------------------------------------
745scanx :: IsStream t => (x -> a -> x) -> x -> (x -> b) -> t m a -> t m b
746scanx step begin done m =
747 cons (done begin) $ fromStream $ go (toStream m) begin
749 go m1 !acc = Stream $ \st stp sng yld ->
750 let single a = sng (done $ step acc a)
753 in yld (done s) (go r s)
754 in unStream m1 (rstState st) stp single yieldk
757scanl' :: IsStream t => (b -> a -> b) -> b -> t m a -> t m b
758scanl' step begin m = scanx step begin id m
760-------------------------------------------------------------------------------
762-------------------------------------------------------------------------------
765filter :: IsStream t => (a -> Bool) -> t m a -> t m a
766filter p m = fromStream $ go (toStream m)
768 go m1 = Stream $ \st stp sng yld ->
769 let single a | p a = sng a
771 yieldk a r | p a = yld a (go r)
772 | otherwise = (unStream r) (rstState st) stp single yieldk
773 in unStream m1 (rstState st) stp single yieldk
776take :: IsStream t => Int -> t m a -> t m a
777take n m = fromStream $ go n (toStream m)
779 go n1 m1 = Stream $ \st stp sng yld ->
780 let yieldk a r = yld a (go (n1 - 1) r)
783 else unStream m1 (rstState st) stp sng yieldk
785{-# INLINE takeWhile #-}
786takeWhile :: IsStream t => (a -> Bool) -> t m a -> t m a
787takeWhile p m = fromStream $ go (toStream m)
789 go m1 = Stream $ \st stp sng yld ->
790 let single a | p a = sng a
792 yieldk a r | p a = yld a (go r)
794 in unStream m1 (rstState st) stp single yieldk
796drop :: IsStream t => Int -> t m a -> t m a
797drop n m = fromStream $ Stream $ \st stp sng yld ->
798 unStream (go n (toStream m)) (rstState st) stp sng yld
800 go n1 m1 = Stream $ \st stp sng yld ->
802 yieldk _ r = (unStream $ go (n1 - 1) r) st stp sng yld
803 -- Somehow "<=" check performs better than a ">"
805 then unStream m1 st stp sng yld
806 else unStream m1 st stp single yieldk
808{-# INLINE dropWhile #-}
809dropWhile :: IsStream t => (a -> Bool) -> t m a -> t m a
810dropWhile p m = fromStream $ go (toStream m)
812 go m1 = Stream $ \st stp sng yld ->
813 let single a | p a = stp
815 yieldk a r | p a = (unStream r) (rstState st) stp single yieldk
816 | otherwise = yld a r
817 in unStream m1 (rstState st) stp single yieldk
819-------------------------------------------------------------------------------
821-------------------------------------------------------------------------------
824map :: (IsStream t, Monad m) => (a -> b) -> t m a -> t m b
825map f m = fromStream $ Stream $ \st stp sng yld ->
827 yieldk a r = yld (f a) (fmap f r)
828 in unStream (toStream m) (rstState st) stp single yieldk
830-- Be careful when modifying this, this uses a consM (|:) deliberately to allow
831-- other stream types to overload it.
833mapM :: (IsStream t, MonadAsync m) => (a -> m b) -> t m a -> t m b
834mapM f m = go (toStream m)
836 go m1 = fromStream $ Stream $ \st stp sng yld ->
837 let single a = f a >>= sng
838 yieldk a r = unStream (toStream (f a |: (go r))) st stp sng yld
839 in (unStream m1) (rstState st) stp single yieldk
841-- Be careful when modifying this, this uses a consM (|:) deliberately to allow
842-- other stream types to overload it.
843{-# INLINE sequence #-}
844sequence :: (IsStream t, MonadAsync m) => t m (m a) -> t m a
845sequence m = go (toStream m)
847 go m1 = fromStream $ Stream $ \st stp sng yld ->
848 let single ma = ma >>= sng
849 yieldk ma r = unStream (toStream $ ma |: go r) st stp sng yld
850 in (unStream m1) (rstState st) stp single yieldk
852-------------------------------------------------------------------------------
854-------------------------------------------------------------------------------
856{-# INLINE intersperseM #-}
857intersperseM :: (IsStream t, MonadAsync m) => m a -> t m a -> t m a
858intersperseM a m = fromStream $ prependingStart (toStream m)
860 prependingStart m1 = Stream $ \st stp sng yld ->
861 let yieldk i x = unStream (return i |: go x) st stp sng yld
862 in unStream m1 (rstState st) stp sng yieldk
863 go m2 = fromStream $ Stream $ \st stp sng yld ->
864 let single i = unStream (a |: yield i) st stp sng yld
865 yieldk i x = unStream (a |: return i |: go x) st stp sng yld
866 in unStream m2 (rstState st) stp single yieldk
868-------------------------------------------------------------------------------
870-------------------------------------------------------------------------------
872{-# INLINE mapMaybe #-}
873mapMaybe :: IsStream t => (a -> Maybe b) -> t m a -> t m b
874mapMaybe f m = go (toStream m)
876 go m1 = fromStream $ Stream $ \st stp sng yld ->
877 let single a = case f a of
880 yieldk a r = case f a of
881 Just b -> yld b (toStream $ go r)
882 Nothing -> (unStream r) (rstState st) stp single yieldk
883 in unStream m1 (rstState st) stp single yieldk
885------------------------------------------------------------------------------
887------------------------------------------------------------------------------
889{-# INLINE zipWithS #-}
890zipWithS :: (a -> b -> c) -> Stream m a -> Stream m b -> Stream m c
891zipWithS f m1 m2 = go m1 m2
893 go mx my = Stream $ \st stp sng yld -> do
895 let single2 b = sng (f a b)
896 yield2 b rb = yld (f a b) (go ra rb)
897 in unStream my (rstState st) stp single2 yield2
898 let single1 a = merge a nil
899 yield1 a ra = merge a ra
900 unStream mx (rstState st) stp single1 yield1
902-- | Zip two streams serially using a pure zipping function.
905{-# INLINABLE zipWith #-}
906zipWith :: IsStream t => (a -> b -> c) -> t m a -> t m b -> t m c
907zipWith f m1 m2 = fromStream $ zipWithS f (toStream m1) (toStream m2)
909-- | Zip two streams serially using a monadic zipping function.
912zipWithM :: (IsStream t, Monad m) => (a -> b -> m c) -> t m a -> t m b -> t m c
913zipWithM f m1 m2 = fromStream $ go (toStream m1) (toStream m2)
915 go mx my = Stream $ \st stp sng yld -> do
917 let runIt x = unStream x (rstState st) stp sng yld
918 single2 b = f a b >>= sng
919 yield2 b rb = f a b >>= \x -> runIt (x `cons` go ra rb)
920 in unStream my (rstState st) stp single2 yield2
921 let single1 a = merge a nil
922 yield1 a ra = merge a ra
923 unStream mx (rstState st) stp single1 yield1
925------------------------------------------------------------------------------
927------------------------------------------------------------------------------
929-- | Concatenates two streams sequentially i.e. the first stream is
930-- exhausted completely before yielding any element from the second stream.
932serial :: Stream m a -> Stream m a -> Stream m a
935 go (Stream m) = Stream $ \st stp sng yld ->
936 let stop = (unStream m2) (rstState st) stp sng yld
938 yieldk a r = yld a (go r)
939 in m (rstState st) stop single yieldk
941instance Semigroup (Stream m a) where
944------------------------------------------------------------------------------
946------------------------------------------------------------------------------
948instance Monoid (Stream m a) where
952-------------------------------------------------------------------------------
954-------------------------------------------------------------------------------
956instance Monad m => Functor (Stream m) where
959-------------------------------------------------------------------------------
961-------------------------------------------------------------------------------
963{-# INLINE bindWith #-}
965 :: (forall c. Stream m c -> Stream m c -> Stream m c)
969bindWith par m f = go m
972 Stream $ \st stp sng yld ->
973 let run x = (unStream x) st stp sng yld
975 yieldk a r = run $ f a `par` go r
976 in g (rstState st) stp single yieldk
978------------------------------------------------------------------------------
979-- Alternative & MonadPlus
980------------------------------------------------------------------------------
982_alt :: Stream m a -> Stream m a -> Stream m a
983_alt m1 m2 = Stream $ \st stp sng yld ->
984 let stop = unStream m2 (rstState st) stp sng yld
985 in unStream m1 (rstState st) stop sng yld
987------------------------------------------------------------------------------
989------------------------------------------------------------------------------
991withLocal :: MonadReader r m => (r -> r) -> Stream m a -> Stream m a
993 Stream $ \st stp sng yld ->
994 let single = local f . sng
995 yieldk a r = local f $ yld a (withLocal f r)
996 in (unStream m) (rstState st) (local f stp) single yieldk
998------------------------------------------------------------------------------
1000------------------------------------------------------------------------------
1003-- XXX handle and test cross thread state transfer
1006 => Stream m a -> (e -> Stream m a) -> Stream m a
1008 Stream $ \_ stp sng yld ->
1009 let run x = unStream x Nothing stp sng yieldk
1010 handle r = r `catchError` \e -> run $ h e
1011 yieldk a r = yld a (withCatchError r h)
1015-------------------------------------------------------------------------------
1017-------------------------------------------------------------------------------
1019instance MonadTrans Stream where
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list