1{-# LANGUAGE BangPatterns #-}
3{-# LANGUAGE ConstraintKinds #-}
4{-# LANGUAGE FlexibleContexts #-}
5{-# LANGUAGE FlexibleInstances #-}
6{-# LANGUAGE InstanceSigs #-}
7{-# LANGUAGE MultiParamTypeClasses #-}
8{-# LANGUAGE RankNTypes #-}
9{-# LANGUAGE UndecidableInstances #-} -- XXX
12-- Module : Streamly.Streams.StreamK
13-- Copyright : (c) 2017 Harendra Kumar
16-- Maintainer : harendra.kumar@gmail.com
17-- Stability : experimental
21-- Continuation passing style (CPS) stream implementation. The symbol 'K' below
22-- denotes a function as well as a Kontinuation.
25-- import qualified Streamly.Streams.StreamK as K
28module Streamly.Streams.StreamK
30 -- * A class for streams
47 -- * Asynchronous construction
60 -- ** Specialized Generation
81 -- ** Specialized Folds
109 -- ** By folding (scans)
142 -- ** Transformation comprehensions
145 -- * Semigroup Style Composition
154 , Streaming -- deprecated
159import Control.Monad (void)
160import Control.Monad.IO.Class (MonadIO(liftIO))
161import Control.Monad.Reader.Class (MonadReader(..))
162import Control.Monad.Trans.Class (MonadTrans(lift))
163import Data.Semigroup (Semigroup(..))
165 hiding (foldl, foldr, last, map, mapM, mapM_, repeat, sequence,
166 take, filter, all, any, takeWhile, drop, dropWhile, minimum,
167 maximum, elem, notElem, null, head, tail, init, zipWith, lookup,
169import qualified Prelude
173------------------------------------------------------------------------------
174-- The basic stream type
175------------------------------------------------------------------------------
177-- | The type @Stream m a@ represents a monadic stream of values of type 'a'
178-- constructed using actions in monad 'm'. It uses stop, singleton and yield
179-- continuations equivalent to the following direct style type:
182-- data Stream m a = Stop | Singleton a | Yield a (Stream m a)
185-- To facilitate parallel composition we maintain a local state in an 'SVar'
186-- that is shared across and is used for synchronization of the streams being
189-- The singleton case can be expressed in terms of stop and yield but we have
190-- it as a separate case to optimize composition operations for streams with
191-- single element. We build singleton streams in the implementation of 'pure'
192-- for Applicative and Monad, and in 'lift' for MonadTrans.
196 unStream :: forall r.
197 State Stream m a -- state
199 -> (a -> m r) -- singleton
200 -> (a -> Stream m a -> m r) -- yield
204-- XXX make this the default "unStream"
205-- | unwraps the Stream type producing the stream function that can be run with
207{-# INLINE unStreamIsolated #-}
210 -> State Stream m a -- state
212 -> (a -> m r) -- singleton
213 -> (a -> Stream m a -> m r) -- yield
215unStreamIsolated x st = unStream x (rstState st)
217{-# INLINE isolateStream #-}
218isolateStream :: Stream m a -> Stream m a
219isolateStream x = Stream $ \st stp sng yld ->
220 unStreamIsolated x st stp sng yld
222-- | Like unstream, but passes a shared SVar across continuations.
223{-# INLINE unstreamShared #-}
226 -> State Stream m a -- state
228 -> (a -> m r) -- singleton
229 -> (a -> Stream m a -> m r) -- yield
231unstreamShared = unStream
233-- Run the stream using a run function associated with the SVar that runs the
234-- streams with a captured snapshot of the monadic state.
235{-# INLINE runStreamSVar #-}
240 -> State Stream m a -- state
242 -> (a -> m r) -- singleton
243 -> (a -> Stream m a -> m r) -- yield
245runStreamSVar sv m st stp sng yld =
246 let mrun = runInIO $ svarMrun sv
247 in void $ liftIO $ mrun $ unStream m st stp sng yld
249------------------------------------------------------------------------------
250-- Types that can behave as a Stream
251------------------------------------------------------------------------------
256-- | Class of types that can represent a stream of elements of some type 'a' in
260class IsStream t where
261 toStream :: t m a -> Stream m a
262 fromStream :: Stream m a -> t m a
263 -- | Constructs a stream by adding a monadic action at the head of an
264 -- existing stream. For example:
267 -- > toList $ getLine \`consM` getLine \`consM` nil
273 -- /Concurrent (do not use 'parallely' to construct infinite streams)/
276 consM :: MonadAsync m => m a -> t m a -> t m a
277 -- | Operator equivalent of 'consM'. We can read it as "@parallel colon@"
278 -- to remember that @|@ comes before ':'.
281 -- > toList $ getLine |: getLine |: nil
288 -- let delay = threadDelay 1000000 >> print 1
289 -- runStream $ serially $ delay |: delay |: delay |: nil
290 -- runStream $ parallely $ delay |: delay |: delay |: nil
293 -- /Concurrent (do not use 'parallely' to construct infinite streams)/
296 (|:) :: MonadAsync m => m a -> t m a -> t m a
297 -- We can define (|:) just as 'consM' but it is defined explicitly for each
298 -- type because we want to use SPECIALIZE pragma on the definition.
300-- | Same as 'IsStream'.
303{-# DEPRECATED Streaming "Please use IsStream instead." #-}
304type Streaming = IsStream
306-------------------------------------------------------------------------------
307-- Type adapting combinators
308-------------------------------------------------------------------------------
310-- | Adapt any specific stream type to any other specific stream type.
313adapt :: (IsStream t1, IsStream t2) => t1 m a -> t2 m a
314adapt = fromStream . toStream
316------------------------------------------------------------------------------
318------------------------------------------------------------------------------
320-- | Build a stream from an 'SVar', a stop continuation, a singleton stream
321-- continuation and a yield continuation.
323 => (forall r. State Stream m a
326 -> (a -> t m a -> m r)
329mkStream k = fromStream $ Stream $ \st stp sng yld ->
330 let yieldk a r = yld a (toStream r)
331 in k (rstState st) stp sng yieldk
333------------------------------------------------------------------------------
335------------------------------------------------------------------------------
345nil :: IsStream t => t m a
346nil = fromStream $ Stream $ \_ stp _ _ -> stp
350-- faster than consM because there is no bind.
351-- | Construct a stream by adding a pure value at the head of an existing
352-- stream. For serial streams this is the same as @(return a) \`consM` r@ but
353-- more efficient. For concurrent streams this is not concurrent whereas
354-- 'consM' is concurrent. For example:
357-- > toList $ 1 \`cons` 2 \`cons` 3 \`cons` nil
362cons :: IsStream t => a -> t m a -> t m a
363cons a r = fromStream $ Stream $ \_ _ _ yld -> yld a (toStream r)
367-- | Operator equivalent of 'cons'.
370-- > toList $ 1 .: 2 .: 3 .: nil
375(.:) :: IsStream t => a -> t m a -> t m a
378{-# INLINE consMSerial #-}
379consMSerial :: (Monad m) => m a -> Stream m a -> Stream m a
380consMSerial m r = Stream $ \_ _ _ yld -> m >>= \a -> yld a r
382------------------------------------------------------------------------------
383-- Asynchronous construction
384------------------------------------------------------------------------------
386-- | Make an empty stream from a callback function.
387nilK :: IsStream t => (forall r. m r -> m r) -> t m a
388nilK k = fromStream $ Stream $ \_ stp _ _ -> k stp
390-- | Make a singleton stream from a one shot callback function.
391yieldK :: IsStream t => (forall r. (a -> m r) -> m r) -> t m a
392yieldK k = fromStream $ Stream $ \_ _ sng _ -> k sng
394-- | Construct a stream from a callback function.
395consK :: IsStream t => (forall r. (a -> m r) -> m r) -> t m a -> t m a
396consK k r = fromStream $ Stream $ \_ _ _ yld -> k (\x -> yld x (toStream r))
398-- XXX consK with concurrent callbacks
399-- XXX Build a stream from a repeating callback function.
401-------------------------------------------------------------------------------
403-------------------------------------------------------------------------------
405instance IsStream Stream where
410 {-# SPECIALIZE consM :: IO a -> Stream IO a -> Stream IO a #-}
411 consM :: Monad m => m a -> Stream m a -> Stream m a
415 {-# SPECIALIZE (|:) :: IO a -> Stream IO a -> Stream IO a #-}
416 (|:) :: Monad m => m a -> Stream m a -> Stream m a
419-------------------------------------------------------------------------------
421-------------------------------------------------------------------------------
424uncons :: (IsStream t, Monad m) => t m a -> m (Maybe (a, t m a))
426 let stop = return Nothing
427 single a = return (Just (a, nil))
428 yieldk a r = return (Just (a, fromStream r))
429 in unStream (toStream m) defState stop single yieldk
431-------------------------------------------------------------------------------
433-------------------------------------------------------------------------------
435{-# INLINE unfoldr #-}
436unfoldr :: IsStream t => (b -> Maybe (a, b)) -> b -> t m a
437unfoldr step = fromStream . go
439 go s = Stream $ \_ stp _ yld ->
442 Just (a, b) -> yld a (go b)
444{-# INLINE unfoldrM #-}
445unfoldrM :: (IsStream t, MonadAsync m) => (b -> m (Maybe (a, b))) -> b -> t m a
448 go s = fromStream $ Stream $ \svr stp sng yld -> do
453 unStream (toStream (return a |: go b)) svr stp sng yld
455-------------------------------------------------------------------------------
457-------------------------------------------------------------------------------
459yield :: IsStream t => a -> t m a
460yield a = fromStream $ Stream $ \_ _ single _ -> single a
463yieldM :: (Monad m, IsStream t) => m a -> t m a
464yieldM m = fromStream $ Stream $ \_ _ single _ -> m >>= single
469{-# DEPRECATED once "Please use yieldM instead." #-}
471once :: (Monad m, IsStream t) => m a -> t m a
474-- | Generate an infinite stream by repeating a pure value.
475-- Can be expressed as @cycle1 . yield@.
478repeat :: IsStream t => a -> t m a
479repeat a = let x = cons a x in x
481-------------------------------------------------------------------------------
483-------------------------------------------------------------------------------
485-- | Construct a stream from a 'Foldable' containing pure values. Same as
486-- @'Prelude.foldr' 'cons' 'nil'@.
489{-# INLINE fromFoldable #-}
490fromFoldable :: (IsStream t, Foldable f) => f a -> t m a
491fromFoldable = Prelude.foldr cons nil
493{-# INLINE fromList #-}
494fromList :: IsStream t => [a] -> t m a
495fromList = fromFoldable
497{-# INLINE fromStreamK #-}
498fromStreamK :: Stream m a -> Stream m a
501-------------------------------------------------------------------------------
502-- Elimination by Folding
503-------------------------------------------------------------------------------
505-- | Fold a stream by providing an SVar, a stop continuation, a singleton
506-- continuation and a yield continuation.
512 -> (a -> t m a -> m r)
515foldStream st blank single step m =
516 let yieldk a x = step a (fromStream x)
517 in unStream (toStream m) st blank single yieldk
519-- | Lazy right associative fold.
520foldr :: (IsStream t, Monad m) => (a -> b -> b) -> b -> t m a -> m b
521foldr step acc m = go (toStream m)
524 let stop = return acc
525 single a = return (step a acc)
526 yieldk a r = go r >>= \b -> return (step a b)
527 in unStream m1 defState stop single yieldk
529-- | Lazy right fold with a monadic step function.
531foldrM :: (IsStream t, Monad m) => (a -> b -> m b) -> b -> t m a -> m b
532foldrM step acc m = go (toStream m)
535 let stop = return acc
536 single a = step a acc
537 yieldk a r = go r >>= step a
538 in unStream m1 defState stop single yieldk
541foldr1 :: (IsStream t, Monad m) => (a -> a -> a) -> t m a -> m (Maybe a)
545 Nothing -> return Nothing
546 Just (h, t) -> fmap Just (go h (toStream t))
550 single a = return $ step a p
551 yieldk a r = fmap (step p) (go a r)
552 in unStream m1 defState stp single yieldk
554-- | Strict left fold with an extraction function. Like the standard strict
555-- left fold, but applies a user supplied extraction function (the third
556-- argument) to the folded value at the end. This is designed to work with the
557-- @foldl@ library. The suffix @x@ is a mnemonic for extraction.
559foldx :: (IsStream t, Monad m)
560 => (x -> a -> x) -> x -> (x -> b) -> t m a -> m b
561foldx step begin done m = get $ go (toStream m) begin
565 let single = return . done
566 in unStream m1 undefined undefined single undefined
568 -- Note, this can be implemented by making a recursive call to "go",
569 -- however that is more expensive because of unnecessary recursion
570 -- that cannot be tail call optimized. Unfolding recursion explicitly via
571 -- continuations is much more efficient.
572 go m1 !acc = Stream $ \_ _ sng yld ->
574 single a = sng $ step acc a
576 let stream = go r (step acc a)
577 in unStream stream defState undefined sng yld
578 in unStream m1 defState stop single yieldk
580-- | Strict left associative fold.
582foldl' :: (IsStream t, Monad m) => (b -> a -> b) -> b -> t m a -> m b
583foldl' step begin = foldx step begin id
585-- XXX replace the recursive "go" with explicit continuations.
586-- | Like 'foldx', but with a monadic step function.
587foldxM :: (IsStream t, Monad m)
588 => (x -> a -> m x) -> m x -> (x -> m b) -> t m a -> m b
589foldxM step begin done m = go begin (toStream m)
592 let stop = acc >>= done
593 single a = acc >>= \b -> step b a >>= done
594 yieldk a r = acc >>= \b -> step b a >>= \x -> go (return x) r
595 in unStream m1 defState stop single yieldk
597-- | Like 'foldl'' but with a monadic step function.
598foldlM' :: (IsStream t, Monad m) => (b -> a -> m b) -> b -> t m a -> m b
599foldlM' step begin = foldxM step (return begin) return
601------------------------------------------------------------------------------
603------------------------------------------------------------------------------
605{-# INLINE runStream #-}
606runStream :: (Monad m, IsStream t) => t m a -> m ()
607runStream m = go (toStream m)
612 yieldk _ r = go (toStream r)
613 in unStream m1 defState stop single yieldk
616null :: (IsStream t, Monad m) => t m a -> m Bool
618 let stop = return True
619 single _ = return False
620 yieldk _ _ = return False
621 in unStream (toStream m) defState stop single yieldk
624head :: (IsStream t, Monad m) => t m a -> m (Maybe a)
626 let stop = return Nothing
627 single a = return (Just a)
628 yieldk a _ = return (Just a)
629 in unStream (toStream m) defState stop single yieldk
632tail :: (IsStream t, Monad m) => t m a -> m (Maybe (t m a))
634 let stop = return Nothing
635 single _ = return $ Just nil
636 yieldk _ r = return $ Just $ fromStream r
637 in unStream (toStream m) defState stop single yieldk
640init :: (IsStream t, Monad m) => t m a -> m (Maybe (t m a))
641init m = go1 (toStream m)
646 Nothing -> return Nothing
647 Just (h, t) -> return . Just . fromStream $ go h t
648 go p m1 = Stream $ \_ stp sng yld ->
650 yieldk a x = yld p $ go a x
651 in unStream m1 defState stp single yieldk
654elem :: (IsStream t, Monad m, Eq a) => a -> t m a -> m Bool
655elem e m = go (toStream m)
658 let stop = return False
659 single a = return (a == e)
660 yieldk a r = if a == e then return True else go r
661 in unStream m1 defState stop single yieldk
663{-# INLINE notElem #-}
664notElem :: (IsStream t, Monad m, Eq a) => a -> t m a -> m Bool
665notElem e m = go (toStream m)
668 let stop = return True
669 single a = return (a /= e)
670 yieldk a r = if a == e then return False else go r
671 in unStream m1 defState stop single yieldk
673all :: (IsStream t, Monad m) => (a -> Bool) -> t m a -> m Bool
674all p m = go (toStream m)
677 let single a | p a = return True
678 | otherwise = return False
679 yieldk a r | p a = go r
680 | otherwise = return False
681 in unStream m1 defState (return True) single yieldk
683any :: (IsStream t, Monad m) => (a -> Bool) -> t m a -> m Bool
684any p m = go (toStream m)
687 let single a | p a = return True
688 | otherwise = return False
689 yieldk a r | p a = return True
691 in unStream m1 defState (return False) single yieldk
693-- | Extract the last element of the stream, if any.
695last :: (IsStream t, Monad m) => t m a -> m (Maybe a)
696last = foldx (\_ y -> Just y) Nothing id
698{-# INLINE minimum #-}
699minimum :: (IsStream t, Monad m, Ord a) => t m a -> m (Maybe a)
700minimum m = go Nothing (toStream m)
703 let stop = return Nothing
704 single a = return (Just a)
705 yieldk a r = go (Just a) r
706 in unStream m1 defState stop single yieldk
709 let stop = return (Just res)
712 then return (Just res)
718 in unStream m1 defState stop single yieldk
720{-# INLINE minimumBy #-}
721minimumBy :: (IsStream t, Monad m) => (a -> a -> Ordering) -> t m a -> m (Maybe a)
722minimumBy cmp m = go Nothing (toStream m)
725 let stop = return Nothing
726 single a = return (Just a)
727 yieldk a r = go (Just a) r
728 in unStream m1 defState stop single yieldk
731 let stop = return (Just res)
732 single a = case cmp res a of
733 GT -> return (Just a)
734 _ -> return (Just res)
735 yieldk a r = case cmp res a of
738 in unStream m1 defState stop single yieldk
740{-# INLINE maximum #-}
741maximum :: (IsStream t, Monad m, Ord a) => t m a -> m (Maybe a)
742maximum m = go Nothing (toStream m)
745 let stop = return Nothing
746 single a = return (Just a)
747 yieldk a r = go (Just a) r
748 in unStream m1 defState stop single yieldk
751 let stop = return (Just res)
755 else return (Just res)
760 in unStream m1 defState stop single yieldk
762{-# INLINE maximumBy #-}
763maximumBy :: (IsStream t, Monad m) => (a -> a -> Ordering) -> t m a -> m (Maybe a)
764maximumBy cmp m = go Nothing (toStream m)
767 let stop = return Nothing
768 single a = return (Just a)
769 yieldk a r = go (Just a) r
770 in unStream m1 defState stop single yieldk
773 let stop = return (Just res)
774 single a = case cmp res a of
775 GT -> return (Just res)
777 yieldk a r = case cmp res a of
778 GT -> go (Just res) r
780 in unStream m1 defState stop single yieldk
783(!!) :: (IsStream t, Monad m) => t m a -> Int -> m (Maybe a)
784m !! i = go i (toStream m)
787 let single a | n == 0 = return $ Just a
788 | otherwise = return Nothing
789 yieldk a x | n < 0 = return Nothing
790 | n == 0 = return $ Just a
791 | otherwise = go (n - 1) x
792 in unStream m1 defState (return Nothing) single yieldk
795lookup :: (IsStream t, Monad m, Eq a) => a -> t m (a, b) -> m (Maybe b)
796lookup e m = go (toStream m)
799 let single (a, b) | a == e = return $ Just b
800 | otherwise = return Nothing
801 yieldk (a, b) x | a == e = return $ Just b
803 in unStream m1 defState (return Nothing) single yieldk
806find :: (IsStream t, Monad m) => (a -> Bool) -> t m a -> m (Maybe a)
807find p m = go (toStream m)
810 let single a | p a = return $ Just a
811 | otherwise = return Nothing
812 yieldk a x | p a = return $ Just a
814 in unStream m1 defState (return Nothing) single yieldk
816{-# INLINE findIndices #-}
817findIndices :: IsStream t => (a -> Bool) -> t m a -> t m Int
818findIndices p = fromStream . go 0 . toStream
820 go offset m1 = Stream $ \st stp sng yld ->
821 let single a | p a = sng offset
823 yieldk a x | p a = yld offset $ go (offset + 1) x
824 | otherwise = unStream (go (offset + 1) x) st stp sng yld
825 in unStream m1 (rstState st) stp single yieldk
827------------------------------------------------------------------------------
829------------------------------------------------------------------------------
831-- | Apply a monadic action to each element of the stream and discard the
832-- output of the action.
833mapM_ :: (IsStream t, Monad m) => (a -> m b) -> t m a -> m ()
834mapM_ f m = go (toStream m)
838 single a = void (f a)
839 yieldk a r = f a >> go r
840 in unStream m1 defState stop single yieldk
842------------------------------------------------------------------------------
844------------------------------------------------------------------------------
846{-# INLINABLE toList #-}
847toList :: (IsStream t, Monad m) => t m a -> m [a]
850{-# INLINE toStreamK #-}
851toStreamK :: Stream m a -> Stream m a
854-------------------------------------------------------------------------------
855-- Transformation by folding (Scans)
856-------------------------------------------------------------------------------
859scanx :: IsStream t => (x -> a -> x) -> x -> (x -> b) -> t m a -> t m b
860scanx step begin done m =
861 cons (done begin) $ fromStream $ go (toStream m) begin
863 go m1 !acc = Stream $ \st stp sng yld ->
864 let single a = sng (done $ step acc a)
867 in yld (done s) (go r s)
868 in unStream m1 (rstState st) stp single yieldk
871scanl' :: IsStream t => (b -> a -> b) -> b -> t m a -> t m b
872scanl' step begin = scanx step begin id
874-------------------------------------------------------------------------------
876-------------------------------------------------------------------------------
879filter :: IsStream t => (a -> Bool) -> t m a -> t m a
880filter p m = fromStream $ go (toStream m)
882 go m1 = Stream $ \st stp sng yld ->
883 let single a | p a = sng a
885 yieldk a r | p a = yld a (go r)
886 | otherwise = unStream r (rstState st) stp single yieldk
887 in unStream m1 (rstState st) stp single yieldk
890take :: IsStream t => Int -> t m a -> t m a
891take n m = fromStream $ go n (toStream m)
893 go n1 m1 = Stream $ \st stp sng yld ->
894 let yieldk a r = yld a (go (n1 - 1) r)
897 else unStream m1 (rstState st) stp sng yieldk
899{-# INLINE takeWhile #-}
900takeWhile :: IsStream t => (a -> Bool) -> t m a -> t m a
901takeWhile p m = fromStream $ go (toStream m)
903 go m1 = Stream $ \st stp sng yld ->
904 let single a | p a = sng a
906 yieldk a r | p a = yld a (go r)
908 in unStream m1 (rstState st) stp single yieldk
910drop :: IsStream t => Int -> t m a -> t m a
911drop n m = fromStream $ Stream $ \st stp sng yld ->
912 unStream (go n (toStream m)) (rstState st) stp sng yld
914 go n1 m1 = Stream $ \st stp sng yld ->
916 yieldk _ r = (unStream $ go (n1 - 1) r) st stp sng yld
917 -- Somehow "<=" check performs better than a ">"
919 then unStream m1 st stp sng yld
920 else unStream m1 st stp single yieldk
922{-# INLINE dropWhile #-}
923dropWhile :: IsStream t => (a -> Bool) -> t m a -> t m a
924dropWhile p m = fromStream $ go (toStream m)
926 go m1 = Stream $ \st stp sng yld ->
927 let single a | p a = stp
929 yieldk a r | p a = unStream r (rstState st) stp single yieldk
930 | otherwise = yld a r
931 in unStream m1 (rstState st) stp single yieldk
933-------------------------------------------------------------------------------
935-------------------------------------------------------------------------------
938map :: (IsStream t, Monad m) => (a -> b) -> t m a -> t m b
939map f m = fromStream $ Stream $ \st stp sng yld ->
941 yieldk a r = yld (f a) (fmap f r)
942 in unStream (toStream m) (rstState st) stp single yieldk
944-- Be careful when modifying this, this uses a consM (|:) deliberately to allow
945-- other stream types to overload it.
947mapM :: (IsStream t, MonadAsync m) => (a -> m b) -> t m a -> t m b
948mapM f m = go (toStream m)
950 go m1 = fromStream $ Stream $ \st stp sng yld ->
951 let single a = f a >>= sng
952 yieldk a r = unStream (toStream (f a |: go r)) st stp sng yld
953 in unStream m1 (rstState st) stp single yieldk
955-- Be careful when modifying this, this uses a consM (|:) deliberately to allow
956-- other stream types to overload it.
957{-# INLINE sequence #-}
958sequence :: (IsStream t, MonadAsync m) => t m (m a) -> t m a
959sequence m = go (toStream m)
961 go m1 = fromStream $ Stream $ \st stp sng yld ->
962 let single ma = ma >>= sng
963 yieldk ma r = unStream (toStream $ ma |: go r) st stp sng yld
964 in unStream m1 (rstState st) stp single yieldk
966-------------------------------------------------------------------------------
968-------------------------------------------------------------------------------
970{-# INLINE intersperseM #-}
971intersperseM :: (IsStream t, MonadAsync m) => m a -> t m a -> t m a
972intersperseM a m = fromStream $ prependingStart (toStream m)
974 prependingStart m1 = Stream $ \st stp sng yld ->
975 let yieldk i x = unStream (return i |: go x) st stp sng yld
976 in unStream m1 (rstState st) stp sng yieldk
977 go m2 = fromStream $ Stream $ \st stp sng yld ->
978 let single i = unStream (a |: yield i) st stp sng yld
979 yieldk i x = unStream (a |: return i |: go x) st stp sng yld
980 in unStream m2 (rstState st) stp single yieldk
982{-# INLINE insertBy #-}
983insertBy :: IsStream t => (a -> a -> Ordering) -> a -> t m a -> t m a
984insertBy cmp x m = fromStream $ go (toStream m)
986 go m1 = Stream $ \st _ _ yld ->
987 let single a = case cmp x a of
988 GT -> yld a (yield x)
991 yieldk a r = case cmp x a of
993 _ -> yld x (a `cons` r)
994 in unStream m1 (rstState st) stop single yieldk
996------------------------------------------------------------------------------
998------------------------------------------------------------------------------
1000{-# INLINE deleteBy #-}
1001deleteBy :: IsStream t => (a -> a -> Bool) -> a -> t m a -> t m a
1002deleteBy eq x m = fromStream $ go (toStream m)
1004 go m1 = Stream $ \st stp sng yld ->
1005 let single a = if eq x a then stp else sng a
1006 yieldk a r = if eq x a
1007 then unStream r (rstState st) stp sng yld
1009 in unStream m1 (rstState st) stp single yieldk
1011-------------------------------------------------------------------------------
1013-------------------------------------------------------------------------------
1015{-# INLINE mapMaybe #-}
1016mapMaybe :: IsStream t => (a -> Maybe b) -> t m a -> t m b
1017mapMaybe f m = go (toStream m)
1019 go m1 = fromStream $ Stream $ \st stp sng yld ->
1020 let single a = case f a of
1023 yieldk a r = case f a of
1024 Just b -> yld b (toStream $ go r)
1025 Nothing -> unStream r (rstState st) stp single yieldk
1026 in unStream m1 (rstState st) stp single yieldk
1028------------------------------------------------------------------------------
1030------------------------------------------------------------------------------
1032{-# INLINE zipWithS #-}
1033zipWithS :: (a -> b -> c) -> Stream m a -> Stream m b -> Stream m c
1036 go mx my = Stream $ \st stp sng yld -> do
1038 let single2 b = sng (f a b)
1039 yield2 b rb = yld (f a b) (go ra rb)
1040 in unStream my (rstState st) stp single2 yield2
1041 let single1 a = merge a nil
1043 unStream mx (rstState st) stp single1 yield1
1045-- | Zip two streams serially using a pure zipping function.
1048{-# INLINABLE zipWith #-}
1049zipWith :: IsStream t => (a -> b -> c) -> t m a -> t m b -> t m c
1050zipWith f m1 m2 = fromStream $ zipWithS f (toStream m1) (toStream m2)
1052-- | Zip two streams serially using a monadic zipping function.
1055zipWithM :: (IsStream t, Monad m) => (a -> b -> m c) -> t m a -> t m b -> t m c
1056zipWithM f m1 m2 = fromStream $ go (toStream m1) (toStream m2)
1058 go mx my = Stream $ \st stp sng yld -> do
1060 let runIt x = unStream x (rstState st) stp sng yld
1061 single2 b = f a b >>= sng
1062 yield2 b rb = f a b >>= \x -> runIt (x `cons` go ra rb)
1063 in unStream my (rstState st) stp single2 yield2
1064 let single1 a = merge a nil
1066 unStream mx (rstState st) stp single1 yield1
1068------------------------------------------------------------------------------
1070------------------------------------------------------------------------------
1072data MergeWithState l r o
1074 | MergeWithLeft l r o
1075 | MergeWithRight l r o
1077{-# INLINE mergeByS #-}
1078mergeByS :: (a -> a -> Ordering) -> Stream m a -> Stream m a -> Stream m a
1079mergeByS cmp m1 m2 = go (MergeBoth m1 m2)
1081 go (MergeBoth mx my) =
1082 Stream $ \st stp sng yld -> do
1084 let single2 b = sng (cond a b)
1088 LT -> yld a (go (MergeWithRight ra rb b))
1089 _ -> yld b (go (MergeWithLeft ra rb a))
1090 in unStream my (rstState st) stop2 single2 yield2
1092 stop1 = unStream my (rstState st) stp sng yld
1093 unStream mx (rstState st) stop1 single1 yield1
1094 go (MergeWithLeft mx my x) =
1095 Stream $ \st _ sng yld -> do
1096 let single2 b = sng (cond x b)
1100 LT -> yld x (go (MergeWithRight mx rb b))
1101 _ -> yld b (go (MergeWithLeft mx rb x))
1102 unStream my (rstState st) stop2 single2 yield2
1103 go (MergeWithRight mx my x) =
1104 Stream $ \st _ sng yld -> do
1105 let single1 a = sng (cond a x)
1109 LT -> yld a (go (MergeWithRight ra my x))
1110 _ -> yld x (go (MergeWithLeft ra my a))
1111 unStream mx (rstState st) stop1 single1 yield1
1117{-# INLINABLE mergeBy #-}
1118mergeBy :: IsStream t => (a -> a -> Ordering) -> t m a -> t m a -> t m a
1119mergeBy f m1 m2 = fromStream $ mergeByS f (toStream m1) (toStream m2)
1121------------------------------------------------------------------------------
1122-- Transformation comprehensions
1123------------------------------------------------------------------------------
1126the :: (Eq a, IsStream t, Monad m) => t m a -> m (Maybe a)
1130 Nothing -> return Nothing
1131 Just (h, t) -> go h (toStream t)
1134 let single a | h == a = return $ Just h
1135 | otherwise = return Nothing
1136 yieldk a r | h == a = go h r
1137 | otherwise = return Nothing
1138 in unStream m1 defState (return $ Just h) single yieldk
1140------------------------------------------------------------------------------
1142------------------------------------------------------------------------------
1144-- | Concatenates two streams sequentially i.e. the first stream is
1145-- exhausted completely before yielding any element from the second stream.
1146{-# INLINE serial #-}
1147serial :: Stream m a -> Stream m a -> Stream m a
1150 go (Stream m) = Stream $ \st stp sng yld ->
1151 let stop = unStream m2 (rstState st) stp sng yld
1153 yieldk a r = yld a (go r)
1154 in m (rstState st) stop single yieldk
1156instance Semigroup (Stream m a) where
1159------------------------------------------------------------------------------
1161------------------------------------------------------------------------------
1163instance Monoid (Stream m a) where
1167-------------------------------------------------------------------------------
1169-------------------------------------------------------------------------------
1171instance Monad m => Functor (Stream m) where
1174-------------------------------------------------------------------------------
1176-------------------------------------------------------------------------------
1178{-# INLINE bindWith #-}
1180 :: (forall c. Stream m c -> Stream m c -> Stream m c)
1182 -> (a -> Stream m b)
1184bindWith par m f = go m
1187 Stream $ \st stp sng yld ->
1188 let runShared x = unstreamShared x st stp sng yld
1189 runIsolated x = unStreamIsolated x st stp sng yld
1191 single a = runIsolated $ f a
1192 yieldk a r = runShared $ isolateStream (f a) `par` go r
1193 in g (rstState st) stp single yieldk
1195------------------------------------------------------------------------------
1196-- Alternative & MonadPlus
1197------------------------------------------------------------------------------
1199_alt :: Stream m a -> Stream m a -> Stream m a
1200_alt m1 m2 = Stream $ \st stp sng yld ->
1201 let stop = unStream m2 (rstState st) stp sng yld
1202 in unStream m1 (rstState st) stop sng yld
1204------------------------------------------------------------------------------
1206------------------------------------------------------------------------------
1208withLocal :: MonadReader r m => (r -> r) -> Stream m a -> Stream m a
1210 Stream $ \st stp sng yld ->
1211 let single = local f . sng
1212 yieldk a r = local f $ yld a (withLocal f r)
1213 in unStream m (rstState st) (local f stp) single yieldk
1215------------------------------------------------------------------------------
1217------------------------------------------------------------------------------
1220-- XXX handle and test cross thread state transfer
1223 => Stream m a -> (e -> Stream m a) -> Stream m a
1225 Stream $ \_ stp sng yld ->
1226 let run x = unStream x Nothing stp sng yieldk
1227 handle r = r `catchError` \e -> run $ h e
1228 yieldk a r = yld a (withCatchError r h)
1232-------------------------------------------------------------------------------
1234-------------------------------------------------------------------------------
1236instance 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