1{-# LANGUAGE BangPatterns #-}
3{-# LANGUAGE ConstraintKinds #-}
4{-# LANGUAGE ExistentialQuantification #-}
5{-# LANGUAGE FlexibleContexts #-}
6{-# LANGUAGE FlexibleInstances #-}
7{-# LANGUAGE MultiParamTypeClasses #-}
8{-# LANGUAGE PatternSynonyms #-}
9{-# LANGUAGE ViewPatterns #-}
10{-# LANGUAGE RankNTypes #-}
15-- Module : Streamly.Streams.StreamD
16-- Copyright : (c) 2018 Harendra Kumar
17-- Copyright : (c) Roman Leshchinskiy 2008-2010
20-- Maintainer : harendra.kumar@gmail.com
21-- Stability : experimental
24-- Direct style re-implementation of CPS style stream in StreamK module. The
25-- symbol or suffix 'D' in this module denotes the "Direct" style. GHC is able
26-- to INLINE and fuse direct style better, providing better performance than
30-- import qualified Streamly.Streams.StreamD as D
33-- Some of the functions in this file have been adapted from the vector
34-- library, https://hackage.haskell.org/package/vector.
36module Streamly.Streams.StreamD
54 -- ** Specialized Generation
55 -- | Generate a monadic stream from a seed.
65 , enumerateFromStepIntegral
66 , enumerateFromIntegral
67 , enumerateFromThenIntegral
68 , enumerateFromToIntegral
69 , enumerateFromThenToIntegral
71 , enumerateFromStepNum
74 , enumerateFromToFractional
75 , enumerateFromThenToFractional
78 -- | Transform an input structure into a stream.
79 -- | Direct style stream does not support @fromFoldable@.
95 -- ** Specialized Folds
126 -- | Transform a stream into another type.
132 -- ** By folding (scans)
189 -- * Transformation comprehensions
194import Data.Maybe (fromJust, isJust)
195import GHC.Types ( SPEC(..) )
197 hiding (map, mapM, mapM_, repeat, foldr, last, take, filter,
198 takeWhile, drop, dropWhile, all, any, maximum, minimum, elem,
199 notElem, null, head, tail, zipWith, lookup, foldr1, sequence,
200 (!!), scanl, scanl1, concatMap, replicate, enumFromTo)
202import Streamly.SVar (MonadAsync, defState, adaptState)
204import Streamly.Streams.StreamD.Type
205import qualified Streamly.Streams.StreamK as K
207------------------------------------------------------------------------------
209------------------------------------------------------------------------------
211-- | An empty 'Stream'.
212{-# INLINE_NORMAL nil #-}
213nil :: Monad m => Stream m a
214nil = Stream (\_ _ -> return Stop) ()
216-- | Can fuse but has O(n^2) complexity.
217{-# INLINE_NORMAL cons #-}
218cons :: Monad m => a -> Stream m a -> Stream m a
219cons x (Stream step state) = Stream step1 Nothing
221 {-# INLINE_LATE step1 #-}
222 step1 _ Nothing = return $ Yield x (Just state)
223 step1 gst (Just st) = do
227 Yield a s -> Yield a (Just s)
228 Skip s -> Skip (Just s)
231-------------------------------------------------------------------------------
233-------------------------------------------------------------------------------
235-- Does not fuse, has the same performance as the StreamK version.
236{-# INLINE_NORMAL uncons #-}
237uncons :: Monad m => Stream m a -> m (Maybe (a, Stream m a))
238uncons (UnStream step state) = go state
241 r <- step defState st
243 Yield x s -> return $ Just (x, Stream step s)
245 Stop -> return Nothing
247------------------------------------------------------------------------------
248-- Generation by unfold
249------------------------------------------------------------------------------
251{-# INLINE_NORMAL unfoldrM #-}
252unfoldrM :: Monad m => (s -> m (Maybe (a, s))) -> s -> Stream m a
253unfoldrM next state = Stream step state
255 {-# INLINE_LATE step #-}
259 Just (x, s) -> Yield x s
262{-# INLINE_LATE unfoldr #-}
263unfoldr :: Monad m => (s -> Maybe (a, s)) -> s -> Stream m a
264unfoldr f = unfoldrM (return . f)
266------------------------------------------------------------------------------
267-- Specialized Generation
268------------------------------------------------------------------------------
270repeat :: Monad m => a -> Stream m a
271repeat x = Stream (\_ _ -> return $ Yield x ()) ()
273{-# INLINE_NORMAL replicateM #-}
274replicateM :: Monad m => Int -> m a -> Stream m a
275replicateM n p = Stream step n
277 {-# INLINE_LATE step #-}
278 step _ i | i <= 0 = return Stop
281 return $ Yield x (i - 1)
283{-# INLINE_NORMAL replicate #-}
284replicate :: Monad m => Int -> a -> Stream m a
285replicate n x = replicateM n (return x)
287-- This would not work properly for floats, therefore we put an Integral
289-- | Can be used to enumerate unbounded integrals. This does not check for
290-- overflow or underflow for bounded integrals.
291{-# INLINE_NORMAL enumerateFromStepIntegral #-}
292enumerateFromStepIntegral :: (Integral a, Monad m) => a -> a -> Stream m a
293enumerateFromStepIntegral from stride =
294 from `seq` stride `seq` Stream step from
296 {-# INLINE_LATE step #-}
297 step _ !x = return $ Yield x $! (x + stride)
299-- We are assuming that "to" is constrained by the type to be within
301{-# INLINE enumerateFromToIntegral #-}
302enumerateFromToIntegral :: (Monad m, Integral a) => a -> a -> Stream m a
303enumerateFromToIntegral from to =
304 takeWhile (<= to) $ enumerateFromStepIntegral from 1
306{-# INLINE enumerateFromIntegral #-}
307enumerateFromIntegral :: (Monad m, Integral a, Bounded a) => a -> Stream m a
308enumerateFromIntegral from = enumerateFromToIntegral from maxBound
310data EnumState a = EnumInit | EnumYield a a a | EnumStop
312{-# INLINE_NORMAL enumerateFromThenToIntegralUp #-}
313enumerateFromThenToIntegralUp
314 :: (Monad m, Integral a)
315 => a -> a -> a -> Stream m a
316enumerateFromThenToIntegralUp from next to = Stream step EnumInit
318 {-# INLINE_LATE step #-}
324 else Yield from EnumStop
325 else -- from <= next <= to
326 let stride = next - from
327 in Skip $ EnumYield from stride (to - stride)
329 step _ (EnumYield x stride toMinus) =
332 then Yield x EnumStop
333 else Yield x $ EnumYield (x + stride) stride toMinus
335 step _ EnumStop = return Stop
337{-# INLINE_NORMAL enumerateFromThenToIntegralDn #-}
338enumerateFromThenToIntegralDn
339 :: (Monad m, Integral a)
340 => a -> a -> a -> Stream m a
341enumerateFromThenToIntegralDn from next to = Stream step EnumInit
343 {-# INLINE_LATE step #-}
345 return $ if to > next
348 else Yield from EnumStop
349 else -- from >= next >= to
350 let stride = next - from
351 in Skip $ EnumYield from stride (to - stride)
353 step _ (EnumYield x stride toMinus) =
356 then Yield x EnumStop
357 else Yield x $ EnumYield (x + stride) stride toMinus
359 step _ EnumStop = return Stop
361{-# INLINE_NORMAL enumerateFromThenToIntegral #-}
362enumerateFromThenToIntegral
363 :: (Monad m, Integral a)
364 => a -> a -> a -> Stream m a
365enumerateFromThenToIntegral from next to
366 | next >= from = enumerateFromThenToIntegralUp from next to
367 | otherwise = enumerateFromThenToIntegralDn from next to
369{-# INLINE_NORMAL enumerateFromThenIntegral #-}
370enumerateFromThenIntegral
371 :: (Monad m, Integral a, Bounded a)
372 => a -> a -> Stream m a
373enumerateFromThenIntegral from next =
375 then enumerateFromThenToIntegralUp from next maxBound
376 else enumerateFromThenToIntegralDn from next minBound
378-- For floating point numbers if the increment is less than the precision then
379-- it just gets lost. Therefore we cannot always increment it correctly by just
381-- 9007199254740992 + 1 + 1 :: Double => 9.007199254740992e15
382-- 9007199254740992 + 2 :: Double => 9.007199254740994e15
384-- Instead we accumulate the increment counter and compute the increment
385-- everytime before adding it to the starting number.
387-- This works for Integrals as well as floating point numbers, but
388-- enumerateFromStepIntegral is faster for integrals.
389{-# INLINE_NORMAL enumerateFromStepNum #-}
390enumerateFromStepNum :: (Monad m, Num a) => a -> a -> Stream m a
391enumerateFromStepNum from stride = Stream step 0
393 {-# INLINE_LATE step #-}
394 step _ !i = return $ (Yield $! (from + i * stride)) $! (i + 1)
396{-# INLINE_NORMAL numFrom #-}
397numFrom :: (Monad m, Num a) => a -> Stream m a
398numFrom from = enumerateFromStepNum from 1
400{-# INLINE_NORMAL numFromThen #-}
401numFromThen :: (Monad m, Num a) => a -> a -> Stream m a
402numFromThen from next = enumerateFromStepNum from (next - from)
404-- We cannot write a general function for Num. The only way to write code
405-- portable between the two is to use a 'Real' constraint and convert between
406-- Fractional and Integral using fromRational which is horribly slow.
407{-# INLINE_NORMAL enumerateFromToFractional #-}
408enumerateFromToFractional
409 :: (Monad m, Fractional a, Ord a)
410 => a -> a -> Stream m a
411enumerateFromToFractional from to =
412 takeWhile (<= to + 1 / 2) $ enumerateFromStepNum from 1
414{-# INLINE_NORMAL enumerateFromThenToFractional #-}
415enumerateFromThenToFractional
416 :: (Monad m, Fractional a, Ord a)
417 => a -> a -> a -> Stream m a
418enumerateFromThenToFractional from next to =
419 takeWhile predicate $ numFromThen from next
421 mid = (next - from) / 2
422 predicate | next >= from = (<= to + mid)
423 | otherwise = (>= to + mid)
425-------------------------------------------------------------------------------
426-- Generation by Conversion
427-------------------------------------------------------------------------------
429-- | Create a singleton 'Stream' from a pure value.
430{-# INLINE_NORMAL yield #-}
431yield :: Monad m => a -> Stream m a
432yield x = Stream (\_ s -> return $ step undefined s) True
434 {-# INLINE_LATE step #-}
435 step _ True = Yield x False
438-- | Create a singleton 'Stream' from a monadic action.
439{-# INLINE_NORMAL yieldM #-}
440yieldM :: Monad m => m a -> Stream m a
441yieldM m = Stream step True
443 {-# INLINE_LATE step #-}
444 step _ True = m >>= \x -> return $ Yield x False
445 step _ False = return Stop
447{-# INLINE_NORMAL fromIndicesM #-}
448fromIndicesM :: Monad m => (Int -> m a) -> Stream m a
449fromIndicesM gen = Stream step 0
451 {-# INLINE_LATE step #-}
454 return $ Yield x (i + 1)
456{-# INLINE fromIndices #-}
457fromIndices :: Monad m => (Int -> a) -> Stream m a
458fromIndices gen = fromIndicesM (return . gen)
460{-# INLINE_NORMAL generateM #-}
461generateM :: Monad m => Int -> (Int -> m a) -> Stream m a
462generateM n gen = n `seq` Stream step 0
464 {-# INLINE_LATE step #-}
465 step _ i | i < n = do
467 return $ Yield x (i + 1)
468 | otherwise = return Stop
470{-# INLINE generate #-}
471generate :: Monad m => Int -> (Int -> a) -> Stream m a
472generate n gen = generateM n (return . gen)
474-- XXX we need the MonadAsync constraint because of a rewrite rule.
475-- | Convert a list of monadic actions to a 'Stream'
476{-# INLINE_LATE fromListM #-}
477fromListM :: MonadAsync m => [m a] -> Stream m a
478fromListM = Stream step
480 {-# INLINE_LATE step #-}
481 step _ (m:ms) = m >>= \x -> return $ Yield x ms
482 step _ [] = return Stop
484-- | Convert a list of pure values to a 'Stream'
485{-# INLINE_LATE fromList #-}
486fromList :: Monad m => [a] -> Stream m a
487fromList = Stream step
489 {-# INLINE_LATE step #-}
490 step _ (x:xs) = return $ Yield x xs
491 step _ [] = return Stop
493{-# INLINE_LATE fromStreamK #-}
494fromStreamK :: Monad m => K.Stream m a -> Stream m a
495fromStreamK = Stream step
498 let stop = return Stop
499 single a = return $ Yield a K.nil
500 yieldk a r = return $ Yield a r
501 in K.foldStreamShared gst yieldk single stop m1
503{-# INLINE toStreamD #-}
504toStreamD :: (K.IsStream t, Monad m) => t m a -> Stream m a
505toStreamD = fromStreamK . K.toStream
507------------------------------------------------------------------------------
508-- Elimination by Folds
509------------------------------------------------------------------------------
511{-# INLINE_NORMAL foldrM #-}
512foldrM :: Monad m => (a -> b -> m b) -> b -> Stream m a -> m b
513foldrM f z (Stream step state) = go SPEC state
516 r <- step defState st
518 Yield x s -> go SPEC s >>= f x
522{-# INLINE_NORMAL foldr #-}
523foldr :: Monad m => (a -> b -> b) -> b -> Stream m a -> m b
524foldr f = foldrM (\a b -> return (f a b))
526{-# INLINE_NORMAL foldr1 #-}
527foldr1 :: Monad m => (a -> a -> a) -> Stream m a -> m (Maybe a)
531 Nothing -> return Nothing
532 Just (h, t) -> fmap Just (foldr f h t)
534{-# INLINE_NORMAL foldlM' #-}
535foldlM' :: Monad m => (b -> a -> m b) -> b -> Stream m a -> m b
536foldlM' fstep begin (Stream step state) = go SPEC begin state
538 go !_ acc st = acc `seq` do
539 r <- step defState st
544 Skip s -> go SPEC acc s
548foldl' :: Monad m => (b -> a -> b) -> b -> Stream m a -> m b
549foldl' fstep = foldlM' (\b a -> return (fstep b a))
551------------------------------------------------------------------------------
553------------------------------------------------------------------------------
555-- | Run a streaming composition, discard the results.
556{-# INLINE_LATE runStream #-}
557runStream :: Monad m => Stream m a -> m ()
558runStream (Stream step state) = go SPEC state
561 r <- step defState st
563 Yield _ s -> go SPEC s
567{-# INLINE_NORMAL null #-}
568null :: Monad m => Stream m a -> m Bool
569null (Stream step state) = go state
572 r <- step defState st
574 Yield _ _ -> return False
579{-# INLINE_NORMAL head #-}
580head :: Monad m => Stream m a -> m (Maybe a)
581head (Stream step state) = go state
584 r <- step defState st
586 Yield x _ -> return (Just x)
588 Stop -> return Nothing
590-- Does not fuse, has the same performance as the StreamK version.
591{-# INLINE_NORMAL tail #-}
592tail :: Monad m => Stream m a -> m (Maybe (Stream m a))
593tail (UnStream step state) = go state
596 r <- step defState st
598 Yield _ s -> return (Just $ Stream step s)
600 Stop -> return Nothing
602-- XXX will it fuse? need custom impl?
603{-# INLINE_NORMAL last #-}
604last :: Monad m => Stream m a -> m (Maybe a)
605last = foldl' (\_ y -> Just y) Nothing
607{-# INLINE_NORMAL elem #-}
608elem :: (Monad m, Eq a) => a -> Stream m a -> m Bool
609elem e (Stream step state) = go state
612 r <- step defState st
615 | x == e -> return True
620{-# INLINE_NORMAL notElem #-}
621notElem :: (Monad m, Eq a) => a -> Stream m a -> m Bool
622notElem e s = fmap not (elem e s)
624{-# INLINE_NORMAL all #-}
625all :: Monad m => (a -> Bool) -> Stream m a -> m Bool
626all p (Stream step state) = go state
629 r <- step defState st
633 | otherwise -> return False
637{-# INLINE_NORMAL any #-}
638any :: Monad m => (a -> Bool) -> Stream m a -> m Bool
639any p (Stream step state) = go state
642 r <- step defState st
650{-# INLINE_NORMAL maximum #-}
651maximum :: (Monad m, Ord a) => Stream m a -> m (Maybe a)
652maximum (Stream step state) = go Nothing state
655 r <- step defState st
657 Yield x s -> go (Just x) s
658 Skip s -> go Nothing s
659 Stop -> return Nothing
660 go (Just acc) st = do
661 r <- step defState st
664 | acc <= x -> go (Just x) s
665 | otherwise -> go (Just acc) s
666 Skip s -> go (Just acc) s
667 Stop -> return (Just acc)
669{-# INLINE_NORMAL maximumBy #-}
670maximumBy :: Monad m => (a -> a -> Ordering) -> Stream m a -> m (Maybe a)
671maximumBy cmp (Stream step state) = go Nothing state
674 r <- step defState st
676 Yield x s -> go (Just x) s
677 Skip s -> go Nothing s
678 Stop -> return Nothing
679 go (Just acc) st = do
680 r <- step defState st
682 Yield x s -> case cmp acc x of
683 GT -> go (Just acc) s
685 Skip s -> go (Just acc) s
686 Stop -> return (Just acc)
688{-# INLINE_NORMAL minimum #-}
689minimum :: (Monad m, Ord a) => Stream m a -> m (Maybe a)
690minimum (Stream step state) = go Nothing state
693 r <- step defState st
695 Yield x s -> go (Just x) s
696 Skip s -> go Nothing s
697 Stop -> return Nothing
698 go (Just acc) st = do
699 r <- step defState st
702 | acc <= x -> go (Just acc) s
703 | otherwise -> go (Just x) s
704 Skip s -> go (Just acc) s
705 Stop -> return (Just acc)
707{-# INLINE_NORMAL minimumBy #-}
708minimumBy :: Monad m => (a -> a -> Ordering) -> Stream m a -> m (Maybe a)
709minimumBy cmp (Stream step state) = go Nothing state
712 r <- step defState st
714 Yield x s -> go (Just x) s
715 Skip s -> go Nothing s
716 Stop -> return Nothing
717 go (Just acc) st = do
718 r <- step defState st
720 Yield x s -> case cmp acc x of
723 Skip s -> go (Just acc) s
724 Stop -> return (Just acc)
726{-# INLINE_NORMAL (!!) #-}
727(!!) :: (Monad m) => Stream m a -> Int -> m (Maybe a)
728(Stream step state) !! i = go i state
731 r <- step defState st
733 Yield x s | n < 0 -> return Nothing
734 | n == 0 -> return $ Just x
735 | otherwise -> go (n - 1) s
737 Stop -> return Nothing
739{-# INLINE_NORMAL lookup #-}
740lookup :: (Monad m, Eq a) => a -> Stream m (a, b) -> m (Maybe b)
741lookup e (Stream step state) = go state
744 r <- step defState st
746 Yield (a, b) s -> if e == a then return (Just b) else go s
748 Stop -> return Nothing
750{-# INLINE_NORMAL findM #-}
751findM :: Monad m => (a -> m Bool) -> Stream m a -> m (Maybe a)
752findM p (Stream step state) = go SPEC state
755 r <- step defState st
759 if b then return (Just x) else go SPEC s
761 Stop -> return Nothing
764find :: Monad m => (a -> Bool) -> Stream m a -> m (Maybe a)
765find p = findM (return . p)
767{-# INLINE_NORMAL findIndices #-}
768findIndices :: Monad m => (a -> Bool) -> Stream m a -> Stream m Int
769findIndices p (Stream step state) = Stream step' (state, 0)
771 {-# INLINE_LATE step' #-}
772 step' gst (st, i) = do
773 r <- step (adaptState gst) st
775 Yield x s -> if p x then Yield i (s, i+1) else Skip (s, i+1)
776 Skip s -> Skip (s, i+1)
779{-# INLINE_NORMAL concatMapM #-}
780concatMapM :: Monad m => (a -> m (Stream m b)) -> Stream m a -> Stream m b
781concatMapM f (Stream step state) = Stream step' (Left state)
783 {-# INLINE_LATE step' #-}
784 step' gst (Left st) = do
785 r <- step (adaptState gst) st
789 return $ Skip (Right (b_stream, s))
790 Skip s -> return $ Skip (Left s)
793 -- XXX using the pattern synonym Stream causes a major performance issue
794 -- here even if the synonym does not include a adaptState call. Need to
795 -- find out why. Is that something to be fixed in GHC?
796 step' _ (Right (UnStream inner_step inner_st, st)) = do
797 r <- inner_step defState inner_st
800 return $ Yield b (Right (Stream inner_step inner_s, st))
802 return $ Skip (Right (Stream inner_step inner_s, st))
803 Stop -> return $ Skip (Left st)
805{-# INLINE concatMap #-}
806concatMap :: Monad m => (a -> Stream m b) -> Stream m a -> Stream m b
807concatMap f = concatMapM (return . f)
809------------------------------------------------------------------------------
811------------------------------------------------------------------------------
813{-# INLINE_NORMAL isPrefixOf #-}
814isPrefixOf :: (Eq a, Monad m) => Stream m a -> Stream m a -> m Bool
815isPrefixOf (Stream stepa ta) (Stream stepb tb) = go (ta, tb, Nothing)
817 go (sa, sb, Nothing) = do
818 r <- stepa defState sa
820 Yield x sa' -> go (sa', sb, Just x)
821 Skip sa' -> go (sa', sb, Nothing)
824 go (sa, sb, Just x) = do
825 r <- stepb defState sb
829 then go (sa, sb', Nothing)
831 Skip sb' -> go (sa, sb', Just x)
834{-# INLINE_NORMAL isSubsequenceOf #-}
835isSubsequenceOf :: (Eq a, Monad m) => Stream m a -> Stream m a -> m Bool
836isSubsequenceOf (Stream stepa ta) (Stream stepb tb) = go (ta, tb, Nothing)
838 go (sa, sb, Nothing) = do
839 r <- stepa defState sa
841 Yield x sa' -> go (sa', sb, Just x)
842 Skip sa' -> go (sa', sb, Nothing)
845 go (sa, sb, Just x) = do
846 r <- stepb defState sb
850 then go (sa, sb', Nothing)
851 else go (sa, sb', Just x)
852 Skip sb' -> go (sa, sb', Just x)
855{-# INLINE_NORMAL stripPrefix #-}
858 => Stream m a -> Stream m a -> m (Maybe (Stream m a))
859stripPrefix (Stream stepa ta) (Stream stepb tb) = go (ta, tb, Nothing)
861 go (sa, sb, Nothing) = do
862 r <- stepa defState sa
864 Yield x sa' -> go (sa', sb, Just x)
865 Skip sa' -> go (sa', sb, Nothing)
866 Stop -> return $ Just (Stream stepb sb)
868 go (sa, sb, Just x) = do
869 r <- stepb defState sb
873 then go (sa, sb', Nothing)
875 Skip sb' -> go (sa, sb', Just x)
876 Stop -> return Nothing
878------------------------------------------------------------------------------
880------------------------------------------------------------------------------
882-- | Execute a monadic action for each element of the 'Stream'
883{-# INLINE_NORMAL mapM_ #-}
884mapM_ :: Monad m => (a -> m b) -> Stream m a -> m ()
885mapM_ m = runStream . mapM m
887------------------------------------------------------------------------------
889------------------------------------------------------------------------------
892toList :: Monad m => Stream m a -> m [a]
895-- Convert a direct stream to and from CPS encoded stream
896{-# INLINE_LATE toStreamK #-}
897toStreamK :: Monad m => Stream m a -> K.Stream m a
898toStreamK (Stream step state) = go state
900 go st = K.mkStream $ \gst yld sng stp -> do
903 Yield x s -> yld x (go s)
904 Skip s -> K.foldStreamShared gst yld sng stp $ go s
907#ifndef DISABLE_FUSION
908{-# RULES "fromStreamK/toStreamK fusion"
909 forall s. toStreamK (fromStreamK s) = s #-}
910{-# RULES "toStreamK/fromStreamK fusion"
911 forall s. fromStreamK (toStreamK s) = s #-}
914{-# INLINE fromStreamD #-}
915fromStreamD :: (K.IsStream t, Monad m) => Stream m a -> t m a
916fromStreamD = K.fromStream . toStreamK
918------------------------------------------------------------------------------
919-- Transformation by Folding (Scans)
920------------------------------------------------------------------------------
922-- XXX Is a prescan useful, discarding the last step does not sound useful? I
923-- am not sure about the utility of this function, so this is implemented but
924-- not exposed. We can expose it if someone provides good reasons why this is
927-- XXX We have to execute the stream one step ahead to know that we are at the
928-- last step. The vector implementation of prescan executes the last fold step
929-- but does not yield the result. This means we have executed the effect but
930-- discarded value. This does not sound right. In this implementation we are
931-- not executing the last fold step.
932{-# INLINE_NORMAL prescanlM' #-}
933prescanlM' :: Monad m => (b -> a -> m b) -> m b -> Stream m a -> Stream m b
934prescanlM' f mz (Stream step state) = Stream step' (state, mz)
936 {-# INLINE_LATE step' #-}
937 step' gst (st, prev) = do
938 r <- step (adaptState gst) st
942 return $ Yield acc (s, f acc x)
943 Skip s -> return $ Skip (s, prev)
946{-# INLINE prescanl' #-}
947prescanl' :: Monad m => (b -> a -> b) -> b -> Stream m a -> Stream m b
948prescanl' f z = prescanlM' (\a b -> return (f a b)) (return z)
950-- XXX if we make the initial value of the accumulator monadic then should we
951-- execute it even if the stream is empty? In that case we would have generated
952-- the effect but discarded the value, but that is what a fold does when the
953-- stream is empty. Whatever we decide, need to reconcile this with prescan.
954-- If we execute the initial value here without even using it then it is ok to
955-- execute the last step there as well without using the value.
956-- Looking at the duality with right fold, in case of right fold we always
957-- perform the action when the construction terminates, so in case of left fold
958-- we should perform it only when the reduction starts.
959{-# INLINE_NORMAL postscanlM' #-}
960postscanlM' :: Monad m => (b -> a -> m b) -> b -> Stream m a -> Stream m b
961postscanlM' fstep begin (Stream step state) =
962 begin `seq` Stream step' (state, begin)
964 {-# INLINE_LATE step' #-}
965 step' gst (st, acc) = acc `seq` do
966 r <- step (adaptState gst) st
970 y `seq` return (Yield y (s, y))
971 Skip s -> return $ Skip (s, acc)
974{-# INLINE_NORMAL postscanl' #-}
975postscanl' :: Monad m => (a -> b -> a) -> a -> Stream m b -> Stream m a
976postscanl' f = postscanlM' (\a b -> return (f a b))
978{-# INLINE_NORMAL postscanlM #-}
979postscanlM :: Monad m => (b -> a -> m b) -> b -> Stream m a -> Stream m b
980postscanlM fstep begin (Stream step state) = Stream step' (state, begin)
982 {-# INLINE_LATE step' #-}
983 step' gst (st, acc) = do
984 r <- step (adaptState gst) st
988 return (Yield y (s, y))
989 Skip s -> return $ Skip (s, acc)
992{-# INLINE_NORMAL postscanl #-}
993postscanl :: Monad m => (a -> b -> a) -> a -> Stream m b -> Stream m a
994postscanl f = postscanlM (\a b -> return (f a b))
996{-# INLINE_NORMAL scanlM' #-}
997scanlM' :: Monad m => (b -> a -> m b) -> b -> Stream m a -> Stream m b
998scanlM' fstep begin s = begin `seq` (begin `cons` postscanlM' fstep begin s)
1000{-# INLINE scanl' #-}
1001scanl' :: Monad m => (b -> a -> b) -> b -> Stream m a -> Stream m b
1002scanl' f = scanlM' (\a b -> return (f a b))
1004{-# INLINE_NORMAL scanlM #-}
1005scanlM :: Monad m => (b -> a -> m b) -> b -> Stream m a -> Stream m b
1006scanlM fstep begin s = begin `cons` postscanlM fstep begin s
1009scanl :: Monad m => (b -> a -> b) -> b -> Stream m a -> Stream m b
1010scanl f = scanlM (\a b -> return (f a b))
1012{-# INLINE_NORMAL scanl1M #-}
1013scanl1M :: Monad m => (a -> a -> m a) -> Stream m a -> Stream m a
1014scanl1M fstep (Stream step state) = Stream step' (state, Nothing)
1016 {-# INLINE_LATE step' #-}
1017 step' gst (st, Nothing) = do
1020 Yield x s -> return $ Yield x (s, Just x)
1021 Skip s -> return $ Skip (s, Nothing)
1024 step' gst (st, Just acc) = do
1029 return $ Yield z (s, Just z)
1030 Skip s -> return $ Skip (s, Just acc)
1033{-# INLINE scanl1 #-}
1034scanl1 :: Monad m => (a -> a -> a) -> Stream m a -> Stream m a
1035scanl1 f = scanl1M (\x y -> return (f x y))
1037{-# INLINE_NORMAL scanl1M' #-}
1038scanl1M' :: Monad m => (a -> a -> m a) -> Stream m a -> Stream m a
1039scanl1M' fstep (Stream step state) = Stream step' (state, Nothing)
1041 {-# INLINE_LATE step' #-}
1042 step' gst (st, Nothing) = do
1045 Yield x s -> x `seq` return $ Yield x (s, Just x)
1046 Skip s -> return $ Skip (s, Nothing)
1049 step' gst (st, Just acc) = acc `seq` do
1054 z `seq` return $ Yield z (s, Just z)
1055 Skip s -> return $ Skip (s, Just acc)
1058{-# INLINE scanl1' #-}
1059scanl1' :: Monad m => (a -> a -> a) -> Stream m a -> Stream m a
1060scanl1' f = scanl1M' (\x y -> return (f x y))
1062-------------------------------------------------------------------------------
1064-------------------------------------------------------------------------------
1066{-# INLINE_NORMAL take #-}
1067take :: Monad m => Int -> Stream m a -> Stream m a
1068take n (Stream step state) = n `seq` Stream step' (state, 0)
1070 {-# INLINE_LATE step' #-}
1071 step' gst (st, i) | i < n = do
1074 Yield x s -> Yield x (s, i + 1)
1075 Skip s -> Skip (s, i)
1077 step' _ (_, _) = return Stop
1079{-# INLINE_NORMAL takeWhileM #-}
1080takeWhileM :: Monad m => (a -> m Bool) -> Stream m a -> Stream m a
1081takeWhileM f (Stream step state) = Stream step' state
1083 {-# INLINE_LATE step' #-}
1089 return $ if b then Yield x s else Stop
1090 Skip s -> return $ Skip s
1093{-# INLINE takeWhile #-}
1094takeWhile :: Monad m => (a -> Bool) -> Stream m a -> Stream m a
1095takeWhile f = takeWhileM (return . f)
1097{-# INLINE_NORMAL drop #-}
1098drop :: Monad m => Int -> Stream m a -> Stream m a
1099drop n (Stream step state) = Stream step' (state, Just n)
1101 {-# INLINE_LATE step' #-}
1102 step' gst (st, Just i)
1107 Yield _ s -> Skip (s, Just (i - 1))
1108 Skip s -> Skip (s, Just i)
1110 | otherwise = return $ Skip (st, Nothing)
1112 step' gst (st, Nothing) = do
1116 Yield x s -> Yield x (s, Nothing)
1117 Skip s -> Skip (s, Nothing)
1120data DropWhileState s a
1122 | DropWhileYield a s
1125{-# INLINE_NORMAL dropWhileM #-}
1126dropWhileM :: Monad m => (a -> m Bool) -> Stream m a -> Stream m a
1127dropWhileM f (Stream step state) = Stream step' (DropWhileDrop state)
1129 {-# INLINE_LATE step' #-}
1130 step' gst (DropWhileDrop st) = do
1136 then return $ Skip (DropWhileDrop s)
1137 else return $ Skip (DropWhileYield x s)
1138 Skip s -> return $ Skip (DropWhileDrop s)
1141 step' gst (DropWhileNext st) = do
1144 Yield x s -> return $ Skip (DropWhileYield x s)
1145 Skip s -> return $ Skip (DropWhileNext s)
1148 step' _ (DropWhileYield x st) = return $ Yield x (DropWhileNext st)
1150{-# INLINE dropWhile #-}
1151dropWhile :: Monad m => (a -> Bool) -> Stream m a -> Stream m a
1152dropWhile f = dropWhileM (return . f)
1154{-# INLINE_NORMAL filterM #-}
1155filterM :: Monad m => (a -> m Bool) -> Stream m a -> Stream m a
1156filterM f (Stream step state) = Stream step' state
1158 {-# INLINE_LATE step' #-}
1167 Skip s -> return $ Skip s
1170{-# INLINE filter #-}
1171filter :: Monad m => (a -> Bool) -> Stream m a -> Stream m a
1172filter f = filterM (return . f)
1174{-# INLINE_NORMAL uniq #-}
1175uniq :: (Eq a, Monad m) => Stream m a -> Stream m a
1176uniq (Stream step state) = Stream step' (Nothing, state)
1178 {-# INLINE_LATE step' #-}
1179 step' gst (Nothing, st) = do
1182 Yield x s -> return $ Yield x (Just x, s)
1183 Skip s -> return $ Skip (Nothing, s)
1185 step' gst (Just x, st) = do
1188 Yield y s | x == y -> return $ Skip (Just x, s)
1189 | otherwise -> return $ Yield x (Just y, s)
1190 Skip s -> return $ Skip (Just x, s)
1193------------------------------------------------------------------------------
1194-- Transformation by Mapping
1195------------------------------------------------------------------------------
1197{-# INLINE_NORMAL sequence #-}
1198sequence :: Monad m => Stream m (m a) -> Stream m a
1199sequence (Stream step state) = Stream step' state
1201 {-# INLINE_LATE step' #-}
1203 r <- step (adaptState gst) st
1205 Yield x s -> x >>= \a -> return (Yield a s)
1206 Skip s -> return $ Skip s
1209------------------------------------------------------------------------------
1211------------------------------------------------------------------------------
1213{-# INLINE_NORMAL insertBy #-}
1214insertBy :: Monad m => (a -> a -> Ordering) -> a -> Stream m a -> Stream m a
1215insertBy cmp a (Stream step state) = Stream step' (state, False, Nothing)
1217 {-# INLINE_LATE step' #-}
1218 step' gst (st, False, _) = do
1221 Yield x s -> case cmp a x of
1222 GT -> return $ Yield x (s, False, Nothing)
1223 _ -> return $ Yield a (s, True, Just x)
1224 Skip s -> return $ Skip (s, False, Nothing)
1225 Stop -> return $ Yield a (st, True, Nothing)
1227 step' _ (_, True, Nothing) = return Stop
1229 step' gst (st, True, Just prev) = do
1232 Yield x s -> return $ Yield prev (s, True, Just x)
1233 Skip s -> return $ Skip (s, True, Just prev)
1234 Stop -> return $ Yield prev (st, True, Nothing)
1236------------------------------------------------------------------------------
1238------------------------------------------------------------------------------
1240{-# INLINE_NORMAL deleteBy #-}
1241deleteBy :: Monad m => (a -> a -> Bool) -> a -> Stream m a -> Stream m a
1242deleteBy eq x (Stream step state) = Stream step' (state, False)
1244 {-# INLINE_LATE step' #-}
1245 step' gst (st, False) = do
1248 Yield y s -> return $
1249 if eq x y then Skip (s, True) else Yield y (s, False)
1250 Skip s -> return $ Skip (s, False)
1253 step' gst (st, True) = do
1256 Yield y s -> return $ Yield y (s, True)
1257 Skip s -> return $ Skip (s, True)
1260------------------------------------------------------------------------------
1261-- Transformation by Map and Filter
1262------------------------------------------------------------------------------
1264-- XXX Will this always fuse properly?
1265{-# INLINE_NORMAL mapMaybe #-}
1266mapMaybe :: Monad m => (a -> Maybe b) -> Stream m a -> Stream m b
1267mapMaybe f = fmap fromJust . filter isJust . map f
1269{-# INLINE_NORMAL mapMaybeM #-}
1270mapMaybeM :: Monad m => (a -> m (Maybe b)) -> Stream m a -> Stream m b
1271mapMaybeM f = fmap fromJust . filter isJust . mapM f
1273------------------------------------------------------------------------------
1275------------------------------------------------------------------------------
1277{-# INLINE_NORMAL indexed #-}
1278indexed :: Monad m => Stream m a -> Stream m (Int, a)
1279indexed (Stream step state) = Stream step' (state, 0)
1281 {-# INLINE_LATE step' #-}
1282 step' gst (st, i) = i `seq` do
1283 r <- step (adaptState gst) st
1285 Yield x s -> return $ Yield (i, x) (s, i+1)
1286 Skip s -> return $ Skip (s, i)
1289{-# INLINE_NORMAL indexedR #-}
1290indexedR :: Monad m => Int -> Stream m a -> Stream m (Int, a)
1291indexedR m (Stream step state) = Stream step' (state, m)
1293 {-# INLINE_LATE step' #-}
1294 step' gst (st, i) = i `seq` do
1295 r <- step (adaptState gst) st
1297 Yield x s -> let i' = i - 1
1299 return $ Yield (i', x) (s, i')
1300 Skip s -> return $ Skip (s, i)
1303{-# INLINE_NORMAL zipWithM #-}
1305 => (a -> b -> m c) -> Stream m a -> Stream m b -> Stream m c
1306zipWithM f (Stream stepa ta) (Stream stepb tb) = Stream step (ta, tb, Nothing)
1308 {-# INLINE_LATE step #-}
1309 step gst (sa, sb, Nothing) = do
1310 r <- stepa (adaptState gst) sa
1313 Yield x sa' -> Skip (sa', sb, Just x)
1314 Skip sa' -> Skip (sa', sb, Nothing)
1317 step gst (sa, sb, Just x) = do
1318 r <- stepb (adaptState gst) sb
1322 return $ Yield z (sa, sb', Nothing)
1323 Skip sb' -> return $ Skip (sa, sb', Just x)
1326{-# RULES "zipWithM xs xs"
1327 forall f xs. zipWithM f xs xs = mapM (\x -> f x x) xs #-}
1329{-# INLINE zipWith #-}
1330zipWith :: Monad m => (a -> b -> c) -> Stream m a -> Stream m b -> Stream m c
1331zipWith f = zipWithM (\a b -> return (f a b))
1333------------------------------------------------------------------------------
1335------------------------------------------------------------------------------
1337{-# INLINE_NORMAL eqBy #-}
1338eqBy :: Monad m => (a -> b -> Bool) -> Stream m a -> Stream m b -> m Bool
1339eqBy eq (Stream step1 t1) (Stream step2 t2) = eq_loop0 SPEC t1 t2
1341 eq_loop0 !_ s1 s2 = do
1342 r <- step1 defState s1
1344 Yield x s1' -> eq_loop1 SPEC x s1' s2
1345 Skip s1' -> eq_loop0 SPEC s1' s2
1348 eq_loop1 !_ x s1 s2 = do
1349 r <- step2 defState s2
1352 | eq x y -> eq_loop0 SPEC s1 s2'
1353 | otherwise -> return False
1354 Skip s2' -> eq_loop1 SPEC x s1 s2'
1355 Stop -> return False
1358 r <- step2 defState s2
1360 Yield _ _ -> return False
1361 Skip s2' -> eq_null s2'
1364-- | Compare two streams lexicographically
1365{-# INLINE_NORMAL cmpBy #-}
1368 => (a -> b -> Ordering) -> Stream m a -> Stream m b -> m Ordering
1369cmpBy cmp (Stream step1 t1) (Stream step2 t2) = cmp_loop0 SPEC t1 t2
1371 cmp_loop0 !_ s1 s2 = do
1372 r <- step1 defState s1
1374 Yield x s1' -> cmp_loop1 SPEC x s1' s2
1375 Skip s1' -> cmp_loop0 SPEC s1' s2
1378 cmp_loop1 !_ x s1 s2 = do
1379 r <- step2 defState s2
1381 Yield y s2' -> case x `cmp` y of
1382 EQ -> cmp_loop0 SPEC s1 s2'
1384 Skip s2' -> cmp_loop1 SPEC x s1 s2'
1388 r <- step2 defState s2
1390 Yield _ _ -> return LT
1391 Skip s2' -> cmp_null s2'
1394------------------------------------------------------------------------------
1396------------------------------------------------------------------------------
1398{-# INLINE_NORMAL mergeByM #-}
1401 => (a -> a -> m Ordering) -> Stream m a -> Stream m a -> Stream m a
1402mergeByM cmp (Stream stepa ta) (Stream stepb tb) =
1403 Stream step (Just ta, Just tb, Nothing, Nothing)
1405 {-# INLINE_LATE step #-}
1407 -- one of the values is missing, and the corresponding stream is running
1408 step gst (Just sa, sb, Nothing, b) = do
1411 Yield a sa' -> Skip (Just sa', sb, Just a, b)
1412 Skip sa' -> Skip (Just sa', sb, Nothing, b)
1413 Stop -> Skip (Nothing, sb, Nothing, b)
1415 step gst (sa, Just sb, a, Nothing) = do
1418 Yield b sb' -> Skip (sa, Just sb', a, Just b)
1419 Skip sb' -> Skip (sa, Just sb', a, Nothing)
1420 Stop -> Skip (sa, Nothing, a, Nothing)
1422 -- both the values are available
1423 step _ (sa, sb, Just a, Just b) = do
1425 return $ case res of
1426 GT -> Yield b (sa, sb, Just a, Nothing)
1427 _ -> Yield a (sa, sb, Nothing, Just b)
1429 -- one of the values is missing, corresponding stream is done
1430 step _ (Nothing, sb, Nothing, Just b) =
1431 return $ Yield b (Nothing, sb, Nothing, Nothing)
1433 step _ (sa, Nothing, Just a, Nothing) =
1434 return $ Yield a (sa, Nothing, Nothing, Nothing)
1436 step _ (Nothing, Nothing, Nothing, Nothing) = return Stop
1438{-# INLINE mergeBy #-}
1441 => (a -> a -> Ordering) -> Stream m a -> Stream m a -> Stream m a
1442mergeBy cmp = mergeByM (\a b -> return $ cmp a b)
1444------------------------------------------------------------------------------
1445-- Transformation comprehensions
1446------------------------------------------------------------------------------
1448{-# INLINE_NORMAL the #-}
1449the :: (Eq a, Monad m) => Stream m a -> m (Maybe a)
1450the (Stream step state) = go state
1453 r <- step defState st
1455 Yield x s -> go' x s
1457 Stop -> return Nothing
1459 r <- step defState st
1461 Yield x s | x == n -> go' n s
1462 | otherwise -> return Nothing
1464 Stop -> return (Just n)
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