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
79 -- ** Specialized Folds
104 -- ** By folding (scans)
127 -- * Semigroup Style Composition
136 , Streaming -- deprecated
141import Control.Monad (void)
142import Control.Monad.Reader.Class (MonadReader(..))
143import Control.Monad.Trans.Class (MonadTrans(lift))
144import Data.Semigroup (Semigroup(..))
146 hiding (foldl, foldr, last, map, mapM, mapM_, repeat, sequence,
147 take, filter, all, any, takeWhile, drop, dropWhile, minimum,
148 maximum, elem, notElem, null, head, tail, init, zipWith, lookup)
149import qualified Prelude
153------------------------------------------------------------------------------
154-- The basic stream type
155------------------------------------------------------------------------------
157-- | The type @Stream m a@ represents a monadic stream of values of type 'a'
158-- constructed using actions in monad 'm'. It uses stop, singleton and yield
159-- continuations equivalent to the following direct style type:
162-- data Stream m a = Stop | Singleton a | Yield a (Stream m a)
165-- To facilitate parallel composition we maintain a local state in an 'SVar'
166-- that is shared across and is used for synchronization of the streams being
169-- The singleton case can be expressed in terms of stop and yield but we have
170-- it as a separate case to optimize composition operations for streams with
171-- single element. We build singleton streams in the implementation of 'pure'
172-- for Applicative and Monad, and in 'lift' for MonadTrans.
176 unStream :: forall r.
177 State Stream m a -- state
179 -> (a -> m r) -- singleton
180 -> (a -> Stream m a -> m r) -- yield
184------------------------------------------------------------------------------
185-- Types that can behave as a Stream
186------------------------------------------------------------------------------
191-- | Class of types that can represent a stream of elements of some type 'a' in
195class IsStream t where
196 toStream :: t m a -> Stream m a
197 fromStream :: Stream m a -> t m a
198 -- | Constructs a stream by adding a monadic action at the head of an
199 -- existing stream. For example:
202 -- > toList $ getLine \`consM` getLine \`consM` nil
208 -- /Concurrent (do not use 'parallely' to construct infinite streams)/
211 consM :: MonadAsync m => m a -> t m a -> t m a
212 -- | Operator equivalent of 'consM'. We can read it as "@parallel colon@"
213 -- to remember that @|@ comes before ':'.
216 -- > toList $ getLine |: getLine |: nil
223 -- let delay = threadDelay 1000000 >> print 1
224 -- runStream $ serially $ delay |: delay |: delay |: nil
225 -- runStream $ parallely $ delay |: delay |: delay |: nil
228 -- /Concurrent (do not use 'parallely' to construct infinite streams)/
231 (|:) :: MonadAsync m => m a -> t m a -> t m a
232 -- We can define (|:) just as 'consM' but it is defined explicitly for each
233 -- type because we want to use SPECIALIZE pragma on the definition.
235-- | Same as 'IsStream'.
238{-# DEPRECATED Streaming "Please use IsStream instead." #-}
239type Streaming = IsStream
241-------------------------------------------------------------------------------
242-- Type adapting combinators
243-------------------------------------------------------------------------------
245-- | Adapt any specific stream type to any other specific stream type.
248adapt :: (IsStream t1, IsStream t2) => t1 m a -> t2 m a
249adapt = fromStream . toStream
251------------------------------------------------------------------------------
253------------------------------------------------------------------------------
255-- | Build a stream from an 'SVar', a stop continuation, a singleton stream
256-- continuation and a yield continuation.
258 => (forall r. State Stream m a
261 -> (a -> t m a -> m r)
264mkStream k = fromStream $ Stream $ \st stp sng yld ->
265 let yieldk a r = yld a (toStream r)
266 in k (rstState st) stp sng yieldk
268------------------------------------------------------------------------------
270------------------------------------------------------------------------------
280nil :: IsStream t => t m a
281nil = fromStream $ Stream $ \_ stp _ _ -> stp
285-- faster than consM because there is no bind.
286-- | Construct a stream by adding a pure value at the head of an existing
287-- stream. For serial streams this is the same as @(return a) \`consM` r@ but
288-- more efficient. For concurrent streams this is not concurrent whereas
289-- 'consM' is concurrent. For example:
292-- > toList $ 1 \`cons` 2 \`cons` 3 \`cons` nil
297cons :: IsStream t => a -> t m a -> t m a
298cons a r = fromStream $ Stream $ \_ _ _ yld -> yld a (toStream r)
302-- | Operator equivalent of 'cons'.
305-- > toList $ 1 .: 2 .: 3 .: nil
310(.:) :: IsStream t => a -> t m a -> t m a
313{-# INLINE consMSerial #-}
314consMSerial :: (Monad m) => m a -> Stream m a -> Stream m a
315consMSerial m r = Stream $ \_ _ _ yld -> m >>= \a -> yld a r
317------------------------------------------------------------------------------
318-- Asynchronous construction
319------------------------------------------------------------------------------
321-- | Make an empty stream from a callback function.
322nilK :: IsStream t => (forall r. m r -> m r) -> t m a
323nilK k = fromStream $ Stream $ \_ stp _ _ -> k stp
325-- | Make a singleton stream from a one shot callback function.
326yieldK :: IsStream t => (forall r. (a -> m r) -> m r) -> t m a
327yieldK k = fromStream $ Stream $ \_ _ sng _ -> k sng
329-- | Construct a stream from a callback function.
330consK :: IsStream t => (forall r. (a -> m r) -> m r) -> t m a -> t m a
331consK k r = fromStream $ Stream $ \_ _ _ yld -> k (\x -> yld x (toStream r))
333-- XXX consK with concurrent callbacks
334-- XXX Build a stream from a repeating callback function.
336-------------------------------------------------------------------------------
338-------------------------------------------------------------------------------
340instance IsStream Stream where
345 {-# SPECIALIZE consM :: IO a -> Stream IO a -> Stream IO a #-}
346 consM :: Monad m => m a -> Stream m a -> Stream m a
350 {-# SPECIALIZE (|:) :: IO a -> Stream IO a -> Stream IO a #-}
351 (|:) :: Monad m => m a -> Stream m a -> Stream m a
354-------------------------------------------------------------------------------
356-------------------------------------------------------------------------------
359uncons :: (IsStream t, Monad m) => t m a -> m (Maybe (a, t m a))
361 let stop = return Nothing
362 single a = return (Just (a, nil))
363 yieldk a r = return (Just (a, fromStream r))
364 in (unStream (toStream m)) defState stop single yieldk
366-------------------------------------------------------------------------------
368-------------------------------------------------------------------------------
370{-# INLINE unfoldr #-}
371unfoldr :: IsStream t => (b -> Maybe (a, b)) -> b -> t m a
372unfoldr step = fromStream . go
374 go s = Stream $ \_ stp _ yld ->
377 Just (a, b) -> yld a (go b)
379{-# INLINE unfoldrM #-}
380unfoldrM :: (IsStream t, MonadAsync m) => (b -> m (Maybe (a, b))) -> b -> t m a
383 go s = fromStream $ Stream $ \svr stp sng yld -> do
388 unStream (toStream (return a |: go b)) svr stp sng yld
390-------------------------------------------------------------------------------
392-------------------------------------------------------------------------------
394-- Faster than yieldM because there is no bind. Usually we can construct a
395-- stream from a pure value using "pure" in an applicative, however in case of
396-- Zip streams pure creates an infinite stream.
398-- | Create a singleton stream from a pure value. In monadic streams, 'pure' or
399-- 'return' can be used in place of 'yield', however, in Zip applicative
400-- streams 'pure' is equivalent to 'repeat'.
403yield :: IsStream t => a -> t m a
404yield a = fromStream $ Stream $ \_ _ single _ -> single a
406-- | Create a singleton stream from a monadic action. Same as @m \`consM` nil@
407-- but more efficient.
410-- > toList $ yieldM getLine
417yieldM :: (Monad m, IsStream t) => m a -> t m a
418yieldM m = fromStream $ Stream $ \_ _ single _ -> m >>= single
423{-# DEPRECATED once "Please use yieldM instead." #-}
425once :: (Monad m, IsStream t) => m a -> t m a
428-- | Generate an infinite stream by repeating a pure value.
431repeat :: IsStream t => a -> t m a
432repeat a = let x = cons a x in x
434-------------------------------------------------------------------------------
436-------------------------------------------------------------------------------
438-- | Construct a stream from a 'Foldable' containing pure values.
441{-# INLINE fromFoldable #-}
442fromFoldable :: (IsStream t, Foldable f) => f a -> t m a
443fromFoldable = Prelude.foldr cons nil
445{-# INLINE fromList #-}
446fromList :: IsStream t => [a] -> t m a
447fromList = fromFoldable
449{-# INLINE fromStreamK #-}
450fromStreamK :: Stream m a -> Stream m a
453-------------------------------------------------------------------------------
454-- Elimination by Folding
455-------------------------------------------------------------------------------
457-- | Fold a stream by providing an SVar, a stop continuation, a singleton
458-- continuation and a yield continuation.
464 -> (a -> t m a -> m r)
467foldStream st blank single step m =
468 let yieldk a x = step a (fromStream x)
469 in (unStream (toStream m)) st blank single yieldk
471-- | Lazy right associative fold.
472foldr :: (IsStream t, Monad m) => (a -> b -> b) -> b -> t m a -> m b
473foldr step acc m = go (toStream m)
476 let stop = return acc
477 single a = return (step a acc)
478 yieldk a r = go r >>= \b -> return (step a b)
479 in (unStream m1) defState stop single yieldk
481-- | Lazy right fold with a monadic step function.
483foldrM :: (IsStream t, Monad m) => (a -> b -> m b) -> b -> t m a -> m b
484foldrM step acc m = go (toStream m)
487 let stop = return acc
488 single a = step a acc
489 yieldk a r = go r >>= step a
490 in (unStream m1) defState stop 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 mapMaybe #-}
857mapMaybe :: IsStream t => (a -> Maybe b) -> t m a -> t m b
858mapMaybe f m = go (toStream m)
860 go m1 = fromStream $ Stream $ \st stp sng yld ->
861 let single a = case f a of
864 yieldk a r = case f a of
865 Just b -> yld b (toStream $ go r)
866 Nothing -> (unStream r) (rstState st) stp single yieldk
867 in unStream m1 (rstState st) stp single yieldk
869------------------------------------------------------------------------------
871------------------------------------------------------------------------------
873{-# INLINE zipWithS #-}
874zipWithS :: (a -> b -> c) -> Stream m a -> Stream m b -> Stream m c
875zipWithS f m1 m2 = go m1 m2
877 go mx my = Stream $ \st stp sng yld -> do
879 let single2 b = sng (f a b)
880 yield2 b rb = yld (f a b) (go ra rb)
881 in unStream my (rstState st) stp single2 yield2
882 let single1 a = merge a nil
883 yield1 a ra = merge a ra
884 unStream mx (rstState st) stp single1 yield1
886-- | Zip two streams serially using a pure zipping function.
889{-# INLINABLE zipWith #-}
890zipWith :: IsStream t => (a -> b -> c) -> t m a -> t m b -> t m c
891zipWith f m1 m2 = fromStream $ zipWithS f (toStream m1) (toStream m2)
893-- | Zip two streams serially using a monadic zipping function.
896zipWithM :: (IsStream t, Monad m) => (a -> b -> m c) -> t m a -> t m b -> t m c
897zipWithM f m1 m2 = fromStream $ go (toStream m1) (toStream m2)
899 go mx my = Stream $ \st stp sng yld -> do
901 let runIt x = unStream x (rstState st) stp sng yld
902 single2 b = f a b >>= sng
903 yield2 b rb = f a b >>= \x -> runIt (x `cons` go ra rb)
904 in unStream my (rstState st) stp single2 yield2
905 let single1 a = merge a nil
906 yield1 a ra = merge a ra
907 unStream mx (rstState st) stp single1 yield1
909------------------------------------------------------------------------------
911------------------------------------------------------------------------------
913-- | Concatenates two streams sequentially i.e. the first stream is
914-- exhausted completely before yielding any element from the second stream.
916serial :: Stream m a -> Stream m a -> Stream m a
919 go (Stream m) = Stream $ \st stp sng yld ->
920 let stop = (unStream m2) (rstState st) stp sng yld
922 yieldk a r = yld a (go r)
923 in m (rstState st) stop single yieldk
925instance Semigroup (Stream m a) where
928------------------------------------------------------------------------------
930------------------------------------------------------------------------------
932instance Monoid (Stream m a) where
936-------------------------------------------------------------------------------
938-------------------------------------------------------------------------------
940instance Monad m => Functor (Stream m) where
943-------------------------------------------------------------------------------
945-------------------------------------------------------------------------------
947{-# INLINE bindWith #-}
949 :: (forall c. Stream m c -> Stream m c -> Stream m c)
953bindWith par m f = go m
956 Stream $ \st stp sng yld ->
957 let run x = (unStream x) st stp sng yld
959 yieldk a r = run $ f a `par` go r
960 in g (rstState st) stp single yieldk
962------------------------------------------------------------------------------
963-- Alternative & MonadPlus
964------------------------------------------------------------------------------
966_alt :: Stream m a -> Stream m a -> Stream m a
967_alt m1 m2 = Stream $ \st stp sng yld ->
968 let stop = unStream m2 (rstState st) stp sng yld
969 in unStream m1 (rstState st) stop sng yld
971------------------------------------------------------------------------------
973------------------------------------------------------------------------------
975withLocal :: MonadReader r m => (r -> r) -> Stream m a -> Stream m a
977 Stream $ \st stp sng yld ->
978 let single = local f . sng
979 yieldk a r = local f $ yld a (withLocal f r)
980 in (unStream m) (rstState st) (local f stp) single yieldk
982------------------------------------------------------------------------------
984------------------------------------------------------------------------------
987-- XXX handle and test cross thread state transfer
990 => Stream m a -> (e -> Stream m a) -> Stream m a
992 Stream $ \_ stp sng yld ->
993 let run x = unStream x Nothing stp sng yieldk
994 handle r = r `catchError` \e -> run $ h e
995 yieldk a r = yld a (withCatchError r h)
999-------------------------------------------------------------------------------
1001-------------------------------------------------------------------------------
1003instance 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