on 5592064 help sign in
4270 lines 148 kB history raw
1{-# LANGUAGE BangPatterns #-}
2{-# LANGUAGE CPP #-}
3{-# LANGUAGE ConstraintKinds #-}
4{-# LANGUAGE ExistentialQuantification #-}
5{-# LANGUAGE FlexibleContexts #-}
6{-# LANGUAGE FlexibleInstances #-}
7{-# LANGUAGE MultiParamTypeClasses #-}
8{-# LANGUAGE PatternSynonyms #-}
9{-# LANGUAGE RecordWildCards #-}
10{-# LANGUAGE ScopedTypeVariables #-}
11{-# LANGUAGE ViewPatterns #-}
12{-# LANGUAGE RankNTypes #-}
13{-# LANGUAGE MagicHash #-}
15#if __GLASGOW_HASKELL__ >= 801
16{-# LANGUAGE TypeApplications #-}
17#endif
19#include "inline.hs"
21-- |
22-- Module : Streamly.Internal.Data.Stream.StreamD
23-- Copyright : (c) 2018 Harendra Kumar
24-- (c) Roman Leshchinskiy 2008-2010
25-- (c) The University of Glasgow, 2009
26--
27-- License : BSD3
28-- Maintainer : streamly@composewell.com
29-- Stability : experimental
30-- Portability : GHC
31--
32-- Direct style re-implementation of CPS style stream in StreamK module. The
33-- symbol or suffix 'D' in this module denotes the "Direct" style. GHC is able
34-- to INLINE and fuse direct style better, providing better performance than
35-- CPS implementation.
36--
37-- @
38-- import qualified Streamly.Internal.Data.Stream.StreamD as D
39-- @
41-- Some of the functions in this file have been adapted from the vector
42-- library, https://hackage.haskell.org/package/vector.
44module Streamly.Internal.Data.Stream.StreamD
45 (
46 -- * The stream type
47 Step (..)
49#if __GLASGOW_HASKELL__ >= 800
50 , Stream (Stream, UnStream)
51#else
52 , Stream (UnStream)
53 , pattern Stream
54#endif
56 -- * Construction
57 , nil
58 , nilM
59 , cons
61 -- * Deconstruction
62 , uncons
64 -- * Generation
65 -- ** Unfolds
66 , unfoldr
67 , unfoldrM
68 , unfold
70 -- ** Specialized Generation
71 -- | Generate a monadic stream from a seed.
72 , repeat
73 , repeatM
74 , replicate
75 , replicateM
76 , fromIndices
77 , fromIndicesM
78 , generate
79 , generateM
80 , iterate
81 , iterateM
83 -- ** Enumerations
84 , enumerateFromStepIntegral
85 , enumerateFromIntegral
86 , enumerateFromThenIntegral
87 , enumerateFromToIntegral
88 , enumerateFromThenToIntegral
90 , enumerateFromStepNum
91 , numFrom
92 , numFromThen
93 , enumerateFromToFractional
94 , enumerateFromThenToFractional
96 -- ** Time
97 , currentTime
99 -- ** Conversions
100 -- | Transform an input structure into a stream.
101 -- | Direct style stream does not support @fromFoldable@.
102 , yield
103 , yieldM
104 , fromList
105 , fromListM
106 , fromStreamK
107 , fromStreamD
108 , fromPrimVar
109 , fromSVar
111 -- * Elimination
112 -- ** General Folds
113 , foldrS
114 , foldrT
115 , foldrM
116 , foldrMx
117 , foldr
118 , foldr1
120 , foldl'
121 , foldlM'
122 , foldlS
123 , foldlT
124 , reverse
125 , reverse'
127 , foldlx'
128 , foldlMx'
129 , runFold
131 -- ** Specialized Folds
132 , tap
133 , tapOffsetEvery
134 , tapAsync
135 , tapRate
136 , pollCounts
137 , drain
138 , null
139 , head
140 , headElse
141 , tail
142 , last
143 , elem
144 , notElem
145 , all
146 , any
147 , maximum
148 , maximumBy
149 , minimum
150 , minimumBy
151 , findIndices
152 , lookup
153 , findM
154 , find
155 , (!!)
156 , toSVarParallel
158 -- ** Flattening nested streams
159 , concatMapM
160 , concatMap
161 , ConcatMapUState (..)
162 , concatMapU
163 , ConcatUnfoldInterleaveState (..)
164 , concatUnfoldInterleave
165 , concatUnfoldRoundrobin
166 , AppendState(..)
167 , append
168 , InterleaveState(..)
169 , interleave
170 , interleaveMin
171 , interleaveSuffix
172 , interleaveInfix
173 , roundRobin -- interleaveFair?/ParallelFair
174 , gintercalateSuffix
175 , interposeSuffix
176 , gintercalate
177 , interpose
179 -- ** Grouping
180 , groupsOf
181 , groupsOf2
182 , groupsBy
183 , groupsRollingBy
185 -- ** Splitting
186 , splitBy
187 , splitSuffixBy
188 , wordsBy
189 , splitSuffixBy'
191 , splitOn
192 , splitSuffixOn
194 , splitInnerBy
195 , splitInnerBySuffix
197 -- ** Substreams
198 , isPrefixOf
199 , isSubsequenceOf
200 , stripPrefix
202 -- ** Map and Fold
203 , mapM_
205 -- ** Conversions
206 -- | Transform a stream into another type.
207 , toList
208 , toListRev
209 , toStreamK
210 , toStreamD
212 , hoist
213 , generally
215 , liftInner
216 , runReaderT
217 , evalStateT
218 , runStateT
220 -- * Transformation
221 , transform
223 -- ** By folding (scans)
224 , scanlM'
225 , scanl'
226 , scanlM
227 , scanl
228 , scanl1M'
229 , scanl1'
230 , scanl1M
231 , scanl1
233 , prescanl'
234 , prescanlM'
236 , postscanl
237 , postscanlM
238 , postscanl'
239 , postscanlM'
241 , postscanlx'
242 , postscanlMx'
243 , scanlMx'
244 , scanlx'
246 -- * Filtering
247 , filter
248 , filterM
249 , uniq
250 , take
251 , takeByTime
252 , takeWhile
253 , takeWhileM
254 , drop
255 , dropByTime
256 , dropWhile
257 , dropWhileM
259 -- * Mapping
260 , map
261 , mapM
262 , sequence
263 , rollingMap
264 , rollingMapM
266 -- * Inserting
267 , intersperseM
268 , intersperse
269 , intersperseSuffix
270 , intersperseSuffixBySpan
271 , insertBy
273 -- * Deleting
274 , deleteBy
276 -- ** Map and Filter
277 , mapMaybe
278 , mapMaybeM
280 -- * Zipping
281 , indexed
282 , indexedR
283 , zipWith
284 , zipWithM
286 -- * Comparisons
287 , eqBy
288 , cmpBy
290 -- * Merging
291 , mergeBy
292 , mergeByM
294 -- * Transformation comprehensions
295 , the
297 -- * Exceptions
298 , newFinalizedIORef
299 , runIORefFinalizer
300 , clearIORefFinalizer
301 , gbracket
302 , before
303 , after
304 , afterIO
305 , bracket
306 , bracketIO
307 , onException
308 , finally
309 , finallyIO
310 , handle
312 -- * Concurrent Application
313 , mkParallel
314 , mkParallelD
316 , lastN
317 )
318where
320import Control.Concurrent (killThread, myThreadId, takeMVar, threadDelay)
321import Control.Exception
322 (Exception, SomeException, AsyncException, fromException)
323import Control.Monad (void, when, forever)
324import Control.Monad.Catch (MonadCatch, throwM)
325import Control.Monad.IO.Class (MonadIO(..))
326import Control.Monad.Reader (ReaderT)
327import Control.Monad.State.Strict (StateT)
328import Control.Monad.Trans (MonadTrans(lift))
329import Control.Monad.Trans.Control (MonadBaseControl)
330import Data.Bits (shiftR, shiftL, (.|.), (.&.))
331import Data.Functor.Identity (Identity(..))
332import Data.Int (Int64)
333import Data.IORef (newIORef, readIORef, mkWeakIORef, writeIORef, IORef)
334import Data.Maybe (fromJust, isJust, isNothing)
335import Data.Word (Word32)
336import Foreign.Ptr (Ptr)
337import Foreign.Storable (Storable(..))
338import GHC.Types (SPEC(..))
339import System.Mem (performMajorGC)
340import Prelude
341 hiding (map, mapM, mapM_, repeat, foldr, last, take, filter,
342 takeWhile, drop, dropWhile, all, any, maximum, minimum, elem,
343 notElem, null, head, tail, zipWith, lookup, foldr1, sequence,
344 (!!), scanl, scanl1, concatMap, replicate, enumFromTo, concat,
345 reverse, iterate)
347import qualified Control.Monad.Catch as MC
348import qualified Control.Monad.Reader as Reader
349import qualified Control.Monad.State.Strict as State
350import qualified Prelude
352import Streamly.Internal.Mutable.Prim.Var
353 (Prim, Var, readVar, newVar, modifyVar')
354import Streamly.Internal.Data.Time.Units
355 (TimeUnit64, toRelTime64, diffAbsTime64)
357import Streamly.Internal.Data.Atomics (atomicModifyIORefCAS_)
358import Streamly.Internal.Memory.Array.Types (Array(..))
359import Streamly.Internal.Data.Fold.Types (Fold(..))
360import Streamly.Internal.Data.Pipe.Types (Pipe(..), PipeState(..))
361import Streamly.Internal.Data.Time.Clock (Clock(Monotonic), getTime)
362import Streamly.Internal.Data.Time.Units
363 (MicroSecond64(..), fromAbsTime, toAbsTime, AbsTime)
364import Streamly.Internal.Data.Unfold.Types (Unfold(..))
365import Streamly.Internal.Data.Strict (Tuple3'(..))
367import Streamly.Internal.Data.Stream.StreamD.Type
368import Streamly.Internal.Data.SVar
369import Streamly.Internal.Data.Stream.SVar (fromConsumer, pushToFold)
371import qualified Streamly.Internal.Data.Pipe.Types as Pipe
372import qualified Streamly.Internal.Memory.Array.Types as A
373import qualified Streamly.Internal.Data.Fold as FL
374import qualified Streamly.Memory.Ring as RB
375import qualified Streamly.Internal.Data.Stream.StreamK as K
377------------------------------------------------------------------------------
378-- Construction
379------------------------------------------------------------------------------
381-- | An empty 'Stream'.
382{-# INLINE_NORMAL nil #-}
383nil :: Monad m => Stream m a
384nil = Stream (\_ _ -> return Stop) ()
386-- | An empty 'Stream' with a side effect.
387{-# INLINE_NORMAL nilM #-}
388nilM :: Monad m => m b -> Stream m a
389nilM m = Stream (\_ _ -> m >> return Stop) ()
391{-# INLINE_NORMAL consM #-}
392consM :: Monad m => m a -> Stream m a -> Stream m a
393consM m (Stream step state) = Stream step1 Nothing
394 where
395 {-# INLINE_LATE step1 #-}
396 step1 _ Nothing = m >>= \x -> return $ Yield x (Just state)
397 step1 gst (Just st) = do
398 r <- step gst st
399 return $
400 case r of
401 Yield a s -> Yield a (Just s)
402 Skip s -> Skip (Just s)
403 Stop -> Stop
405-- XXX implement in terms of consM?
406-- cons x = consM (return x)
407--
408-- | Can fuse but has O(n^2) complexity.
409{-# INLINE_NORMAL cons #-}
410cons :: Monad m => a -> Stream m a -> Stream m a
411cons x (Stream step state) = Stream step1 Nothing
412 where
413 {-# INLINE_LATE step1 #-}
414 step1 _ Nothing = return $ Yield x (Just state)
415 step1 gst (Just st) = do
416 r <- step gst st
417 return $
418 case r of
419 Yield a s -> Yield a (Just s)
420 Skip s -> Skip (Just s)
421 Stop -> Stop
423-------------------------------------------------------------------------------
424-- Deconstruction
425-------------------------------------------------------------------------------
427-- Does not fuse, has the same performance as the StreamK version.
428{-# INLINE_NORMAL uncons #-}
429uncons :: Monad m => Stream m a -> m (Maybe (a, Stream m a))
430uncons (UnStream step state) = go state
431 where
432 go st = do
433 r <- step defState st
434 case r of
435 Yield x s -> return $ Just (x, Stream step s)
436 Skip s -> go s
437 Stop -> return Nothing
439------------------------------------------------------------------------------
440-- Generation by unfold
441------------------------------------------------------------------------------
443{-# INLINE_NORMAL unfoldrM #-}
444unfoldrM :: Monad m => (s -> m (Maybe (a, s))) -> s -> Stream m a
445unfoldrM next state = Stream step state
446 where
447 {-# INLINE_LATE step #-}
448 step _ st = do
449 r <- next st
450 return $ case r of
451 Just (x, s) -> Yield x s
452 Nothing -> Stop
454{-# INLINE_LATE unfoldr #-}
455unfoldr :: Monad m => (s -> Maybe (a, s)) -> s -> Stream m a
456unfoldr f = unfoldrM (return . f)
458-- | Convert an 'Unfold' into a 'Stream' by supplying it a seed.
459--
460{-# INLINE_NORMAL unfold #-}
461unfold :: Monad m => Unfold m a b -> a -> Stream m b
462unfold (Unfold ustep inject) seed = Stream step Nothing
463 where
464 {-# INLINE_LATE step #-}
465 step _ Nothing = inject seed >>= return . Skip . Just
466 step _ (Just st) = do
467 r <- ustep st
468 return $ case r of
469 Yield x s -> Yield x (Just s)
470 Skip s -> Skip (Just s)
471 Stop -> Stop
473------------------------------------------------------------------------------
474-- Specialized Generation
475------------------------------------------------------------------------------
477{-# INLINE_NORMAL repeatM #-}
478repeatM :: Monad m => m a -> Stream m a
479repeatM x = Stream (\_ _ -> x >>= \r -> return $ Yield r ()) ()
481{-# INLINE_NORMAL repeat #-}
482repeat :: Monad m => a -> Stream m a
483repeat x = Stream (\_ _ -> return $ Yield x ()) ()
485{-# INLINE_NORMAL iterateM #-}
486iterateM :: Monad m => (a -> m a) -> m a -> Stream m a
487iterateM step = Stream (\_ st -> st >>= \x -> return $ Yield x (step x))
489{-# INLINE_NORMAL iterate #-}
490iterate :: Monad m => (a -> a) -> a -> Stream m a
491iterate step st = iterateM (return . step) (return st)
493{-# INLINE_NORMAL replicateM #-}
494replicateM :: forall m a. Monad m => Int -> m a -> Stream m a
495replicateM n p = Stream step n
496 where
497 {-# INLINE_LATE step #-}
498 step _ (i :: Int)
499 | i <= 0 = return Stop
500 | otherwise = do
501 x <- p
502 return $ Yield x (i - 1)
504{-# INLINE_NORMAL replicate #-}
505replicate :: Monad m => Int -> a -> Stream m a
506replicate n x = replicateM n (return x)
508-- This would not work properly for floats, therefore we put an Integral
509-- constraint.
510-- | Can be used to enumerate unbounded integrals. This does not check for
511-- overflow or underflow for bounded integrals.
512{-# INLINE_NORMAL enumerateFromStepIntegral #-}
513enumerateFromStepIntegral :: (Integral a, Monad m) => a -> a -> Stream m a
514enumerateFromStepIntegral from stride =
515 from `seq` stride `seq` Stream step from
516 where
517 {-# INLINE_LATE step #-}
518 step _ !x = return $ Yield x $! (x + stride)
520-- We are assuming that "to" is constrained by the type to be within
521-- max/min bounds.
522{-# INLINE enumerateFromToIntegral #-}
523enumerateFromToIntegral :: (Monad m, Integral a) => a -> a -> Stream m a
524enumerateFromToIntegral from to =
525 takeWhile (<= to) $ enumerateFromStepIntegral from 1
527{-# INLINE enumerateFromIntegral #-}
528enumerateFromIntegral :: (Monad m, Integral a, Bounded a) => a -> Stream m a
529enumerateFromIntegral from = enumerateFromToIntegral from maxBound
531data EnumState a = EnumInit | EnumYield a a a | EnumStop
533{-# INLINE_NORMAL enumerateFromThenToIntegralUp #-}
534enumerateFromThenToIntegralUp
535 :: (Monad m, Integral a)
536 => a -> a -> a -> Stream m a
537enumerateFromThenToIntegralUp from next to = Stream step EnumInit
538 where
539 {-# INLINE_LATE step #-}
540 step _ EnumInit =
541 return $
542 if to < next
543 then if to < from
544 then Stop
545 else Yield from EnumStop
546 else -- from <= next <= to
547 let stride = next - from
548 in Skip $ EnumYield from stride (to - stride)
550 step _ (EnumYield x stride toMinus) =
551 return $
552 if x > toMinus
553 then Yield x EnumStop
554 else Yield x $ EnumYield (x + stride) stride toMinus
556 step _ EnumStop = return Stop
558{-# INLINE_NORMAL enumerateFromThenToIntegralDn #-}
559enumerateFromThenToIntegralDn
560 :: (Monad m, Integral a)
561 => a -> a -> a -> Stream m a
562enumerateFromThenToIntegralDn from next to = Stream step EnumInit
563 where
564 {-# INLINE_LATE step #-}
565 step _ EnumInit =
566 return $ if to > next
567 then if to > from
568 then Stop
569 else Yield from EnumStop
570 else -- from >= next >= to
571 let stride = next - from
572 in Skip $ EnumYield from stride (to - stride)
574 step _ (EnumYield x stride toMinus) =
575 return $
576 if x < toMinus
577 then Yield x EnumStop
578 else Yield x $ EnumYield (x + stride) stride toMinus
580 step _ EnumStop = return Stop
582{-# INLINE_NORMAL enumerateFromThenToIntegral #-}
583enumerateFromThenToIntegral
584 :: (Monad m, Integral a)
585 => a -> a -> a -> Stream m a
586enumerateFromThenToIntegral from next to
587 | next >= from = enumerateFromThenToIntegralUp from next to
588 | otherwise = enumerateFromThenToIntegralDn from next to
590{-# INLINE_NORMAL enumerateFromThenIntegral #-}
591enumerateFromThenIntegral
592 :: (Monad m, Integral a, Bounded a)
593 => a -> a -> Stream m a
594enumerateFromThenIntegral from next =
595 if next > from
596 then enumerateFromThenToIntegralUp from next maxBound
597 else enumerateFromThenToIntegralDn from next minBound
599-- For floating point numbers if the increment is less than the precision then
600-- it just gets lost. Therefore we cannot always increment it correctly by just
601-- repeated addition.
602-- 9007199254740992 + 1 + 1 :: Double => 9.007199254740992e15
603-- 9007199254740992 + 2 :: Double => 9.007199254740994e15
605-- Instead we accumulate the increment counter and compute the increment
606-- every time before adding it to the starting number.
607--
608-- This works for Integrals as well as floating point numbers, but
609-- enumerateFromStepIntegral is faster for integrals.
610{-# INLINE_NORMAL enumerateFromStepNum #-}
611enumerateFromStepNum :: (Monad m, Num a) => a -> a -> Stream m a
612enumerateFromStepNum from stride = Stream step 0
613 where
614 {-# INLINE_LATE step #-}
615 step _ !i = return $ (Yield $! (from + i * stride)) $! (i + 1)
617{-# INLINE_NORMAL numFrom #-}
618numFrom :: (Monad m, Num a) => a -> Stream m a
619numFrom from = enumerateFromStepNum from 1
621{-# INLINE_NORMAL numFromThen #-}
622numFromThen :: (Monad m, Num a) => a -> a -> Stream m a
623numFromThen from next = enumerateFromStepNum from (next - from)
625-- We cannot write a general function for Num. The only way to write code
626-- portable between the two is to use a 'Real' constraint and convert between
627-- Fractional and Integral using fromRational which is horribly slow.
628{-# INLINE_NORMAL enumerateFromToFractional #-}
629enumerateFromToFractional
630 :: (Monad m, Fractional a, Ord a)
631 => a -> a -> Stream m a
632enumerateFromToFractional from to =
633 takeWhile (<= to + 1 / 2) $ enumerateFromStepNum from 1
635{-# INLINE_NORMAL enumerateFromThenToFractional #-}
636enumerateFromThenToFractional
637 :: (Monad m, Fractional a, Ord a)
638 => a -> a -> a -> Stream m a
639enumerateFromThenToFractional from next to =
640 takeWhile predicate $ numFromThen from next
641 where
642 mid = (next - from) / 2
643 predicate | next >= from = (<= to + mid)
644 | otherwise = (>= to + mid)
646-------------------------------------------------------------------------------
647-- Generation by Conversion
648-------------------------------------------------------------------------------
650{-# INLINE_NORMAL fromIndicesM #-}
651fromIndicesM :: Monad m => (Int -> m a) -> Stream m a
652fromIndicesM gen = Stream step 0
653 where
654 {-# INLINE_LATE step #-}
655 step _ i = do
656 x <- gen i
657 return $ Yield x (i + 1)
659{-# INLINE fromIndices #-}
660fromIndices :: Monad m => (Int -> a) -> Stream m a
661fromIndices gen = fromIndicesM (return . gen)
663{-# INLINE_NORMAL generateM #-}
664generateM :: Monad m => Int -> (Int -> m a) -> Stream m a
665generateM n gen = n `seq` Stream step 0
666 where
667 {-# INLINE_LATE step #-}
668 step _ i | i < n = do
669 x <- gen i
670 return $ Yield x (i + 1)
671 | otherwise = return Stop
673{-# INLINE generate #-}
674generate :: Monad m => Int -> (Int -> a) -> Stream m a
675generate n gen = generateM n (return . gen)
677-- XXX we need the MonadAsync constraint because of a rewrite rule.
678-- | Convert a list of monadic actions to a 'Stream'
679{-# INLINE_LATE fromListM #-}
680fromListM :: MonadAsync m => [m a] -> Stream m a
681fromListM = Stream step
682 where
683 {-# INLINE_LATE step #-}
684 step _ (m:ms) = m >>= \x -> return $ Yield x ms
685 step _ [] = return Stop
687{-# INLINE toStreamD #-}
688toStreamD :: (K.IsStream t, Monad m) => t m a -> Stream m a
689toStreamD = fromStreamK . K.toStream
691{-# INLINE_NORMAL fromPrimVar #-}
692fromPrimVar :: (MonadIO m, Prim a) => Var IO a -> Stream m a
693fromPrimVar var = Stream step ()
694 where
695 {-# INLINE_LATE step #-}
696 step _ () = liftIO (readVar var) >>= \x -> return $ Yield x ()
698-------------------------------------------------------------------------------
699-- Generation from SVar
700-------------------------------------------------------------------------------
702data FromSVarState t m a =
703 FromSVarInit
704 | FromSVarRead (SVar t m a)
705 | FromSVarLoop (SVar t m a) [ChildEvent a]
706 | FromSVarDone (SVar t m a)
708{-# INLINE_NORMAL fromSVar #-}
709fromSVar :: (MonadAsync m) => SVar t m a -> Stream m a
710fromSVar svar = Stream step FromSVarInit
711 where
713 {-# INLINE_LATE step #-}
714 step _ FromSVarInit = do
715 ref <- liftIO $ newIORef ()
716 _ <- liftIO $ mkWeakIORef ref hook
717 -- when this copy of svar gets garbage collected "ref" will get
718 -- garbage collected and our GC hook will be called.
719 let sv = svar{svarRef = Just ref}
720 return $ Skip (FromSVarRead sv)
722 where
724 {-# NOINLINE hook #-}
725 hook = do
726 when (svarInspectMode svar) $ do
727 r <- liftIO $ readIORef (svarStopTime (svarStats svar))
728 when (isNothing r) $
729 printSVar svar "SVar Garbage Collected"
730 cleanupSVar svar
731 -- If there are any SVars referenced by this SVar a GC will prompt
732 -- them to be cleaned up quickly.
733 when (svarInspectMode svar) performMajorGC
735 step _ (FromSVarRead sv) = do
736 list <- readOutputQ sv
737 -- Reversing the output is important to guarantee that we process the
738 -- outputs in the same order as they were generated by the constituent
739 -- streams.
740 return $ Skip $ FromSVarLoop sv (Prelude.reverse list)
742 step _ (FromSVarLoop sv []) = do
743 done <- postProcess sv
744 return $ Skip $ if done
745 then (FromSVarDone sv)
746 else (FromSVarRead sv)
748 step _ (FromSVarLoop sv (ev : es)) = do
749 case ev of
750 ChildYield a -> return $ Yield a (FromSVarLoop sv es)
751 ChildStop tid e -> do
752 accountThread sv tid
753 case e of
754 Nothing -> do
755 stop <- shouldStop tid
756 if stop
757 then do
758 liftIO (cleanupSVar sv)
759 return $ Skip (FromSVarDone sv)
760 else return $ Skip (FromSVarLoop sv es)
761 Just ex ->
762 case fromException ex of
763 Just ThreadAbort ->
764 return $ Skip (FromSVarLoop sv es)
765 Nothing -> liftIO (cleanupSVar sv) >> throwM ex
766 where
768 shouldStop tid =
769 case svarStopStyle sv of
770 StopNone -> return False
771 StopAny -> return True
772 StopBy -> do
773 sid <- liftIO $ readIORef (svarStopBy sv)
774 return $ if tid == sid then True else False
776 step _ (FromSVarDone sv) = do
777 when (svarInspectMode sv) $ do
778 t <- liftIO $ getTime Monotonic
779 liftIO $ writeIORef (svarStopTime (svarStats sv)) (Just t)
780 liftIO $ printSVar sv "SVar Done"
781 return Stop
783-------------------------------------------------------------------------------
784-- Process events received by a fold consumer from a stream producer
785-------------------------------------------------------------------------------
787{-# INLINE_NORMAL fromProducer #-}
788fromProducer :: (MonadAsync m) => SVar t m a -> Stream m a
789fromProducer svar = Stream step (FromSVarRead svar)
790 where
792 {-# INLINE_LATE step #-}
793 step _ (FromSVarRead sv) = do
794 list <- readOutputQ sv
795 -- Reversing the output is important to guarantee that we process the
796 -- outputs in the same order as they were generated by the constituent
797 -- streams.
798 return $ Skip $ FromSVarLoop sv (Prelude.reverse list)
800 step _ (FromSVarLoop sv []) = return $ Skip $ FromSVarRead sv
801 step _ (FromSVarLoop sv (ev : es)) = do
802 case ev of
803 ChildYield a -> return $ Yield a (FromSVarLoop sv es)
804 ChildStop tid e -> do
805 accountThread sv tid
806 case e of
807 Nothing -> do
808 sendStopToProducer sv
809 return $ Skip (FromSVarDone sv)
810 Just _ -> error "Bug: fromProducer: received exception"
812 step _ (FromSVarDone sv) = do
813 when (svarInspectMode sv) $ do
814 t <- liftIO $ getTime Monotonic
815 liftIO $ writeIORef (svarStopTime (svarStats sv)) (Just t)
816 liftIO $ printSVar sv "SVar Done"
817 return Stop
819 step _ FromSVarInit = undefined
821-------------------------------------------------------------------------------
822-- Hoisting the inner monad
823-------------------------------------------------------------------------------
825{-# INLINE_NORMAL hoist #-}
826hoist :: Monad n => (forall x. m x -> n x) -> Stream m a -> Stream n a
827hoist f (Stream step state) = (Stream step' state)
828 where
829 {-# INLINE_LATE step' #-}
830 step' gst st = do
831 r <- f $ step (adaptState gst) st
832 return $ case r of
833 Yield x s -> Yield x s
834 Skip s -> Skip s
835 Stop -> Stop
837{-# INLINE generally #-}
838generally :: Monad m => Stream Identity a -> Stream m a
839generally = hoist (return . runIdentity)
841{-# INLINE_NORMAL liftInner #-}
842liftInner :: (Monad m, MonadTrans t, Monad (t m))
843 => Stream m a -> Stream (t m) a
844liftInner (Stream step state) = Stream step' state
845 where
846 {-# INLINE_LATE step' #-}
847 step' gst st = do
848 r <- lift $ step (adaptState gst) st
849 return $ case r of
850 Yield x s -> Yield x s
851 Skip s -> Skip s
852 Stop -> Stop
854{-# INLINE_NORMAL runReaderT #-}
855runReaderT :: Monad m => s -> Stream (ReaderT s m) a -> Stream m a
856runReaderT sval (Stream step state) = Stream step' state
857 where
858 {-# INLINE_LATE step' #-}
859 step' gst st = do
860 r <- Reader.runReaderT (step (adaptState gst) st) sval
861 return $ case r of
862 Yield x s -> Yield x s
863 Skip s -> Skip s
864 Stop -> Stop
866{-# INLINE_NORMAL evalStateT #-}
867evalStateT :: Monad m => s -> Stream (StateT s m) a -> Stream m a
868evalStateT sval (Stream step state) = Stream step' (state, sval)
869 where
870 {-# INLINE_LATE step' #-}
871 step' gst (st, sv) = do
872 (r, sv') <- State.runStateT (step (adaptState gst) st) sv
873 return $ case r of
874 Yield x s -> Yield x (s, sv')
875 Skip s -> Skip (s, sv')
876 Stop -> Stop
878{-# INLINE_NORMAL runStateT #-}
879runStateT :: Monad m => s -> Stream (StateT s m) a -> Stream m (s, a)
880runStateT sval (Stream step state) = Stream step' (state, sval)
881 where
882 {-# INLINE_LATE step' #-}
883 step' gst (st, sv) = do
884 (r, sv') <- State.runStateT (step (adaptState gst) st) sv
885 return $ case r of
886 Yield x s -> Yield (sv', x) (s, sv')
887 Skip s -> Skip (s, sv')
888 Stop -> Stop
890------------------------------------------------------------------------------
891-- Elimination by Folds
892------------------------------------------------------------------------------
894------------------------------------------------------------------------------
895-- Right Folds
896------------------------------------------------------------------------------
898{-# INLINE_NORMAL foldr1 #-}
899foldr1 :: Monad m => (a -> a -> a) -> Stream m a -> m (Maybe a)
900foldr1 f m = do
901 r <- uncons m
902 case r of
903 Nothing -> return Nothing
904 Just (h, t) -> fmap Just (foldr f h t)
906------------------------------------------------------------------------------
907-- Left Folds
908------------------------------------------------------------------------------
910{-# INLINE_NORMAL foldlT #-}
911foldlT :: (Monad m, Monad (s m), MonadTrans s)
912 => (s m b -> a -> s m b) -> s m b -> Stream m a -> s m b
913foldlT fstep begin (Stream step state) = go SPEC begin state
914 where
915 go !_ acc st = do
916 r <- lift $ step defState st
917 case r of
918 Yield x s -> go SPEC (fstep acc x) s
919 Skip s -> go SPEC acc s
920 Stop -> acc
922-- Note, this is going to have horrible performance, because of the nature of
923-- the stream type (i.e. direct stream vs CPS). Its only for reference, it is
924-- likely be practically unusable.
925{-# INLINE_NORMAL foldlS #-}
926foldlS :: Monad m
927 => (Stream m b -> a -> Stream m b) -> Stream m b -> Stream m a -> Stream m b
928foldlS fstep begin (Stream step state) = Stream step' (Left (state, begin))
929 where
930 step' gst (Left (st, acc)) = do
931 r <- step (adaptState gst) st
932 return $ case r of
933 Yield x s -> Skip (Left (s, fstep acc x))
934 Skip s -> Skip (Left (s, acc))
935 Stop -> Skip (Right acc)
937 step' gst (Right (Stream stp stt)) = do
938 r <- stp (adaptState gst) stt
939 return $ case r of
940 Yield x s -> Yield x (Right (Stream stp s))
941 Skip s -> Skip (Right (Stream stp s))
942 Stop -> Stop
944------------------------------------------------------------------------------
945-- Specialized Folds
946------------------------------------------------------------------------------
948-- | Run a streaming composition, discard the results.
949{-# INLINE_LATE drain #-}
950drain :: Monad m => Stream m a -> m ()
951-- drain = foldrM (\_ xs -> xs) (return ())
952drain (Stream step state) = go SPEC state
953 where
954 go !_ st = do
955 r <- step defState st
956 case r of
957 Yield _ s -> go SPEC s
958 Skip s -> go SPEC s
959 Stop -> return ()
961{-# INLINE_NORMAL null #-}
962null :: Monad m => Stream m a -> m Bool
963null m = foldrM (\_ _ -> return False) (return True) m
965{-# INLINE_NORMAL head #-}
966head :: Monad m => Stream m a -> m (Maybe a)
967head m = foldrM (\x _ -> return (Just x)) (return Nothing) m
969{-# INLINE_NORMAL headElse #-}
970headElse :: Monad m => a -> Stream m a -> m a
971headElse a m = foldrM (\x _ -> return x) (return a) m
973-- Does not fuse, has the same performance as the StreamK version.
974{-# INLINE_NORMAL tail #-}
975tail :: Monad m => Stream m a -> m (Maybe (Stream m a))
976tail (UnStream step state) = go state
977 where
978 go st = do
979 r <- step defState st
980 case r of
981 Yield _ s -> return (Just $ Stream step s)
982 Skip s -> go s
983 Stop -> return Nothing
985-- XXX will it fuse? need custom impl?
986{-# INLINE_NORMAL last #-}
987last :: Monad m => Stream m a -> m (Maybe a)
988last = foldl' (\_ y -> Just y) Nothing
990{-# INLINE_NORMAL elem #-}
991elem :: (Monad m, Eq a) => a -> Stream m a -> m Bool
992-- elem e m = foldrM (\x xs -> if x == e then return True else xs) (return False) m
993elem e (Stream step state) = go state
994 where
995 go st = do
996 r <- step defState st
997 case r of
998 Yield x s
999 | x == e -> return True
1000 | otherwise -> go s
1001 Skip s -> go s
1002 Stop -> return False
1004{-# INLINE_NORMAL notElem #-}
1005notElem :: (Monad m, Eq a) => a -> Stream m a -> m Bool
1006notElem e s = fmap not (elem e s)
1008{-# INLINE_NORMAL all #-}
1009all :: Monad m => (a -> Bool) -> Stream m a -> m Bool
1010-- all p m = foldrM (\x xs -> if p x then xs else return False) (return True) m
1011all p (Stream step state) = go state
1012 where
1013 go st = do
1014 r <- step defState st
1015 case r of
1016 Yield x s
1017 | p x -> go s
1018 | otherwise -> return False
1019 Skip s -> go s
1020 Stop -> return True
1022{-# INLINE_NORMAL any #-}
1023any :: Monad m => (a -> Bool) -> Stream m a -> m Bool
1024-- any p m = foldrM (\x xs -> if p x then return True else xs) (return False) m
1025any p (Stream step state) = go state
1026 where
1027 go st = do
1028 r <- step defState st
1029 case r of
1030 Yield x s
1031 | p x -> return True
1032 | otherwise -> go s
1033 Skip s -> go s
1034 Stop -> return False
1036{-# INLINE_NORMAL maximum #-}
1037maximum :: (Monad m, Ord a) => Stream m a -> m (Maybe a)
1038maximum (Stream step state) = go Nothing state
1039 where
1040 go Nothing st = do
1041 r <- step defState st
1042 case r of
1043 Yield x s -> go (Just x) s
1044 Skip s -> go Nothing s
1045 Stop -> return Nothing
1046 go (Just acc) st = do
1047 r <- step defState st
1048 case r of
1049 Yield x s
1050 | acc <= x -> go (Just x) s
1051 | otherwise -> go (Just acc) s
1052 Skip s -> go (Just acc) s
1053 Stop -> return (Just acc)
1055{-# INLINE_NORMAL maximumBy #-}
1056maximumBy :: Monad m => (a -> a -> Ordering) -> Stream m a -> m (Maybe a)
1057maximumBy cmp (Stream step state) = go Nothing state
1058 where
1059 go Nothing st = do
1060 r <- step defState st
1061 case r of
1062 Yield x s -> go (Just x) s
1063 Skip s -> go Nothing s
1064 Stop -> return Nothing
1065 go (Just acc) st = do
1066 r <- step defState st
1067 case r of
1068 Yield x s -> case cmp acc x of
1069 GT -> go (Just acc) s
1070 _ -> go (Just x) s
1071 Skip s -> go (Just acc) s
1072 Stop -> return (Just acc)
1074{-# INLINE_NORMAL minimum #-}
1075minimum :: (Monad m, Ord a) => Stream m a -> m (Maybe a)
1076minimum (Stream step state) = go Nothing state
1077 where
1078 go Nothing st = do
1079 r <- step defState st
1080 case r of
1081 Yield x s -> go (Just x) s
1082 Skip s -> go Nothing s
1083 Stop -> return Nothing
1084 go (Just acc) st = do
1085 r <- step defState st
1086 case r of
1087 Yield x s
1088 | acc <= x -> go (Just acc) s
1089 | otherwise -> go (Just x) s
1090 Skip s -> go (Just acc) s
1091 Stop -> return (Just acc)
1093{-# INLINE_NORMAL minimumBy #-}
1094minimumBy :: Monad m => (a -> a -> Ordering) -> Stream m a -> m (Maybe a)
1095minimumBy cmp (Stream step state) = go Nothing state
1096 where
1097 go Nothing st = do
1098 r <- step defState st
1099 case r of
1100 Yield x s -> go (Just x) s
1101 Skip s -> go Nothing s
1102 Stop -> return Nothing
1103 go (Just acc) st = do
1104 r <- step defState st
1105 case r of
1106 Yield x s -> case cmp acc x of
1107 GT -> go (Just x) s
1108 _ -> go (Just acc) s
1109 Skip s -> go (Just acc) s
1110 Stop -> return (Just acc)
1112{-# INLINE_NORMAL (!!) #-}
1113(!!) :: (Monad m) => Stream m a -> Int -> m (Maybe a)
1114(Stream step state) !! i = go i state
1115 where
1116 go n st = do
1117 r <- step defState st
1118 case r of
1119 Yield x s | n < 0 -> return Nothing
1120 | n == 0 -> return $ Just x
1121 | otherwise -> go (n - 1) s
1122 Skip s -> go n s
1123 Stop -> return Nothing
1125{-# INLINE_NORMAL lookup #-}
1126lookup :: (Monad m, Eq a) => a -> Stream m (a, b) -> m (Maybe b)
1127lookup e m = foldrM (\(a, b) xs -> if e == a then return (Just b) else xs)
1128 (return Nothing) m
1130{-# INLINE_NORMAL findM #-}
1131findM :: Monad m => (a -> m Bool) -> Stream m a -> m (Maybe a)
1132findM p m = foldrM (\x xs -> p x >>= \r -> if r then return (Just x) else xs)
1133 (return Nothing) m
1135{-# INLINE find #-}
1136find :: Monad m => (a -> Bool) -> Stream m a -> m (Maybe a)
1137find p = findM (return . p)
1139{-# INLINE_NORMAL findIndices #-}
1140findIndices :: Monad m => (a -> Bool) -> Stream m a -> Stream m Int
1141findIndices p (Stream step state) = Stream step' (state, 0)
1142 where
1143 {-# INLINE_LATE step' #-}
1144 step' gst (st, i) = i `seq` do
1145 r <- step (adaptState gst) st
1146 return $ case r of
1147 Yield x s -> if p x then Yield i (s, i+1) else Skip (s, i+1)
1148 Skip s -> Skip (s, i)
1149 Stop -> Stop
1151{-# INLINE toListRev #-}
1152toListRev :: Monad m => Stream m a -> m [a]
1153toListRev = foldl' (flip (:)) []
1155-- We can implement reverse as:
1157-- > reverse = foldlS (flip cons) nil
1159-- However, this implementation is unusable because of the horrible performance
1160-- of cons. So we just convert it to a list first and then stream from the
1161-- list.
1163-- XXX Maybe we can use an Array instead of a list here?
1164{-# INLINE_NORMAL reverse #-}
1165reverse :: Monad m => Stream m a -> Stream m a
1166reverse m = Stream step Nothing
1167 where
1168 {-# INLINE_LATE step #-}
1169 step _ Nothing = do
1170 xs <- toListRev m
1171 return $ Skip (Just xs)
1172 step _ (Just (x:xs)) = return $ Yield x (Just xs)
1173 step _ (Just []) = return Stop
1175-- Much faster reverse for Storables
1176{-# INLINE_NORMAL reverse' #-}
1177reverse' :: forall m a. (MonadIO m, Storable a) => Stream m a -> Stream m a
1179-- This commented implementation copies the whole stream into one single array
1180-- and then streams from that array, this is 3-4x faster than the chunked code
1181-- that follows. Though this could be problematic due to unbounded large
1182-- allocations. We need to figure out why the chunked code is slower and if we
1183-- can optimize the chunked code to work as fast as this one. It may be a
1184-- fusion issue?
1185import Foreign.ForeignPtr (touchForeignPtr)
1186import Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr)
1187import Foreign.Ptr (Ptr, plusPtr)
1188reverse' m = Stream step Nothing
1189 where
1190 {-# INLINE_LATE step #-}
1191 step _ Nothing = do
1192 arr <- A.fromStreamD m
1193 let p = aEnd arr `plusPtr` negate (sizeOf (undefined :: a))
1194 return $ Skip $ Just (aStart arr, p)
1196 step _ (Just (start, p)) | p < unsafeForeignPtrToPtr start = return Stop
1198 step _ (Just (start, p)) = do
1199 let !x = A.unsafeInlineIO $ do
1200 r <- peek p
1201 touchForeignPtr start
1202 return r
1203 next = p `plusPtr` negate (sizeOf (undefined :: a))
1204 return $ Yield x (Just (start, next))
1206reverse' m =
1207 A.flattenArraysRev
1208 $ fromStreamK
1209 $ K.reverse
1210 $ toStreamK
1211 $ A.fromStreamDArraysOf A.defaultChunkSize m
1214------------------------------------------------------------------------------
1215-- Grouping/Splitting
1216------------------------------------------------------------------------------
1218{-# INLINE_NORMAL splitSuffixBy' #-}
1219splitSuffixBy' :: Monad m
1220 => (a -> Bool) -> Fold m a b -> Stream m a -> Stream m b
1221splitSuffixBy' predicate f (Stream step state) =
1222 Stream (stepOuter f) (Just state)
1224 where
1226 {-# INLINE_LATE stepOuter #-}
1227 stepOuter (Fold fstep initial done) gst (Just st) = do
1228 res <- step (adaptState gst) st
1229 case res of
1230 Yield x s -> do
1231 acc <- initial
1232 acc' <- fstep acc x
1233 if (predicate x)
1234 then done acc' >>= \val -> return $ Yield val (Just s)
1235 else go SPEC s acc'
1237 Skip s -> return $ Skip $ Just s
1238 Stop -> return Stop
1240 where
1242 go !_ stt !acc = do
1243 res <- step (adaptState gst) stt
1244 case res of
1245 Yield x s -> do
1246 acc' <- fstep acc x
1247 if (predicate x)
1248 then done acc' >>= \val -> return $ Yield val (Just s)
1249 else go SPEC s acc'
1250 Skip s -> go SPEC s acc
1251 Stop -> done acc >>= \val -> return $ Yield val Nothing
1253 stepOuter _ _ Nothing = return Stop
1255{-# INLINE_NORMAL groupsBy #-}
1256groupsBy :: Monad m
1257 => (a -> a -> Bool)
1258 -> Fold m a b
1259 -> Stream m a
1260 -> Stream m b
1261groupsBy cmp f (Stream step state) = Stream (stepOuter f) (Just state, Nothing)
1263 where
1265 {-# INLINE_LATE stepOuter #-}
1266 stepOuter (Fold fstep initial done) gst (Just st, Nothing) = do
1267 res <- step (adaptState gst) st
1268 case res of
1269 Yield x s -> do
1270 acc <- initial
1271 acc' <- fstep acc x
1272 go SPEC x s acc'
1274 Skip s -> return $ Skip $ (Just s, Nothing)
1275 Stop -> return Stop
1277 where
1279 go !_ prev stt !acc = do
1280 res <- step (adaptState gst) stt
1281 case res of
1282 Yield x s -> do
1283 if cmp x prev
1284 then do
1285 acc' <- fstep acc x
1286 go SPEC prev s acc'
1287 else done acc >>= \r -> return $ Yield r (Just s, Just x)
1288 Skip s -> go SPEC prev s acc
1289 Stop -> done acc >>= \r -> return $ Yield r (Nothing, Nothing)
1291 stepOuter (Fold fstep initial done) gst (Just st, Just prev) = do
1292 acc <- initial
1293 acc' <- fstep acc prev
1294 go SPEC st acc'
1296 where
1298 -- XXX code duplicated from the previous equation
1299 go !_ stt !acc = do
1300 res <- step (adaptState gst) stt
1301 case res of
1302 Yield x s -> do
1303 if cmp x prev
1304 then do
1305 acc' <- fstep acc x
1306 go SPEC s acc'
1307 else done acc >>= \r -> return $ Yield r (Just s, Just x)
1308 Skip s -> go SPEC s acc
1309 Stop -> done acc >>= \r -> return $ Yield r (Nothing, Nothing)
1311 stepOuter _ _ (Nothing,_) = return Stop
1313{-# INLINE_NORMAL groupsRollingBy #-}
1314groupsRollingBy :: Monad m
1315 => (a -> a -> Bool)
1316 -> Fold m a b
1317 -> Stream m a
1318 -> Stream m b
1319groupsRollingBy cmp f (Stream step state) =
1320 Stream (stepOuter f) (Just state, Nothing)
1321 where
1323 {-# INLINE_LATE stepOuter #-}
1324 stepOuter (Fold fstep initial done) gst (Just st, Nothing) = do
1325 res <- step (adaptState gst) st
1326 case res of
1327 Yield x s -> do
1328 acc <- initial
1329 acc' <- fstep acc x
1330 go SPEC x s acc'
1332 Skip s -> return $ Skip $ (Just s, Nothing)
1333 Stop -> return Stop
1335 where
1336 go !_ prev stt !acc = do
1337 res <- step (adaptState gst) stt
1338 case res of
1339 Yield x s -> do
1340 if cmp prev x
1341 then do
1342 acc' <- fstep acc x
1343 go SPEC x s acc'
1344 else
1345 done acc >>= \r -> return $ Yield r (Just s, Just x)
1346 Skip s -> go SPEC prev s acc
1347 Stop -> done acc >>= \r -> return $ Yield r (Nothing, Nothing)
1349 stepOuter (Fold fstep initial done) gst (Just st, Just prev') = do
1350 acc <- initial
1351 acc' <- fstep acc prev'
1352 go SPEC prev' st acc'
1354 where
1355 go !_ prevv stt !acc = do
1356 res <- step (adaptState gst) stt
1357 case res of
1358 Yield x s -> do
1359 if cmp prevv x
1360 then do
1361 acc' <- fstep acc x
1362 go SPEC x s acc'
1363 else done acc >>= \r -> return $ Yield r (Just s, Just x)
1364 Skip s -> go SPEC prevv s acc
1365 Stop -> done acc >>= \r -> return $ Yield r (Nothing, Nothing)
1367 stepOuter _ _ (Nothing, _) = return Stop
1369{-# INLINE_NORMAL splitBy #-}
1370splitBy :: Monad m => (a -> Bool) -> Fold m a b -> Stream m a -> Stream m b
1371splitBy predicate f (Stream step state) = Stream (step' f) (Just state)
1373 where
1375 {-# INLINE_LATE step' #-}
1376 step' (Fold fstep initial done) gst (Just st) = initial >>= go SPEC st
1378 where
1380 go !_ stt !acc = do
1381 res <- step (adaptState gst) stt
1382 case res of
1383 Yield x s -> do
1384 if predicate x
1385 then done acc >>= \r -> return $ Yield r (Just s)
1386 else do
1387 acc' <- fstep acc x
1388 go SPEC s acc'
1389 Skip s -> go SPEC s acc
1390 Stop -> done acc >>= \r -> return $ Yield r Nothing
1392 step' _ _ Nothing = return Stop
1394-- XXX requires -funfolding-use-threshold=150 in lines-unlines benchmark
1395{-# INLINE_NORMAL splitSuffixBy #-}
1396splitSuffixBy :: Monad m
1397 => (a -> Bool) -> Fold m a b -> Stream m a -> Stream m b
1398splitSuffixBy predicate f (Stream step state) = Stream (step' f) (Just state)
1400 where
1402 {-# INLINE_LATE step' #-}
1403 step' (Fold fstep initial done) gst (Just st) = do
1404 res <- step (adaptState gst) st
1405 case res of
1406 Yield x s -> do
1407 acc <- initial
1408 if predicate x
1409 then done acc >>= \val -> return $ Yield val (Just s)
1410 else do
1411 acc' <- fstep acc x
1412 go SPEC s acc'
1414 Skip s -> return $ Skip $ Just s
1415 Stop -> return Stop
1417 where
1419 go !_ stt !acc = do
1420 res <- step (adaptState gst) stt
1421 case res of
1422 Yield x s -> do
1423 if predicate x
1424 then done acc >>= \r -> return $ Yield r (Just s)
1425 else do
1426 acc' <- fstep acc x
1427 go SPEC s acc'
1428 Skip s -> go SPEC s acc
1429 Stop -> done acc >>= \r -> return $ Yield r Nothing
1431 step' _ _ Nothing = return Stop
1433{-# INLINE_NORMAL wordsBy #-}
1434wordsBy :: Monad m => (a -> Bool) -> Fold m a b -> Stream m a -> Stream m b
1435wordsBy predicate f (Stream step state) = Stream (stepOuter f) (Just state)
1437 where
1439 {-# INLINE_LATE stepOuter #-}
1440 stepOuter (Fold fstep initial done) gst (Just st) = do
1441 res <- step (adaptState gst) st
1442 case res of
1443 Yield x s -> do
1444 if predicate x
1445 then return $ Skip (Just s)
1446 else do
1447 acc <- initial
1448 acc' <- fstep acc x
1449 go SPEC s acc'
1451 Skip s -> return $ Skip $ Just s
1452 Stop -> return Stop
1454 where
1456 go !_ stt !acc = do
1457 res <- step (adaptState gst) stt
1458 case res of
1459 Yield x s -> do
1460 if predicate x
1461 then done acc >>= \r -> return $ Yield r (Just s)
1462 else do
1463 acc' <- fstep acc x
1464 go SPEC s acc'
1465 Skip s -> go SPEC s acc
1466 Stop -> done acc >>= \r -> return $ Yield r Nothing
1468 stepOuter _ _ Nothing = return Stop
1470-- String search algorithms:
1471-- http://www-igm.univ-mlv.fr/~lecroq/string/index.html
1474-- TODO can we unify the splitting operations using a splitting configuration
1475-- like in the split package.
1477data SplitStyle = Infix | Suffix | Prefix deriving (Eq, Show)
1479data SplitOptions = SplitOptions
1480 { style :: SplitStyle
1481 , withSep :: Bool -- ^ keep the separators in output
1482 -- , compact :: Bool -- ^ treat multiple consecutive separators as one
1483 -- , trimHead :: Bool -- ^ drop blank at head
1484 -- , trimTail :: Bool -- ^ drop blank at tail
1488data SplitOnState s a =
1489 GO_START
1490 | GO_EMPTY_PAT s
1491 | GO_SINGLE_PAT s a
1492 | GO_SHORT_PAT s
1493 | GO_KARP_RABIN s !(RB.Ring a) !(Ptr a)
1494 | GO_DONE
1496{-# INLINE_NORMAL splitOn #-}
1497splitOn
1498 :: forall m a b. (MonadIO m, Storable a, Enum a, Eq a)
1499 => Array a
1500 -> Fold m a b
1501 -> Stream m a
1502 -> Stream m b
1503splitOn patArr@Array{..} (Fold fstep initial done) (Stream step state) =
1504 Stream stepOuter GO_START
1506 where
1508 patLen = A.length patArr
1509 maxIndex = patLen - 1
1510 elemBits = sizeOf (undefined :: a) * 8
1512 {-# INLINE_LATE stepOuter #-}
1513 stepOuter _ GO_START =
1514 if patLen == 0
1515 then return $ Skip $ GO_EMPTY_PAT state
1516 else if patLen == 1
1517 then do
1518 r <- liftIO $ (A.unsafeIndexIO patArr 0)
1519 return $ Skip $ GO_SINGLE_PAT state r
1520 else if sizeOf (undefined :: a) * patLen
1521 <= sizeOf (undefined :: Word)
1522 then return $ Skip $ GO_SHORT_PAT state
1523 else do
1524 (rb, rhead) <- liftIO $ RB.new patLen
1525 return $ Skip $ GO_KARP_RABIN state rb rhead
1527 stepOuter gst (GO_SINGLE_PAT stt pat) = initial >>= go SPEC stt
1529 where
1531 go !_ st !acc = do
1532 res <- step (adaptState gst) st
1533 case res of
1534 Yield x s -> do
1535 if pat == x
1536 then do
1537 r <- done acc
1538 return $ Yield r (GO_SINGLE_PAT s pat)
1539 else fstep acc x >>= go SPEC s
1540 Skip s -> go SPEC s acc
1541 Stop -> done acc >>= \r -> return $ Yield r GO_DONE
1543 stepOuter gst (GO_SHORT_PAT stt) = initial >>= go0 SPEC 0 (0 :: Word) stt
1545 where
1547 mask :: Word
1548 mask = (1 `shiftL` (elemBits * patLen)) - 1
1550 addToWord wrd a = (wrd `shiftL` elemBits) .|. fromIntegral (fromEnum a)
1552 patWord :: Word
1553 patWord = mask .&. A.foldl' addToWord 0 patArr
1555 go0 !_ !idx wrd st !acc = do
1556 res <- step (adaptState gst) st
1557 case res of
1558 Yield x s -> do
1559 let wrd' = addToWord wrd x
1560 if idx == maxIndex
1561 then do
1562 if wrd' .&. mask == patWord
1563 then do
1564 r <- done acc
1565 return $ Yield r (GO_SHORT_PAT s)
1566 else go1 SPEC wrd' s acc
1567 else go0 SPEC (idx + 1) wrd' s acc
1568 Skip s -> go0 SPEC idx wrd s acc
1569 Stop -> do
1570 acc' <- if idx /= 0
1571 then go2 wrd idx acc
1572 else return acc
1573 done acc' >>= \r -> return $ Yield r GO_DONE
1575 {-# INLINE go1 #-}
1576 go1 !_ wrd st !acc = do
1577 res <- step (adaptState gst) st
1578 case res of
1579 Yield x s -> do
1580 let wrd' = addToWord wrd x
1581 old = (mask .&. wrd) `shiftR` (elemBits * (patLen - 1))
1582 acc' <- fstep acc (toEnum $ fromIntegral old)
1583 if wrd' .&. mask == patWord
1584 then done acc' >>= \r -> return $ Yield r (GO_SHORT_PAT s)
1585 else go1 SPEC wrd' s acc'
1586 Skip s -> go1 SPEC wrd s acc
1587 Stop -> do
1588 acc' <- go2 wrd patLen acc
1589 done acc' >>= \r -> return $ Yield r GO_DONE
1591 go2 !wrd !n !acc | n > 0 = do
1592 let old = (mask .&. wrd) `shiftR` (elemBits * (n - 1))
1593 fstep acc (toEnum $ fromIntegral old) >>= go2 wrd (n - 1)
1594 go2 _ _ acc = return acc
1596 stepOuter gst (GO_KARP_RABIN stt rb rhead) = do
1597 initial >>= go0 SPEC 0 rhead stt
1599 where
1601 k = 2891336453 :: Word32
1602 coeff = k ^ patLen
1603 addCksum cksum a = cksum * k + fromIntegral (fromEnum a)
1604 deltaCksum cksum old new =
1605 addCksum cksum new - coeff * fromIntegral (fromEnum old)
1607 -- XXX shall we use a random starting hash or 1 instead of 0?
1608 patHash = A.foldl' addCksum 0 patArr
1610 -- rh == ringHead
1611 go0 !_ !idx !rh st !acc = do
1612 res <- step (adaptState gst) st
1613 case res of
1614 Yield x s -> do
1615 rh' <- liftIO $ RB.unsafeInsert rb rh x
1616 if idx == maxIndex
1617 then do
1618 let fold = RB.unsafeFoldRing (RB.ringBound rb)
1619 let !ringHash = fold addCksum 0 rb
1620 if ringHash == patHash
1621 then go2 SPEC ringHash rh' s acc
1622 else go1 SPEC ringHash rh' s acc
1623 else go0 SPEC (idx + 1) rh' s acc
1624 Skip s -> go0 SPEC idx rh s acc
1625 Stop -> do
1626 !acc' <- if idx /= 0
1627 then RB.unsafeFoldRingM rh fstep acc rb
1628 else return acc
1629 done acc' >>= \r -> return $ Yield r GO_DONE
1631 -- XXX Theoretically this code can do 4 times faster if GHC generates
1632 -- optimal code. If we use just "(cksum' == patHash)" condition it goes
1633 -- 4x faster, as soon as we add the "RB.unsafeEqArray rb v" condition
1634 -- the generated code changes drastically and becomes 4x slower. Need
1635 -- to investigate what is going on with GHC.
1636 {-# INLINE go1 #-}
1637 go1 !_ !cksum !rh st !acc = do
1638 res <- step (adaptState gst) st
1639 case res of
1640 Yield x s -> do
1641 old <- liftIO $ peek rh
1642 let cksum' = deltaCksum cksum old x
1643 acc' <- fstep acc old
1645 if (cksum' == patHash)
1646 then do
1647 rh' <- liftIO (RB.unsafeInsert rb rh x)
1648 go2 SPEC cksum' rh' s acc'
1649 else do
1650 rh' <- liftIO (RB.unsafeInsert rb rh x)
1651 go1 SPEC cksum' rh' s acc'
1652 Skip s -> go1 SPEC cksum rh s acc
1653 Stop -> do
1654 acc' <- RB.unsafeFoldRingFullM rh fstep acc rb
1655 done acc' >>= \r -> return $ Yield r GO_DONE
1657 go2 !_ !cksum' !rh' s !acc' = do
1658 if RB.unsafeEqArray rb rh' patArr
1659 then do
1660 r <- done acc'
1661 return $ Yield r (GO_KARP_RABIN s rb rhead)
1662 else go1 SPEC cksum' rh' s acc'
1664 stepOuter gst (GO_EMPTY_PAT st) = do
1665 res <- step (adaptState gst) st
1666 case res of
1667 Yield x s -> do
1668 acc <- initial
1669 acc' <- fstep acc x
1670 done acc' >>= \r -> return $ Yield r (GO_EMPTY_PAT s)
1671 Skip s -> return $ Skip (GO_EMPTY_PAT s)
1672 Stop -> return Stop
1674 stepOuter _ GO_DONE = return Stop
1676{-# INLINE_NORMAL splitSuffixOn #-}
1677splitSuffixOn
1678 :: forall m a b. (MonadIO m, Storable a, Enum a, Eq a)
1679 => Bool
1680 -> Array a
1681 -> Fold m a b
1682 -> Stream m a
1683 -> Stream m b
1684splitSuffixOn withSep patArr@Array{..} (Fold fstep initial done)
1685 (Stream step state) =
1686 Stream stepOuter GO_START
1688 where
1690 patLen = A.length patArr
1691 maxIndex = patLen - 1
1692 elemBits = sizeOf (undefined :: a) * 8
1694 {-# INLINE_LATE stepOuter #-}
1695 stepOuter _ GO_START =
1696 if patLen == 0
1697 then return $ Skip $ GO_EMPTY_PAT state
1698 else if patLen == 1
1699 then do
1700 r <- liftIO $ (A.unsafeIndexIO patArr 0)
1701 return $ Skip $ GO_SINGLE_PAT state r
1702 else if sizeOf (undefined :: a) * patLen
1703 <= sizeOf (undefined :: Word)
1704 then return $ Skip $ GO_SHORT_PAT state
1705 else do
1706 (rb, rhead) <- liftIO $ RB.new patLen
1707 return $ Skip $ GO_KARP_RABIN state rb rhead
1709 stepOuter gst (GO_SINGLE_PAT stt pat) = do
1710 -- This first part is the only difference between splitOn and
1711 -- splitSuffixOn.
1712 -- If the last element is a separator do not issue a blank segment.
1713 res <- step (adaptState gst) stt
1714 case res of
1715 Yield x s -> do
1716 acc <- initial
1717 if pat == x
1718 then do
1719 acc' <- if withSep then fstep acc x else return acc
1720 done acc' >>= \r -> return $ Yield r (GO_SINGLE_PAT s pat)
1721 else fstep acc x >>= go SPEC s
1722 Skip s -> return $ Skip $ (GO_SINGLE_PAT s pat)
1723 Stop -> return Stop
1725 where
1727 -- This is identical for splitOn and splitSuffixOn
1728 go !_ st !acc = do
1729 res <- step (adaptState gst) st
1730 case res of
1731 Yield x s -> do
1732 if pat == x
1733 then do
1734 acc' <- if withSep then fstep acc x else return acc
1735 r <- done acc'
1736 return $ Yield r (GO_SINGLE_PAT s pat)
1737 else fstep acc x >>= go SPEC s
1738 Skip s -> go SPEC s acc
1739 Stop -> done acc >>= \r -> return $ Yield r GO_DONE
1741 stepOuter gst (GO_SHORT_PAT stt) = do
1743 -- Call "initial" only if the stream yields an element, otherwise we
1744 -- may call "initial" but never yield anything. initial may produce a
1745 -- side effect, therefore we will end up doing and discard a side
1746 -- effect.
1748 let idx = 0
1749 let wrd = 0
1750 res <- step (adaptState gst) stt
1751 case res of
1752 Yield x s -> do
1753 acc <- initial
1754 let wrd' = addToWord wrd x
1755 acc' <- if withSep then fstep acc x else return acc
1756 if idx == maxIndex
1757 then do
1758 if wrd' .&. mask == patWord
1759 then done acc' >>= \r -> return $ Yield r (GO_SHORT_PAT s)
1760 else go0 SPEC (idx + 1) wrd' s acc'
1761 else go0 SPEC (idx + 1) wrd' s acc'
1762 Skip s -> return $ Skip (GO_SHORT_PAT s)
1763 Stop -> return Stop
1765 where
1767 mask :: Word
1768 mask = (1 `shiftL` (elemBits * patLen)) - 1
1770 addToWord wrd a = (wrd `shiftL` elemBits) .|. fromIntegral (fromEnum a)
1772 patWord :: Word
1773 patWord = mask .&. A.foldl' addToWord 0 patArr
1775 go0 !_ !idx wrd st !acc = do
1776 res <- step (adaptState gst) st
1777 case res of
1778 Yield x s -> do
1779 let wrd' = addToWord wrd x
1780 acc' <- if withSep then fstep acc x else return acc
1781 if idx == maxIndex
1782 then do
1783 if wrd' .&. mask == patWord
1784 then do
1785 r <- done acc'
1786 return $ Yield r (GO_SHORT_PAT s)
1787 else go1 SPEC wrd' s acc'
1788 else go0 SPEC (idx + 1) wrd' s acc'
1789 Skip s -> go0 SPEC idx wrd s acc
1790 Stop -> do
1791 if (idx == maxIndex) && (wrd .&. mask == patWord)
1792 then return Stop
1793 else do
1794 acc' <- if idx /= 0 && not withSep
1795 then go2 wrd idx acc
1796 else return acc
1797 done acc' >>= \r -> return $ Yield r GO_DONE
1799 {-# INLINE go1 #-}
1800 go1 !_ wrd st !acc = do
1801 res <- step (adaptState gst) st
1802 case res of
1803 Yield x s -> do
1804 let wrd' = addToWord wrd x
1805 old = (mask .&. wrd) `shiftR` (elemBits * (patLen - 1))
1806 acc' <- if withSep
1807 then fstep acc x
1808 else fstep acc (toEnum $ fromIntegral old)
1809 if wrd' .&. mask == patWord
1810 then done acc' >>= \r -> return $ Yield r (GO_SHORT_PAT s)
1811 else go1 SPEC wrd' s acc'
1812 Skip s -> go1 SPEC wrd s acc
1813 Stop ->
1814 -- If the last sequence is a separator do not issue a blank
1815 -- segment.
1816 if wrd .&. mask == patWord
1817 then return Stop
1818 else do
1819 acc' <- if withSep
1820 then return acc
1821 else go2 wrd patLen acc
1822 done acc' >>= \r -> return $ Yield r GO_DONE
1824 go2 !wrd !n !acc | n > 0 = do
1825 let old = (mask .&. wrd) `shiftR` (elemBits * (n - 1))
1826 fstep acc (toEnum $ fromIntegral old) >>= go2 wrd (n - 1)
1827 go2 _ _ acc = return acc
1829 stepOuter gst (GO_KARP_RABIN stt rb rhead) = do
1830 let idx = 0
1831 res <- step (adaptState gst) stt
1832 case res of
1833 Yield x s -> do
1834 acc <- initial
1835 acc' <- if withSep then fstep acc x else return acc
1836 rh' <- liftIO (RB.unsafeInsert rb rhead x)
1837 if idx == maxIndex
1838 then do
1839 let fold = RB.unsafeFoldRing (RB.ringBound rb)
1840 let !ringHash = fold addCksum 0 rb
1841 if ringHash == patHash
1842 then go2 SPEC ringHash rh' s acc'
1843 else go0 SPEC (idx + 1) rh' s acc'
1844 else go0 SPEC (idx + 1) rh' s acc'
1845 Skip s -> return $ Skip (GO_KARP_RABIN s rb rhead)
1846 Stop -> return Stop
1848 where
1850 k = 2891336453 :: Word32
1851 coeff = k ^ patLen
1852 addCksum cksum a = cksum * k + fromIntegral (fromEnum a)
1853 deltaCksum cksum old new =
1854 addCksum cksum new - coeff * fromIntegral (fromEnum old)
1856 -- XXX shall we use a random starting hash or 1 instead of 0?
1857 patHash = A.foldl' addCksum 0 patArr
1859 -- rh == ringHead
1860 go0 !_ !idx !rh st !acc = do
1861 res <- step (adaptState gst) st
1862 case res of
1863 Yield x s -> do
1864 acc' <- if withSep then fstep acc x else return acc
1865 rh' <- liftIO (RB.unsafeInsert rb rh x)
1866 if idx == maxIndex
1867 then do
1868 let fold = RB.unsafeFoldRing (RB.ringBound rb)
1869 let !ringHash = fold addCksum 0 rb
1870 if ringHash == patHash
1871 then go2 SPEC ringHash rh' s acc'
1872 else go1 SPEC ringHash rh' s acc'
1873 else go0 SPEC (idx + 1) rh' s acc'
1874 Skip s -> go0 SPEC idx rh s acc
1875 Stop -> do
1876 -- do not issue a blank segment when we end at pattern
1877 if (idx == maxIndex) && RB.unsafeEqArray rb rh patArr
1878 then return Stop
1879 else do
1880 !acc' <- if idx /= 0 && not withSep
1881 then RB.unsafeFoldRingM rh fstep acc rb
1882 else return acc
1883 done acc' >>= \r -> return $ Yield r GO_DONE
1885 -- XXX Theoretically this code can do 4 times faster if GHC generates
1886 -- optimal code. If we use just "(cksum' == patHash)" condition it goes
1887 -- 4x faster, as soon as we add the "RB.unsafeEqArray rb v" condition
1888 -- the generated code changes drastically and becomes 4x slower. Need
1889 -- to investigate what is going on with GHC.
1890 {-# INLINE go1 #-}
1891 go1 !_ !cksum !rh st !acc = do
1892 res <- step (adaptState gst) st
1893 case res of
1894 Yield x s -> do
1895 old <- liftIO $ peek rh
1896 let cksum' = deltaCksum cksum old x
1897 acc' <- if withSep
1898 then fstep acc x
1899 else fstep acc old
1901 if (cksum' == patHash)
1902 then do
1903 rh' <- liftIO (RB.unsafeInsert rb rh x)
1904 go2 SPEC cksum' rh' s acc'
1905 else do
1906 rh' <- liftIO (RB.unsafeInsert rb rh x)
1907 go1 SPEC cksum' rh' s acc'
1908 Skip s -> go1 SPEC cksum rh s acc
1909 Stop -> do
1910 if RB.unsafeEqArray rb rh patArr
1911 then return Stop
1912 else do
1913 acc' <- if withSep
1914 then return acc
1915 else RB.unsafeFoldRingFullM rh fstep acc rb
1916 done acc' >>= \r -> return $ Yield r GO_DONE
1918 go2 !_ !cksum' !rh' s !acc' = do
1919 if RB.unsafeEqArray rb rh' patArr
1920 then do
1921 r <- done acc'
1922 return $ Yield r (GO_KARP_RABIN s rb rhead)
1923 else go1 SPEC cksum' rh' s acc'
1925 stepOuter gst (GO_EMPTY_PAT st) = do
1926 res <- step (adaptState gst) st
1927 case res of
1928 Yield x s -> do
1929 acc <- initial
1930 acc' <- fstep acc x
1931 done acc' >>= \r -> return $ Yield r (GO_EMPTY_PAT s)
1932 Skip s -> return $ Skip (GO_EMPTY_PAT s)
1933 Stop -> return Stop
1935 stepOuter _ GO_DONE = return Stop
1937data SplitState s arr
1938 = SplitInitial s
1939 | SplitBuffering s arr
1940 | SplitSplitting s arr
1941 | SplitYielding arr (SplitState s arr)
1942 | SplitFinishing
1944-- XXX An alternative approach would be to use a partial fold (Fold m a b) to
1945-- split using a splitBy like combinator. The Fold would consume upto the
1946-- separator and return any leftover which can then be fed to the next fold.
1948-- We can revisit this once we have partial folds/parsers.
1950-- | Performs infix separator style splitting.
1951{-# INLINE_NORMAL splitInnerBy #-}
1952splitInnerBy
1953 :: Monad m
1954 => (f a -> m (f a, Maybe (f a))) -- splitter
1955 -> (f a -> f a -> m (f a)) -- joiner
1956 -> Stream m (f a)
1957 -> Stream m (f a)
1958splitInnerBy splitter joiner (Stream step1 state1) =
1959 (Stream step (SplitInitial state1))
1961 where
1963 {-# INLINE_LATE step #-}
1964 step gst (SplitInitial st) = do
1965 r <- step1 gst st
1966 case r of
1967 Yield x s -> do
1968 (x1, mx2) <- splitter x
1969 return $ case mx2 of
1970 Nothing -> Skip (SplitBuffering s x1)
1971 Just x2 -> Skip (SplitYielding x1 (SplitSplitting s x2))
1972 Skip s -> return $ Skip (SplitInitial s)
1973 Stop -> return $ Stop
1975 step gst (SplitBuffering st buf) = do
1976 r <- step1 gst st
1977 case r of
1978 Yield x s -> do
1979 (x1, mx2) <- splitter x
1980 buf' <- joiner buf x1
1981 return $ case mx2 of
1982 Nothing -> Skip (SplitBuffering s buf')
1983 Just x2 -> Skip (SplitYielding buf' (SplitSplitting s x2))
1984 Skip s -> return $ Skip (SplitBuffering s buf)
1985 Stop -> return $ Skip (SplitYielding buf SplitFinishing)
1987 step _ (SplitSplitting st buf) = do
1988 (x1, mx2) <- splitter buf
1989 return $ case mx2 of
1990 Nothing -> Skip $ SplitBuffering st x1
1991 Just x2 -> Skip $ SplitYielding x1 (SplitSplitting st x2)
1993 step _ (SplitYielding x next) = return $ Yield x next
1994 step _ SplitFinishing = return $ Stop
1996-- | Performs infix separator style splitting.
1997{-# INLINE_NORMAL splitInnerBySuffix #-}
1998splitInnerBySuffix
1999 :: (Monad m, Eq (f a), Monoid (f a))
2000 => (f a -> m (f a, Maybe (f a))) -- splitter
2001 -> (f a -> f a -> m (f a)) -- joiner
2002 -> Stream m (f a)
2003 -> Stream m (f a)
2004splitInnerBySuffix splitter joiner (Stream step1 state1) =
2005 (Stream step (SplitInitial state1))
2007 where
2009 {-# INLINE_LATE step #-}
2010 step gst (SplitInitial st) = do
2011 r <- step1 gst st
2012 case r of
2013 Yield x s -> do
2014 (x1, mx2) <- splitter x
2015 return $ case mx2 of
2016 Nothing -> Skip (SplitBuffering s x1)
2017 Just x2 -> Skip (SplitYielding x1 (SplitSplitting s x2))
2018 Skip s -> return $ Skip (SplitInitial s)
2019 Stop -> return $ Stop
2021 step gst (SplitBuffering st buf) = do
2022 r <- step1 gst st
2023 case r of
2024 Yield x s -> do
2025 (x1, mx2) <- splitter x
2026 buf' <- joiner buf x1
2027 return $ case mx2 of
2028 Nothing -> Skip (SplitBuffering s buf')
2029 Just x2 -> Skip (SplitYielding buf' (SplitSplitting s x2))
2030 Skip s -> return $ Skip (SplitBuffering s buf)
2031 Stop -> return $
2032 if buf == mempty
2033 then Stop
2034 else Skip (SplitYielding buf SplitFinishing)
2036 step _ (SplitSplitting st buf) = do
2037 (x1, mx2) <- splitter buf
2038 return $ case mx2 of
2039 Nothing -> Skip $ SplitBuffering st x1
2040 Just x2 -> Skip $ SplitYielding x1 (SplitSplitting st x2)
2042 step _ (SplitYielding x next) = return $ Yield x next
2043 step _ SplitFinishing = return $ Stop
2045------------------------------------------------------------------------------
2046-- Substreams
2047------------------------------------------------------------------------------
2049{-# INLINE_NORMAL isPrefixOf #-}
2050isPrefixOf :: (Eq a, Monad m) => Stream m a -> Stream m a -> m Bool
2051isPrefixOf (Stream stepa ta) (Stream stepb tb) = go (ta, tb, Nothing)
2052 where
2053 go (sa, sb, Nothing) = do
2054 r <- stepa defState sa
2055 case r of
2056 Yield x sa' -> go (sa', sb, Just x)
2057 Skip sa' -> go (sa', sb, Nothing)
2058 Stop -> return True
2060 go (sa, sb, Just x) = do
2061 r <- stepb defState sb
2062 case r of
2063 Yield y sb' ->
2064 if x == y
2065 then go (sa, sb', Nothing)
2066 else return False
2067 Skip sb' -> go (sa, sb', Just x)
2068 Stop -> return False
2070{-# INLINE_NORMAL isSubsequenceOf #-}
2071isSubsequenceOf :: (Eq a, Monad m) => Stream m a -> Stream m a -> m Bool
2072isSubsequenceOf (Stream stepa ta) (Stream stepb tb) = go (ta, tb, Nothing)
2073 where
2074 go (sa, sb, Nothing) = do
2075 r <- stepa defState sa
2076 case r of
2077 Yield x sa' -> go (sa', sb, Just x)
2078 Skip sa' -> go (sa', sb, Nothing)
2079 Stop -> return True
2081 go (sa, sb, Just x) = do
2082 r <- stepb defState sb
2083 case r of
2084 Yield y sb' ->
2085 if x == y
2086 then go (sa, sb', Nothing)
2087 else go (sa, sb', Just x)
2088 Skip sb' -> go (sa, sb', Just x)
2089 Stop -> return False
2091{-# INLINE_NORMAL stripPrefix #-}
2092stripPrefix
2093 :: (Eq a, Monad m)
2094 => Stream m a -> Stream m a -> m (Maybe (Stream m a))
2095stripPrefix (Stream stepa ta) (Stream stepb tb) = go (ta, tb, Nothing)
2096 where
2097 go (sa, sb, Nothing) = do
2098 r <- stepa defState sa
2099 case r of
2100 Yield x sa' -> go (sa', sb, Just x)
2101 Skip sa' -> go (sa', sb, Nothing)
2102 Stop -> return $ Just (Stream stepb sb)
2104 go (sa, sb, Just x) = do
2105 r <- stepb defState sb
2106 case r of
2107 Yield y sb' ->
2108 if x == y
2109 then go (sa, sb', Nothing)
2110 else return Nothing
2111 Skip sb' -> go (sa, sb', Just x)
2112 Stop -> return Nothing
2114------------------------------------------------------------------------------
2115-- Map and Fold
2116------------------------------------------------------------------------------
2118-- | Execute a monadic action for each element of the 'Stream'
2119{-# INLINE_NORMAL mapM_ #-}
2120mapM_ :: Monad m => (a -> m b) -> Stream m a -> m ()
2121mapM_ m = drain . mapM m
2123-------------------------------------------------------------------------------
2124-- Stream transformations using Unfolds
2125-------------------------------------------------------------------------------
2127-- Define a unique structure to use in inspection testing
2128data ConcatMapUState o i =
2129 ConcatMapUOuter o
2130 | ConcatMapUInner o i
2132-- | @concatMapU unfold stream@ uses @unfold@ to map the input stream elements
2133-- to streams and then flattens the generated streams into a single output
2134-- stream.
2136-- This is like 'concatMap' but uses an unfold with an explicit state to
2137-- generate the stream instead of a 'Stream' type generator. This allows better
2138-- optimization via fusion. This can be many times more efficient than
2139-- 'concatMap'.
2141{-# INLINE_NORMAL concatMapU #-}
2142concatMapU :: Monad m => Unfold m a b -> Stream m a -> Stream m b
2143concatMapU (Unfold istep inject) (Stream ostep ost) =
2144 Stream step (ConcatMapUOuter ost)
2145 where
2146 {-# INLINE_LATE step #-}
2147 step gst (ConcatMapUOuter o) = do
2148 r <- ostep (adaptState gst) o
2149 case r of
2150 Yield a o' -> do
2151 i <- inject a
2152 i `seq` return (Skip (ConcatMapUInner o' i))
2153 Skip o' -> return $ Skip (ConcatMapUOuter o')
2154 Stop -> return $ Stop
2156 step _ (ConcatMapUInner o i) = do
2157 r <- istep i
2158 return $ case r of
2159 Yield x i' -> Yield x (ConcatMapUInner o i')
2160 Skip i' -> Skip (ConcatMapUInner o i')
2161 Stop -> Skip (ConcatMapUOuter o)
2163data ConcatUnfoldInterleaveState o i =
2164 ConcatUnfoldInterleaveOuter o [i]
2165 | ConcatUnfoldInterleaveInner o [i]
2166 | ConcatUnfoldInterleaveInnerL [i] [i]
2167 | ConcatUnfoldInterleaveInnerR [i] [i]
2169-- XXX use arrays to store state instead of lists.
2170-- XXX In general we can use different scheduling strategies e.g. how to
2171-- schedule the outer vs inner loop or assigning weights to different streams
2172-- or outer and inner loops.
2174-- After a yield, switch to the next stream. Do not switch streams on Skip.
2175-- Yield from outer stream switches to the inner stream.
2177-- There are two choices here, (1) exhaust the outer stream first and then
2178-- start yielding from the inner streams, this is much simpler to implement,
2179-- (2) yield at least one element from an inner stream before going back to
2180-- outer stream and opening the next stream from it.
2182-- Ideally, we need some scheduling bias to inner streams vs outer stream.
2183-- Maybe we can configure the behavior.
2185{-# INLINE_NORMAL concatUnfoldInterleave #-}
2186concatUnfoldInterleave :: Monad m => Unfold m a b -> Stream m a -> Stream m b
2187concatUnfoldInterleave (Unfold istep inject) (Stream ostep ost) =
2188 Stream step (ConcatUnfoldInterleaveOuter ost [])
2189 where
2190 {-# INLINE_LATE step #-}
2191 step gst (ConcatUnfoldInterleaveOuter o ls) = do
2192 r <- ostep (adaptState gst) o
2193 case r of
2194 Yield a o' -> do
2195 i <- inject a
2196 i `seq` return (Skip (ConcatUnfoldInterleaveInner o' (i : ls)))
2197 Skip o' -> return $ Skip (ConcatUnfoldInterleaveOuter o' ls)
2198 Stop -> return $ Skip (ConcatUnfoldInterleaveInnerL ls [])
2200 step _ (ConcatUnfoldInterleaveInner _ []) = undefined
2201 step _ (ConcatUnfoldInterleaveInner o (st:ls)) = do
2202 r <- istep st
2203 return $ case r of
2204 Yield x s -> Yield x (ConcatUnfoldInterleaveOuter o (s:ls))
2205 Skip s -> Skip (ConcatUnfoldInterleaveInner o (s:ls))
2206 Stop -> Skip (ConcatUnfoldInterleaveOuter o ls)
2208 step _ (ConcatUnfoldInterleaveInnerL [] []) = return Stop
2209 step _ (ConcatUnfoldInterleaveInnerL [] rs) =
2210 return $ Skip (ConcatUnfoldInterleaveInnerR [] rs)
2212 step _ (ConcatUnfoldInterleaveInnerL (st:ls) rs) = do
2213 r <- istep st
2214 return $ case r of
2215 Yield x s -> Yield x (ConcatUnfoldInterleaveInnerL ls (s:rs))
2216 Skip s -> Skip (ConcatUnfoldInterleaveInnerL (s:ls) rs)
2217 Stop -> Skip (ConcatUnfoldInterleaveInnerL ls rs)
2219 step _ (ConcatUnfoldInterleaveInnerR [] []) = return Stop
2220 step _ (ConcatUnfoldInterleaveInnerR ls []) =
2221 return $ Skip (ConcatUnfoldInterleaveInnerL ls [])
2223 step _ (ConcatUnfoldInterleaveInnerR ls (st:rs)) = do
2224 r <- istep st
2225 return $ case r of
2226 Yield x s -> Yield x (ConcatUnfoldInterleaveInnerR (s:ls) rs)
2227 Skip s -> Skip (ConcatUnfoldInterleaveInnerR ls (s:rs))
2228 Stop -> Skip (ConcatUnfoldInterleaveInnerR ls rs)
2230-- XXX In general we can use different scheduling strategies e.g. how to
2231-- schedule the outer vs inner loop or assigning weights to different streams
2232-- or outer and inner loops.
2234-- This could be inefficient if the tasks are too small.
2236-- Compared to concatUnfoldInterleave this one switches streams on Skips.
2238{-# INLINE_NORMAL concatUnfoldRoundrobin #-}
2239concatUnfoldRoundrobin :: Monad m => Unfold m a b -> Stream m a -> Stream m b
2240concatUnfoldRoundrobin (Unfold istep inject) (Stream ostep ost) =
2241 Stream step (ConcatUnfoldInterleaveOuter ost [])
2242 where
2243 {-# INLINE_LATE step #-}
2244 step gst (ConcatUnfoldInterleaveOuter o ls) = do
2245 r <- ostep (adaptState gst) o
2246 case r of
2247 Yield a o' -> do
2248 i <- inject a
2249 i `seq` return (Skip (ConcatUnfoldInterleaveInner o' (i : ls)))
2250 Skip o' -> return $ Skip (ConcatUnfoldInterleaveInner o' ls)
2251 Stop -> return $ Skip (ConcatUnfoldInterleaveInnerL ls [])
2253 step _ (ConcatUnfoldInterleaveInner o []) =
2254 return $ Skip (ConcatUnfoldInterleaveOuter o [])
2256 step _ (ConcatUnfoldInterleaveInner o (st:ls)) = do
2257 r <- istep st
2258 return $ case r of
2259 Yield x s -> Yield x (ConcatUnfoldInterleaveOuter o (s:ls))
2260 Skip s -> Skip (ConcatUnfoldInterleaveOuter o (s:ls))
2261 Stop -> Skip (ConcatUnfoldInterleaveOuter o ls)
2263 step _ (ConcatUnfoldInterleaveInnerL [] []) = return Stop
2264 step _ (ConcatUnfoldInterleaveInnerL [] rs) =
2265 return $ Skip (ConcatUnfoldInterleaveInnerR [] rs)
2267 step _ (ConcatUnfoldInterleaveInnerL (st:ls) rs) = do
2268 r <- istep st
2269 return $ case r of
2270 Yield x s -> Yield x (ConcatUnfoldInterleaveInnerL ls (s:rs))
2271 Skip s -> Skip (ConcatUnfoldInterleaveInnerL ls (s:rs))
2272 Stop -> Skip (ConcatUnfoldInterleaveInnerL ls rs)
2274 step _ (ConcatUnfoldInterleaveInnerR [] []) = return Stop
2275 step _ (ConcatUnfoldInterleaveInnerR ls []) =
2276 return $ Skip (ConcatUnfoldInterleaveInnerL ls [])
2278 step _ (ConcatUnfoldInterleaveInnerR ls (st:rs)) = do
2279 r <- istep st
2280 return $ case r of
2281 Yield x s -> Yield x (ConcatUnfoldInterleaveInnerR (s:ls) rs)
2282 Skip s -> Skip (ConcatUnfoldInterleaveInnerR (s:ls) rs)
2283 Stop -> Skip (ConcatUnfoldInterleaveInnerR ls rs)
2285data AppendState s1 s2 = AppendFirst s1 | AppendSecond s2
2287-- Note that this could be much faster compared to the CPS stream. However, as
2288-- the number of streams being composed increases this may become expensive.
2289-- Need to see where the breaking point is between the two.
2291{-# INLINE_NORMAL append #-}
2292append :: Monad m => Stream m a -> Stream m a -> Stream m a
2293append (Stream step1 state1) (Stream step2 state2) =
2294 Stream step (AppendFirst state1)
2296 where
2298 {-# INLINE_LATE step #-}
2299 step gst (AppendFirst st) = do
2300 r <- step1 gst st
2301 return $ case r of
2302 Yield a s -> Yield a (AppendFirst s)
2303 Skip s -> Skip (AppendFirst s)
2304 Stop -> Skip (AppendSecond state2)
2306 step gst (AppendSecond st) = do
2307 r <- step2 gst st
2308 return $ case r of
2309 Yield a s -> Yield a (AppendSecond s)
2310 Skip s -> Skip (AppendSecond s)
2311 Stop -> Stop
2313data InterleaveState s1 s2 = InterleaveFirst s1 s2 | InterleaveSecond s1 s2
2314 | InterleaveSecondOnly s2 | InterleaveFirstOnly s1
2316{-# INLINE_NORMAL interleave #-}
2317interleave :: Monad m => Stream m a -> Stream m a -> Stream m a
2318interleave (Stream step1 state1) (Stream step2 state2) =
2319 Stream step (InterleaveFirst state1 state2)
2321 where
2323 {-# INLINE_LATE step #-}
2324 step gst (InterleaveFirst st1 st2) = do
2325 r <- step1 gst st1
2326 return $ case r of
2327 Yield a s -> Yield a (InterleaveSecond s st2)
2328 Skip s -> Skip (InterleaveFirst s st2)
2329 Stop -> Skip (InterleaveSecondOnly st2)
2331 step gst (InterleaveSecond st1 st2) = do
2332 r <- step2 gst st2
2333 return $ case r of
2334 Yield a s -> Yield a (InterleaveFirst st1 s)
2335 Skip s -> Skip (InterleaveSecond st1 s)
2336 Stop -> Skip (InterleaveFirstOnly st1)
2338 step gst (InterleaveFirstOnly st1) = do
2339 r <- step1 gst st1
2340 return $ case r of
2341 Yield a s -> Yield a (InterleaveFirstOnly s)
2342 Skip s -> Skip (InterleaveFirstOnly s)
2343 Stop -> Stop
2345 step gst (InterleaveSecondOnly st2) = do
2346 r <- step2 gst st2
2347 return $ case r of
2348 Yield a s -> Yield a (InterleaveSecondOnly s)
2349 Skip s -> Skip (InterleaveSecondOnly s)
2350 Stop -> Stop
2352{-# INLINE_NORMAL interleaveMin #-}
2353interleaveMin :: Monad m => Stream m a -> Stream m a -> Stream m a
2354interleaveMin (Stream step1 state1) (Stream step2 state2) =
2355 Stream step (InterleaveFirst state1 state2)
2357 where
2359 {-# INLINE_LATE step #-}
2360 step gst (InterleaveFirst st1 st2) = do
2361 r <- step1 gst st1
2362 return $ case r of
2363 Yield a s -> Yield a (InterleaveSecond s st2)
2364 Skip s -> Skip (InterleaveFirst s st2)
2365 Stop -> Stop
2367 step gst (InterleaveSecond st1 st2) = do
2368 r <- step2 gst st2
2369 return $ case r of
2370 Yield a s -> Yield a (InterleaveFirst st1 s)
2371 Skip s -> Skip (InterleaveSecond st1 s)
2372 Stop -> Stop
2374 step _ (InterleaveFirstOnly _) = undefined
2375 step _ (InterleaveSecondOnly _) = undefined
2377{-# INLINE_NORMAL interleaveSuffix #-}
2378interleaveSuffix :: Monad m => Stream m a -> Stream m a -> Stream m a
2379interleaveSuffix (Stream step1 state1) (Stream step2 state2) =
2380 Stream step (InterleaveFirst state1 state2)
2382 where
2384 {-# INLINE_LATE step #-}
2385 step gst (InterleaveFirst st1 st2) = do
2386 r <- step1 gst st1
2387 return $ case r of
2388 Yield a s -> Yield a (InterleaveSecond s st2)
2389 Skip s -> Skip (InterleaveFirst s st2)
2390 Stop -> Stop
2392 step gst (InterleaveSecond st1 st2) = do
2393 r <- step2 gst st2
2394 return $ case r of
2395 Yield a s -> Yield a (InterleaveFirst st1 s)
2396 Skip s -> Skip (InterleaveSecond st1 s)
2397 Stop -> Skip (InterleaveFirstOnly st1)
2399 step gst (InterleaveFirstOnly st1) = do
2400 r <- step1 gst st1
2401 return $ case r of
2402 Yield a s -> Yield a (InterleaveFirstOnly s)
2403 Skip s -> Skip (InterleaveFirstOnly s)
2404 Stop -> Stop
2406 step _ (InterleaveSecondOnly _) = undefined
2408data InterleaveInfixState s1 s2 a
2409 = InterleaveInfixFirst s1 s2
2410 | InterleaveInfixSecondBuf s1 s2
2411 | InterleaveInfixSecondYield s1 s2 a
2412 | InterleaveInfixFirstYield s1 s2 a
2413 | InterleaveInfixFirstOnly s1
2415{-# INLINE_NORMAL interleaveInfix #-}
2416interleaveInfix :: Monad m => Stream m a -> Stream m a -> Stream m a
2417interleaveInfix (Stream step1 state1) (Stream step2 state2) =
2418 Stream step (InterleaveInfixFirst state1 state2)
2420 where
2422 {-# INLINE_LATE step #-}
2423 step gst (InterleaveInfixFirst st1 st2) = do
2424 r <- step1 gst st1
2425 return $ case r of
2426 Yield a s -> Yield a (InterleaveInfixSecondBuf s st2)
2427 Skip s -> Skip (InterleaveInfixFirst s st2)
2428 Stop -> Stop
2430 step gst (InterleaveInfixSecondBuf st1 st2) = do
2431 r <- step2 gst st2
2432 return $ case r of
2433 Yield a s -> Skip (InterleaveInfixSecondYield st1 s a)
2434 Skip s -> Skip (InterleaveInfixSecondBuf st1 s)
2435 Stop -> Skip (InterleaveInfixFirstOnly st1)
2437 step gst (InterleaveInfixSecondYield st1 st2 x) = do
2438 r <- step1 gst st1
2439 return $ case r of
2440 Yield a s -> Yield x (InterleaveInfixFirstYield s st2 a)
2441 Skip s -> Skip (InterleaveInfixSecondYield s st2 x)
2442 Stop -> Stop
2444 step _ (InterleaveInfixFirstYield st1 st2 x) = do
2445 return $ Yield x (InterleaveInfixSecondBuf st1 st2)
2447 step gst (InterleaveInfixFirstOnly st1) = do
2448 r <- step1 gst st1
2449 return $ case r of
2450 Yield a s -> Yield a (InterleaveInfixFirstOnly s)
2451 Skip s -> Skip (InterleaveInfixFirstOnly s)
2452 Stop -> Stop
2454{-# INLINE_NORMAL roundRobin #-}
2455roundRobin :: Monad m => Stream m a -> Stream m a -> Stream m a
2456roundRobin (Stream step1 state1) (Stream step2 state2) =
2457 Stream step (InterleaveFirst state1 state2)
2459 where
2461 {-# INLINE_LATE step #-}
2462 step gst (InterleaveFirst st1 st2) = do
2463 r <- step1 gst st1
2464 return $ case r of
2465 Yield a s -> Yield a (InterleaveSecond s st2)
2466 Skip s -> Skip (InterleaveSecond s st2)
2467 Stop -> Skip (InterleaveSecondOnly st2)
2469 step gst (InterleaveSecond st1 st2) = do
2470 r <- step2 gst st2
2471 return $ case r of
2472 Yield a s -> Yield a (InterleaveFirst st1 s)
2473 Skip s -> Skip (InterleaveFirst st1 s)
2474 Stop -> Skip (InterleaveFirstOnly st1)
2476 step gst (InterleaveSecondOnly st2) = do
2477 r <- step2 gst st2
2478 return $ case r of
2479 Yield a s -> Yield a (InterleaveSecondOnly s)
2480 Skip s -> Skip (InterleaveSecondOnly s)
2481 Stop -> Stop
2483 step gst (InterleaveFirstOnly st1) = do
2484 r <- step1 gst st1
2485 return $ case r of
2486 Yield a s -> Yield a (InterleaveFirstOnly s)
2487 Skip s -> Skip (InterleaveFirstOnly s)
2488 Stop -> Stop
2490data ICUState s1 s2 i1 i2 =
2491 ICUFirst s1 s2
2492 | ICUSecond s1 s2
2493 | ICUSecondOnly s2
2494 | ICUFirstOnly s1
2495 | ICUFirstInner s1 s2 i1
2496 | ICUSecondInner s1 s2 i2
2497 | ICUFirstOnlyInner s1 i1
2498 | ICUSecondOnlyInner s2 i2
2500-- | Interleave streams (full streams, not the elements) unfolded from two
2501-- input streams and concat. Stop when the first stream stops. If the second
2502-- stream ends before the first one then first stream still keeps running alone
2503-- without any interleaving with the second stream.
2505-- [a1, a2, ... an] [b1, b2 ...]
2506-- => [streamA1, streamA2, ... streamAn] [streamB1, streamB2, ...]
2507-- => [streamA1, streamB1, streamA2...StreamAn, streamBn]
2508-- => [a11, a12, ...a1j, b11, b12, ...b1k, a21, a22, ...]
2510{-# INLINE_NORMAL gintercalateSuffix #-}
2511gintercalateSuffix
2512 :: Monad m
2513 => Unfold m a c -> Stream m a -> Unfold m b c -> Stream m b -> Stream m c
2514gintercalateSuffix
2515 (Unfold istep1 inject1) (Stream step1 state1)
2516 (Unfold istep2 inject2) (Stream step2 state2) =
2517 Stream step (ICUFirst state1 state2)
2519 where
2521 {-# INLINE_LATE step #-}
2522 step gst (ICUFirst s1 s2) = do
2523 r <- step1 (adaptState gst) s1
2524 case r of
2525 Yield a s -> do
2526 i <- inject1 a
2527 i `seq` return (Skip (ICUFirstInner s s2 i))
2528 Skip s -> return $ Skip (ICUFirst s s2)
2529 Stop -> return Stop
2531 step gst (ICUFirstOnly s1) = do
2532 r <- step1 (adaptState gst) s1
2533 case r of
2534 Yield a s -> do
2535 i <- inject1 a
2536 i `seq` return (Skip (ICUFirstOnlyInner s i))
2537 Skip s -> return $ Skip (ICUFirstOnly s)
2538 Stop -> return Stop
2540 step _ (ICUFirstInner s1 s2 i1) = do
2541 r <- istep1 i1
2542 return $ case r of
2543 Yield x i' -> Yield x (ICUFirstInner s1 s2 i')
2544 Skip i' -> Skip (ICUFirstInner s1 s2 i')
2545 Stop -> Skip (ICUSecond s1 s2)
2547 step _ (ICUFirstOnlyInner s1 i1) = do
2548 r <- istep1 i1
2549 return $ case r of
2550 Yield x i' -> Yield x (ICUFirstOnlyInner s1 i')
2551 Skip i' -> Skip (ICUFirstOnlyInner s1 i')
2552 Stop -> Skip (ICUFirstOnly s1)
2554 step gst (ICUSecond s1 s2) = do
2555 r <- step2 (adaptState gst) s2
2556 case r of
2557 Yield a s -> do
2558 i <- inject2 a
2559 i `seq` return (Skip (ICUSecondInner s1 s i))
2560 Skip s -> return $ Skip (ICUSecond s1 s)
2561 Stop -> return $ Skip (ICUFirstOnly s1)
2563 step _ (ICUSecondInner s1 s2 i2) = do
2564 r <- istep2 i2
2565 return $ case r of
2566 Yield x i' -> Yield x (ICUSecondInner s1 s2 i')
2567 Skip i' -> Skip (ICUSecondInner s1 s2 i')
2568 Stop -> Skip (ICUFirst s1 s2)
2570 step _ (ICUSecondOnly _s2) = undefined
2571 step _ (ICUSecondOnlyInner _s2 _i2) = undefined
2573data InterposeSuffixState s1 i1 =
2574 InterposeSuffixFirst s1
2575 -- | InterposeSuffixFirstYield s1 i1
2576 | InterposeSuffixFirstInner s1 i1
2577 | InterposeSuffixSecond s1
2579-- Note that if an unfolded layer turns out to be nil we still emit the
2580-- separator effect. An alternate behavior could be to emit the separator
2581-- effect only if at least one element has been yielded by the unfolding.
2582-- However, that becomes a bit complicated, so we have chosen the former
2583-- behvaior for now.
2584{-# INLINE_NORMAL interposeSuffix #-}
2585interposeSuffix
2586 :: Monad m
2587 => m c -> Unfold m b c -> Stream m b -> Stream m c
2588interposeSuffix
2589 action
2590 (Unfold istep1 inject1) (Stream step1 state1) =
2591 Stream step (InterposeSuffixFirst state1)
2593 where
2595 {-# INLINE_LATE step #-}
2596 step gst (InterposeSuffixFirst s1) = do
2597 r <- step1 (adaptState gst) s1
2598 case r of
2599 Yield a s -> do
2600 i <- inject1 a
2601 i `seq` return (Skip (InterposeSuffixFirstInner s i))
2602 -- i `seq` return (Skip (InterposeSuffixFirstYield s i))
2603 Skip s -> return $ Skip (InterposeSuffixFirst s)
2604 Stop -> return Stop
2606 {-
2607 step _ (InterposeSuffixFirstYield s1 i1) = do
2608 r <- istep1 i1
2609 return $ case r of
2610 Yield x i' -> Yield x (InterposeSuffixFirstInner s1 i')
2611 Skip i' -> Skip (InterposeSuffixFirstYield s1 i')
2612 Stop -> Skip (InterposeSuffixFirst s1)
2613 -}
2615 step _ (InterposeSuffixFirstInner s1 i1) = do
2616 r <- istep1 i1
2617 return $ case r of
2618 Yield x i' -> Yield x (InterposeSuffixFirstInner s1 i')
2619 Skip i' -> Skip (InterposeSuffixFirstInner s1 i')
2620 Stop -> Skip (InterposeSuffixSecond s1)
2622 step _ (InterposeSuffixSecond s1) = do
2623 r <- action
2624 return $ Yield r (InterposeSuffixFirst s1)
2626data ICALState s1 s2 i1 i2 a =
2627 ICALFirst s1 s2
2628 -- | ICALFirstYield s1 s2 i1
2629 | ICALFirstInner s1 s2 i1
2630 | ICALFirstOnly s1
2631 | ICALFirstOnlyInner s1 i1
2632 | ICALSecondInject s1 s2
2633 | ICALFirstInject s1 s2 i2
2634 -- | ICALFirstBuf s1 s2 i1 i2
2635 | ICALSecondInner s1 s2 i1 i2
2636 -- -- | ICALSecondInner s1 s2 i1 i2 a
2637 -- -- | ICALFirstResume s1 s2 i1 i2 a
2639-- | Interleave streams (full streams, not the elements) unfolded from two
2640-- input streams and concat. Stop when the first stream stops. If the second
2641-- stream ends before the first one then first stream still keeps running alone
2642-- without any interleaving with the second stream.
2644-- [a1, a2, ... an] [b1, b2 ...]
2645-- => [streamA1, streamA2, ... streamAn] [streamB1, streamB2, ...]
2646-- => [streamA1, streamB1, streamA2...StreamAn, streamBn]
2647-- => [a11, a12, ...a1j, b11, b12, ...b1k, a21, a22, ...]
2649{-# INLINE_NORMAL gintercalate #-}
2650gintercalate
2651 :: Monad m
2652 => Unfold m a c -> Stream m a -> Unfold m b c -> Stream m b -> Stream m c
2653gintercalate
2654 (Unfold istep1 inject1) (Stream step1 state1)
2655 (Unfold istep2 inject2) (Stream step2 state2) =
2656 Stream step (ICALFirst state1 state2)
2658 where
2660 {-# INLINE_LATE step #-}
2661 step gst (ICALFirst s1 s2) = do
2662 r <- step1 (adaptState gst) s1
2663 case r of
2664 Yield a s -> do
2665 i <- inject1 a
2666 i `seq` return (Skip (ICALFirstInner s s2 i))
2667 -- i `seq` return (Skip (ICALFirstYield s s2 i))
2668 Skip s -> return $ Skip (ICALFirst s s2)
2669 Stop -> return Stop
2671 {-
2672 step _ (ICALFirstYield s1 s2 i1) = do
2673 r <- istep1 i1
2674 return $ case r of
2675 Yield x i' -> Yield x (ICALFirstInner s1 s2 i')
2676 Skip i' -> Skip (ICALFirstYield s1 s2 i')
2677 Stop -> Skip (ICALFirst s1 s2)
2678 -}
2680 step _ (ICALFirstInner s1 s2 i1) = do
2681 r <- istep1 i1
2682 return $ case r of
2683 Yield x i' -> Yield x (ICALFirstInner s1 s2 i')
2684 Skip i' -> Skip (ICALFirstInner s1 s2 i')
2685 Stop -> Skip (ICALSecondInject s1 s2)
2687 step gst (ICALFirstOnly s1) = do
2688 r <- step1 (adaptState gst) s1
2689 case r of
2690 Yield a s -> do
2691 i <- inject1 a
2692 i `seq` return (Skip (ICALFirstOnlyInner s i))
2693 Skip s -> return $ Skip (ICALFirstOnly s)
2694 Stop -> return Stop
2696 step _ (ICALFirstOnlyInner s1 i1) = do
2697 r <- istep1 i1
2698 return $ case r of
2699 Yield x i' -> Yield x (ICALFirstOnlyInner s1 i')
2700 Skip i' -> Skip (ICALFirstOnlyInner s1 i')
2701 Stop -> Skip (ICALFirstOnly s1)
2703 -- We inject the second stream even before checking if the first stream
2704 -- would yield any more elements. There is no clear choice whether we
2705 -- should do this before or after that. Doing it after may make the state
2706 -- machine a bit simpler though.
2707 step gst (ICALSecondInject s1 s2) = do
2708 r <- step2 (adaptState gst) s2
2709 case r of
2710 Yield a s -> do
2711 i <- inject2 a
2712 i `seq` return (Skip (ICALFirstInject s1 s i))
2713 Skip s -> return $ Skip (ICALSecondInject s1 s)
2714 Stop -> return $ Skip (ICALFirstOnly s1)
2716 step gst (ICALFirstInject s1 s2 i2) = do
2717 r <- step1 (adaptState gst) s1
2718 case r of
2719 Yield a s -> do
2720 i <- inject1 a
2721 i `seq` return (Skip (ICALSecondInner s s2 i i2))
2722 -- i `seq` return (Skip (ICALFirstBuf s s2 i i2))
2723 Skip s -> return $ Skip (ICALFirstInject s s2 i2)
2724 Stop -> return Stop
2726 {-
2727 step _ (ICALFirstBuf s1 s2 i1 i2) = do
2728 r <- istep1 i1
2729 return $ case r of
2730 Yield x i' -> Skip (ICALSecondInner s1 s2 i' i2 x)
2731 Skip i' -> Skip (ICALFirstBuf s1 s2 i' i2)
2732 Stop -> Stop
2734 step _ (ICALSecondInner s1 s2 i1 i2 v) = do
2735 r <- istep2 i2
2736 return $ case r of
2737 Yield x i' -> Yield x (ICALSecondInner s1 s2 i1 i' v)
2738 Skip i' -> Skip (ICALSecondInner s1 s2 i1 i' v)
2739 Stop -> Skip (ICALFirstResume s1 s2 i1 i2 v)
2740 -}
2742 step _ (ICALSecondInner s1 s2 i1 i2) = do
2743 r <- istep2 i2
2744 return $ case r of
2745 Yield x i' -> Yield x (ICALSecondInner s1 s2 i1 i')
2746 Skip i' -> Skip (ICALSecondInner s1 s2 i1 i')
2747 Stop -> Skip (ICALFirstInner s1 s2 i1)
2748 -- Stop -> Skip (ICALFirstResume s1 s2 i1 i2)
2750 {-
2751 step _ (ICALFirstResume s1 s2 i1 i2 x) = do
2752 return $ Yield x (ICALFirstInner s1 s2 i1 i2)
2753 -}
2755data InterposeState s1 i1 a =
2756 InterposeFirst s1
2757 -- | InterposeFirstYield s1 i1
2758 | InterposeFirstInner s1 i1
2759 | InterposeFirstInject s1
2760 -- | InterposeFirstBuf s1 i1
2761 | InterposeSecondYield s1 i1
2762 -- -- | InterposeSecondYield s1 i1 a
2763 -- -- | InterposeFirstResume s1 i1 a
2765-- Note that this only interposes the pure values, we may run many effects to
2766-- generate those values as some effects may not generate anything (Skip).
2767{-# INLINE_NORMAL interpose #-}
2768interpose :: Monad m => m c -> Unfold m b c -> Stream m b -> Stream m c
2769interpose
2770 action
2771 (Unfold istep1 inject1) (Stream step1 state1) =
2772 Stream step (InterposeFirst state1)
2774 where
2776 {-# INLINE_LATE step #-}
2777 step gst (InterposeFirst s1) = do
2778 r <- step1 (adaptState gst) s1
2779 case r of
2780 Yield a s -> do
2781 i <- inject1 a
2782 i `seq` return (Skip (InterposeFirstInner s i))
2783 -- i `seq` return (Skip (InterposeFirstYield s i))
2784 Skip s -> return $ Skip (InterposeFirst s)
2785 Stop -> return Stop
2787 {-
2788 step _ (InterposeFirstYield s1 i1) = do
2789 r <- istep1 i1
2790 return $ case r of
2791 Yield x i' -> Yield x (InterposeFirstInner s1 i')
2792 Skip i' -> Skip (InterposeFirstYield s1 i')
2793 Stop -> Skip (InterposeFirst s1)
2794 -}
2796 step _ (InterposeFirstInner s1 i1) = do
2797 r <- istep1 i1
2798 return $ case r of
2799 Yield x i' -> Yield x (InterposeFirstInner s1 i')
2800 Skip i' -> Skip (InterposeFirstInner s1 i')
2801 Stop -> Skip (InterposeFirstInject s1)
2803 step gst (InterposeFirstInject s1) = do
2804 r <- step1 (adaptState gst) s1
2805 case r of
2806 Yield a s -> do
2807 i <- inject1 a
2808 -- i `seq` return (Skip (InterposeFirstBuf s i))
2809 i `seq` return (Skip (InterposeSecondYield s i))
2810 Skip s -> return $ Skip (InterposeFirstInject s)
2811 Stop -> return Stop
2813 {-
2814 step _ (InterposeFirstBuf s1 i1) = do
2815 r <- istep1 i1
2816 return $ case r of
2817 Yield x i' -> Skip (InterposeSecondYield s1 i' x)
2818 Skip i' -> Skip (InterposeFirstBuf s1 i')
2819 Stop -> Stop
2820 -}
2822 {-
2823 step _ (InterposeSecondYield s1 i1 v) = do
2824 r <- action
2825 return $ Yield r (InterposeFirstResume s1 i1 v)
2826 -}
2827 step _ (InterposeSecondYield s1 i1) = do
2828 r <- action
2829 return $ Yield r (InterposeFirstInner s1 i1)
2831 {-
2832 step _ (InterposeFirstResume s1 i1 v) = do
2833 return $ Yield v (InterposeFirstInner s1 i1)
2834 -}
2836------------------------------------------------------------------------------
2837-- Exceptions
2838------------------------------------------------------------------------------
2840data GbracketState s1 s2 v
2841 = GBracketInit
2842 | GBracketNormal s1 v
2843 | GBracketException s2
2845-- | The most general bracketing and exception combinator. All other
2846-- combinators can be expressed in terms of this combinator. This can also be
2847-- used for cases which are not covered by the standard combinators.
2849-- /Internal/
2851{-# INLINE_NORMAL gbracket #-}
2852gbracket
2853 :: Monad m
2854 => m c -- ^ before
2855 -> (forall s. m s -> m (Either e s)) -- ^ try (exception handling)
2856 -> (c -> m d) -- ^ after, on normal stop
2857 -> (c -> e -> Stream m b) -- ^ on exception
2858 -> (c -> Stream m b) -- ^ stream generator
2859 -> Stream m b
2860gbracket bef exc aft fexc fnormal =
2861 Stream step GBracketInit
2863 where
2865 {-# INLINE_LATE step #-}
2866 step _ GBracketInit = do
2867 r <- bef
2868 return $ Skip $ GBracketNormal (fnormal r) r
2870 step gst (GBracketNormal (UnStream step1 st) v) = do
2871 res <- exc $ step1 gst st
2872 case res of
2873 Right r -> case r of
2874 Yield x s ->
2875 return $ Yield x (GBracketNormal (Stream step1 s) v)
2876 Skip s -> return $ Skip (GBracketNormal (Stream step1 s) v)
2877 Stop -> aft v >> return Stop
2878 Left e -> return $ Skip (GBracketException (fexc v e))
2879 step gst (GBracketException (UnStream step1 st)) = do
2880 res <- step1 gst st
2881 case res of
2882 Yield x s -> return $ Yield x (GBracketException (Stream step1 s))
2883 Skip s -> return $ Skip (GBracketException (Stream step1 s))
2884 Stop -> return Stop
2886-- | Create an IORef holding a finalizer that is called automatically when the
2887-- IORef is garbage collected. The IORef can be written to with a 'Nothing'
2888-- value to deactivate the finalizer.
2889newFinalizedIORef :: (MonadIO m, MonadBaseControl IO m)
2890 => m a -> m (IORef (Maybe (IO ())))
2891newFinalizedIORef finalizer = do
2892 mrun <- captureMonadState
2893 ref <- liftIO $ newIORef $ Just $ liftIO $ void $ do
2894 _ <- runInIO mrun finalizer
2895 return ()
2896 let finalizer1 = do
2897 res <- readIORef ref
2898 case res of
2899 Nothing -> return ()
2900 Just f -> f
2901 _ <- liftIO $ mkWeakIORef ref finalizer1
2902 return ref
2904-- | Run the finalizer stored in an IORef and deactivate it so that it is run
2905-- only once.
2907runIORefFinalizer :: MonadIO m => IORef (Maybe (IO ())) -> m ()
2908runIORefFinalizer ref = liftIO $ do
2909 res <- readIORef ref
2910 case res of
2911 Nothing -> return ()
2912 Just f -> writeIORef ref Nothing >> f
2914-- | Deactivate the finalizer stored in an IORef without running it.
2916clearIORefFinalizer :: MonadIO m => IORef (Maybe (IO ())) -> m ()
2917clearIORefFinalizer ref = liftIO $ writeIORef ref Nothing
2919data GbracketIOState s1 s2 v wref
2920 = GBracketIOInit
2921 | GBracketIONormal s1 v wref
2922 | GBracketIOException s2
2924-- | Like gbracket but also uses a finalizer to make sure when the stream is
2925-- garbage collected we run the finalizing action. This requires a MonadIO and
2926-- MonadBaseControl IO constraint.
2928-- | The most general bracketing and exception combinator. All other
2929-- combinators can be expressed in terms of this combinator. This can also be
2930-- used for cases which are not covered by the standard combinators.
2932-- /Internal/
2934{-# INLINE_NORMAL gbracketIO #-}
2935gbracketIO
2936 :: (MonadIO m, MonadBaseControl IO m)
2937 => m c -- ^ before
2938 -> (forall s. m s -> m (Either e s)) -- ^ try (exception handling)
2939 -> (c -> m d) -- ^ after, on normal stop or GC
2940 -> (c -> e -> Stream m b) -- ^ on exception
2941 -> (c -> Stream m b) -- ^ stream generator
2942 -> Stream m b
2943gbracketIO bef exc aft fexc fnormal =
2944 Stream step GBracketIOInit
2946 where
2948 -- If the stream is never evaluated the "aft" action will never be
2949 -- called. For that to occur we will need the user of this API to pass a
2950 -- weak pointer to us.
2951 {-# INLINE_LATE step #-}
2952 step _ GBracketIOInit = do
2953 r <- bef
2954 ref <- newFinalizedIORef (aft r)
2955 return $ Skip $ GBracketIONormal (fnormal r) r ref
2957 step gst (GBracketIONormal (UnStream step1 st) v ref) = do
2958 res <- exc $ step1 gst st
2959 case res of
2960 Right r -> case r of
2961 Yield x s ->
2962 return $ Yield x (GBracketIONormal (Stream step1 s) v ref)
2963 Skip s ->
2964 return $ Skip (GBracketIONormal (Stream step1 s) v ref)
2965 Stop -> do
2966 runIORefFinalizer ref
2967 return Stop
2968 Left e -> do
2969 clearIORefFinalizer ref
2970 return $ Skip (GBracketIOException (fexc v e))
2971 step gst (GBracketIOException (UnStream step1 st)) = do
2972 res <- step1 gst st
2973 case res of
2974 Yield x s ->
2975 return $ Yield x (GBracketIOException (Stream step1 s))
2976 Skip s -> return $ Skip (GBracketIOException (Stream step1 s))
2977 Stop -> return Stop
2979-- | Run a side effect before the stream yields its first element.
2980{-# INLINE_NORMAL before #-}
2981before :: Monad m => m b -> Stream m a -> Stream m a
2982before action (Stream step state) = Stream step' Nothing
2984 where
2986 {-# INLINE_LATE step' #-}
2987 step' _ Nothing = action >> return (Skip (Just state))
2989 step' gst (Just st) = do
2990 res <- step gst st
2991 case res of
2992 Yield x s -> return $ Yield x (Just s)
2993 Skip s -> return $ Skip (Just s)
2994 Stop -> return Stop
2996-- | Run a side effect whenever the stream stops normally.
2997{-# INLINE_NORMAL after #-}
2998after :: Monad m => m b -> Stream m a -> Stream m a
2999after action (Stream step state) = Stream step' state
3001 where
3003 {-# INLINE_LATE step' #-}
3004 step' gst st = do
3005 res <- step gst st
3006 case res of
3007 Yield x s -> return $ Yield x s
3008 Skip s -> return $ Skip s
3009 Stop -> action >> return Stop
3011{-# INLINE_NORMAL afterIO #-}
3012afterIO :: (MonadIO m, MonadBaseControl IO m)
3013 => m b -> Stream m a -> Stream m a
3014afterIO action (Stream step state) = Stream step' Nothing
3016 where
3018 {-# INLINE_LATE step' #-}
3019 step' _ Nothing = do
3020 ref <- newFinalizedIORef action
3021 return $ Skip $ Just (state, ref)
3022 step' gst (Just (st, ref)) = do
3023 res <- step gst st
3024 case res of
3025 Yield x s -> return $ Yield x (Just (s, ref))
3026 Skip s -> return $ Skip (Just (s, ref))
3027 Stop -> do
3028 runIORefFinalizer ref
3029 return Stop
3031-- XXX These combinators are expensive due to the call to
3032-- onException/handle/try on each step. Therefore, when possible, they should
3033-- be called in an outer loop where we perform less iterations. For example, we
3034-- cannot call them on each iteration in a char stream, instead we can call
3035-- them when doing an IO on an array.
3037-- XXX For high performance error checks in busy streams we may need another
3038-- Error constructor in step.
3040-- | Run a side effect whenever the stream aborts due to an exception. The
3041-- exception is not caught, simply rethrown.
3042{-# INLINE_NORMAL onException #-}
3043onException :: MonadCatch m => m b -> Stream m a -> Stream m a
3044onException action str =
3045 gbracket (return ()) MC.try return
3046 (\_ (e :: MC.SomeException) -> nilM (action >> MC.throwM e))
3047 (\_ -> str)
3049{-# INLINE_NORMAL _onException #-}
3050_onException :: MonadCatch m => m b -> Stream m a -> Stream m a
3051_onException action (Stream step state) = Stream step' state
3053 where
3055 {-# INLINE_LATE step' #-}
3056 step' gst st = do
3057 res <- step gst st `MC.onException` action
3058 case res of
3059 Yield x s -> return $ Yield x s
3060 Skip s -> return $ Skip s
3061 Stop -> return Stop
3063-- XXX bracket is like concatMap, it generates a stream and then flattens it.
3064-- Like concatMap it has 10x worse performance compared to linear fused
3065-- compositions.
3067-- | Run the first action before the stream starts and remember its output,
3068-- generate a stream using the output, run the second action providing the
3069-- remembered value as an argument whenever the stream ends normally or due to
3070-- an exception.
3071{-# INLINE_NORMAL bracket #-}
3072bracket :: MonadCatch m => m b -> (b -> m c) -> (b -> Stream m a) -> Stream m a
3073bracket bef aft bet =
3074 gbracket bef MC.try aft
3075 (\a (e :: SomeException) -> nilM (aft a >> MC.throwM e)) bet
3077{-# INLINE_NORMAL bracketIO #-}
3078bracketIO :: (MonadAsync m, MonadCatch m)
3079 => m b -> (b -> m c) -> (b -> Stream m a) -> Stream m a
3080bracketIO bef aft bet =
3081 gbracketIO bef MC.try aft
3082 (\a (e :: SomeException) -> nilM (aft a >> MC.throwM e)) bet
3084data BracketState s v = BracketInit | BracketRun s v
3086{-# INLINE_NORMAL _bracket #-}
3087_bracket :: MonadCatch m => m b -> (b -> m c) -> (b -> Stream m a) -> Stream m a
3088_bracket bef aft bet = Stream step' BracketInit
3090 where
3092 {-# INLINE_LATE step' #-}
3093 step' _ BracketInit = bef >>= \x -> return (Skip (BracketRun (bet x) x))
3095 -- NOTE: It is important to use UnStream instead of the Stream pattern
3096 -- here, otherwise we get huge perf degradation, see note in concatMap.
3097 step' gst (BracketRun (UnStream step state) v) = do
3098 -- res <- step gst state `MC.onException` aft v
3099 res <- MC.try $ step gst state
3100 case res of
3101 Left (e :: SomeException) -> aft v >> MC.throwM e >> return Stop
3102 Right r -> case r of
3103 Yield x s -> return $ Yield x (BracketRun (Stream step s) v)
3104 Skip s -> return $ Skip (BracketRun (Stream step s) v)
3105 Stop -> aft v >> return Stop
3107-- | Run a side effect whenever the stream stops normally or aborts due to an
3108-- exception.
3109{-# INLINE finally #-}
3110finally :: MonadCatch m => m b -> Stream m a -> Stream m a
3111-- finally action xs = after action $ onException action xs
3112finally action xs = bracket (return ()) (\_ -> action) (const xs)
3114{-# INLINE finallyIO #-}
3115finallyIO :: (MonadAsync m, MonadCatch m) => m b -> Stream m a -> Stream m a
3116finallyIO action xs = bracketIO (return ()) (\_ -> action) (const xs)
3118-- | When evaluating a stream if an exception occurs, stream evaluation aborts
3119-- and the specified exception handler is run with the exception as argument.
3120{-# INLINE_NORMAL handle #-}
3121handle :: (MonadCatch m, Exception e)
3122 => (e -> Stream m a) -> Stream m a -> Stream m a
3123handle f str =
3124 gbracket (return ()) MC.try return (\_ e -> f e) (\_ -> str)
3126{-# INLINE_NORMAL _handle #-}
3127_handle :: (MonadCatch m, Exception e)
3128 => (e -> Stream m a) -> Stream m a -> Stream m a
3129_handle f (Stream step state) = Stream step' (Left state)
3131 where
3133 {-# INLINE_LATE step' #-}
3134 step' gst (Left st) = do
3135 res <- MC.try $ step gst st
3136 case res of
3137 Left e -> return $ Skip $ Right (f e)
3138 Right r -> case r of
3139 Yield x s -> return $ Yield x (Left s)
3140 Skip s -> return $ Skip (Left s)
3141 Stop -> return Stop
3143 step' gst (Right (UnStream step1 st)) = do
3144 res <- step1 gst st
3145 case res of
3146 Yield x s -> return $ Yield x (Right (Stream step1 s))
3147 Skip s -> return $ Skip (Right (Stream step1 s))
3148 Stop -> return Stop
3150-------------------------------------------------------------------------------
3151-- General transformation
3152-------------------------------------------------------------------------------
3154{-# INLINE_NORMAL transform #-}
3155transform :: Monad m => Pipe m a b -> Stream m a -> Stream m b
3156transform (Pipe pstep1 pstep2 pstate) (Stream step state) =
3157 Stream step' (Consume pstate, state)
3159 where
3161 {-# INLINE_LATE step' #-}
3163 step' gst (Consume pst, st) = pst `seq` do
3164 r <- step (adaptState gst) st
3165 case r of
3166 Yield x s -> do
3167 res <- pstep1 pst x
3168 case res of
3169 Pipe.Yield b pst' -> return $ Yield b (pst', s)
3170 Pipe.Continue pst' -> return $ Skip (pst', s)
3171 Skip s -> return $ Skip (Consume pst, s)
3172 Stop -> return Stop
3174 step' _ (Produce pst, st) = pst `seq` do
3175 res <- pstep2 pst
3176 case res of
3177 Pipe.Yield b pst' -> return $ Yield b (pst', st)
3178 Pipe.Continue pst' -> return $ Skip (pst', st)
3180------------------------------------------------------------------------------
3181-- Transformation by Folding (Scans)
3182------------------------------------------------------------------------------
3184------------------------------------------------------------------------------
3185-- Prescans
3186------------------------------------------------------------------------------
3188-- XXX Is a prescan useful, discarding the last step does not sound useful? I
3189-- am not sure about the utility of this function, so this is implemented but
3190-- not exposed. We can expose it if someone provides good reasons why this is
3191-- useful.
3193-- XXX We have to execute the stream one step ahead to know that we are at the
3194-- last step. The vector implementation of prescan executes the last fold step
3195-- but does not yield the result. This means we have executed the effect but
3196-- discarded value. This does not sound right. In this implementation we are
3197-- not executing the last fold step.
3198{-# INLINE_NORMAL prescanlM' #-}
3199prescanlM' :: Monad m => (b -> a -> m b) -> m b -> Stream m a -> Stream m b
3200prescanlM' f mz (Stream step state) = Stream step' (state, mz)
3201 where
3202 {-# INLINE_LATE step' #-}
3203 step' gst (st, prev) = do
3204 r <- step (adaptState gst) st
3205 case r of
3206 Yield x s -> do
3207 acc <- prev
3208 return $ Yield acc (s, f acc x)
3209 Skip s -> return $ Skip (s, prev)
3210 Stop -> return Stop
3212{-# INLINE prescanl' #-}
3213prescanl' :: Monad m => (b -> a -> b) -> b -> Stream m a -> Stream m b
3214prescanl' f z = prescanlM' (\a b -> return (f a b)) (return z)
3216------------------------------------------------------------------------------
3217-- Monolithic postscans (postscan followed by a map)
3218------------------------------------------------------------------------------
3220-- The performance of a modular postscan followed by a map seems to be
3221-- equivalent to this monolithic scan followed by map therefore we may not need
3222-- this implementation. We just have it for performance comparison and in case
3223-- modular version does not perform well in some situation.
3225{-# INLINE_NORMAL postscanlMx' #-}
3226postscanlMx' :: Monad m
3227 => (x -> a -> m x) -> m x -> (x -> m b) -> Stream m a -> Stream m b
3228postscanlMx' fstep begin done (Stream step state) = do
3229 Stream step' (state, begin)
3230 where
3231 {-# INLINE_LATE step' #-}
3232 step' gst (st, acc) = do
3233 r <- step (adaptState gst) st
3234 case r of
3235 Yield x s -> do
3236 old <- acc
3237 y <- fstep old x
3238 v <- done y
3239 v `seq` y `seq` return (Yield v (s, return y))
3240 Skip s -> return $ Skip (s, acc)
3241 Stop -> return Stop
3243{-# INLINE_NORMAL postscanlx' #-}
3244postscanlx' :: Monad m
3245 => (x -> a -> x) -> x -> (x -> b) -> Stream m a -> Stream m b
3246postscanlx' fstep begin done s =
3247 postscanlMx' (\b a -> return (fstep b a)) (return begin) (return . done) s
3249-- XXX do we need consM strict to evaluate the begin value?
3250{-# INLINE scanlMx' #-}
3251scanlMx' :: Monad m
3252 => (x -> a -> m x) -> m x -> (x -> m b) -> Stream m a -> Stream m b
3253scanlMx' fstep begin done s =
3254 (begin >>= \x -> x `seq` done x) `consM` postscanlMx' fstep begin done s
3256{-# INLINE scanlx' #-}
3257scanlx' :: Monad m
3258 => (x -> a -> x) -> x -> (x -> b) -> Stream m a -> Stream m b
3259scanlx' fstep begin done s =
3260 scanlMx' (\b a -> return (fstep b a)) (return begin) (return . done) s
3262------------------------------------------------------------------------------
3263-- postscans
3264------------------------------------------------------------------------------
3266{-# INLINE_NORMAL postscanlM' #-}
3267postscanlM' :: Monad m => (b -> a -> m b) -> b -> Stream m a -> Stream m b
3268postscanlM' fstep begin (Stream step state) =
3269 begin `seq` Stream step' (state, begin)
3270 where
3271 {-# INLINE_LATE step' #-}
3272 step' gst (st, acc) = acc `seq` do
3273 r <- step (adaptState gst) st
3274 case r of
3275 Yield x s -> do
3276 y <- fstep acc x
3277 y `seq` return (Yield y (s, y))
3278 Skip s -> return $ Skip (s, acc)
3279 Stop -> return Stop
3281{-# INLINE_NORMAL postscanl' #-}
3282postscanl' :: Monad m => (a -> b -> a) -> a -> Stream m b -> Stream m a
3283postscanl' f = postscanlM' (\a b -> return (f a b))
3285{-# INLINE_NORMAL postscanlM #-}
3286postscanlM :: Monad m => (b -> a -> m b) -> b -> Stream m a -> Stream m b
3287postscanlM fstep begin (Stream step state) = Stream step' (state, begin)
3288 where
3289 {-# INLINE_LATE step' #-}
3290 step' gst (st, acc) = do
3291 r <- step (adaptState gst) st
3292 case r of
3293 Yield x s -> do
3294 y <- fstep acc x
3295 return (Yield y (s, y))
3296 Skip s -> return $ Skip (s, acc)
3297 Stop -> return Stop
3299{-# INLINE_NORMAL postscanl #-}
3300postscanl :: Monad m => (a -> b -> a) -> a -> Stream m b -> Stream m a
3301postscanl f = postscanlM (\a b -> return (f a b))
3303{-# INLINE_NORMAL scanlM' #-}
3304scanlM' :: Monad m => (b -> a -> m b) -> b -> Stream m a -> Stream m b
3305scanlM' fstep begin s = begin `seq` (begin `cons` postscanlM' fstep begin s)
3307{-# INLINE scanl' #-}
3308scanl' :: Monad m => (b -> a -> b) -> b -> Stream m a -> Stream m b
3309scanl' f = scanlM' (\a b -> return (f a b))
3311{-# INLINE_NORMAL scanlM #-}
3312scanlM :: Monad m => (b -> a -> m b) -> b -> Stream m a -> Stream m b
3313scanlM fstep begin s = begin `cons` postscanlM fstep begin s
3315{-# INLINE scanl #-}
3316scanl :: Monad m => (b -> a -> b) -> b -> Stream m a -> Stream m b
3317scanl f = scanlM (\a b -> return (f a b))
3319{-# INLINE_NORMAL scanl1M #-}
3320scanl1M :: Monad m => (a -> a -> m a) -> Stream m a -> Stream m a
3321scanl1M fstep (Stream step state) = Stream step' (state, Nothing)
3322 where
3323 {-# INLINE_LATE step' #-}
3324 step' gst (st, Nothing) = do
3325 r <- step gst st
3326 case r of
3327 Yield x s -> return $ Yield x (s, Just x)
3328 Skip s -> return $ Skip (s, Nothing)
3329 Stop -> return Stop
3331 step' gst (st, Just acc) = do
3332 r <- step gst st
3333 case r of
3334 Yield y s -> do
3335 z <- fstep acc y
3336 return $ Yield z (s, Just z)
3337 Skip s -> return $ Skip (s, Just acc)
3338 Stop -> return Stop
3340{-# INLINE scanl1 #-}
3341scanl1 :: Monad m => (a -> a -> a) -> Stream m a -> Stream m a
3342scanl1 f = scanl1M (\x y -> return (f x y))
3344{-# INLINE_NORMAL scanl1M' #-}
3345scanl1M' :: Monad m => (a -> a -> m a) -> Stream m a -> Stream m a
3346scanl1M' fstep (Stream step state) = Stream step' (state, Nothing)
3347 where
3348 {-# INLINE_LATE step' #-}
3349 step' gst (st, Nothing) = do
3350 r <- step gst st
3351 case r of
3352 Yield x s -> x `seq` return $ Yield x (s, Just x)
3353 Skip s -> return $ Skip (s, Nothing)
3354 Stop -> return Stop
3356 step' gst (st, Just acc) = acc `seq` do
3357 r <- step gst st
3358 case r of
3359 Yield y s -> do
3360 z <- fstep acc y
3361 z `seq` return $ Yield z (s, Just z)
3362 Skip s -> return $ Skip (s, Just acc)
3363 Stop -> return Stop
3365{-# INLINE scanl1' #-}
3366scanl1' :: Monad m => (a -> a -> a) -> Stream m a -> Stream m a
3367scanl1' f = scanl1M' (\x y -> return (f x y))
3369------------------------------------------------------------------------------
3370-- Stateful map/scan
3371------------------------------------------------------------------------------
3373data RollingMapState s a = RollingMapInit s | RollingMapGo s a
3375{-# INLINE rollingMapM #-}
3376rollingMapM :: Monad m => (a -> a -> m b) -> Stream m a -> Stream m b
3377rollingMapM f (Stream step1 state1) = Stream step (RollingMapInit state1)
3378 where
3379 step gst (RollingMapInit st) = do
3380 r <- step1 (adaptState gst) st
3381 return $ case r of
3382 Yield x s -> Skip $ RollingMapGo s x
3383 Skip s -> Skip $ RollingMapInit s
3384 Stop -> Stop
3386 step gst (RollingMapGo s1 x1) = do
3387 r <- step1 (adaptState gst) s1
3388 case r of
3389 Yield x s -> do
3390 !res <- f x x1
3391 return $ Yield res $ RollingMapGo s x
3392 Skip s -> return $ Skip $ RollingMapGo s x1
3393 Stop -> return $ Stop
3395{-# INLINE rollingMap #-}
3396rollingMap :: Monad m => (a -> a -> b) -> Stream m a -> Stream m b
3397rollingMap f = rollingMapM (\x y -> return $ f x y)
3399------------------------------------------------------------------------------
3400-- Tapping/Distributing
3401------------------------------------------------------------------------------
3403{-# INLINE tap #-}
3404tap :: Monad m => Fold m a b -> Stream m a -> Stream m a
3405tap (Fold fstep initial extract) (Stream step state) = Stream step' Nothing
3407 where
3409 step' _ Nothing = do
3410 r <- initial
3411 return $ Skip (Just (r, state))
3413 step' gst (Just (acc, st)) = acc `seq` do
3414 r <- step gst st
3415 case r of
3416 Yield x s -> do
3417 acc' <- fstep acc x
3418 return $ Yield x (Just (acc', s))
3419 Skip s -> return $ Skip (Just (acc, s))
3420 Stop -> do
3421 void $ extract acc
3422 return $ Stop
3424{-# INLINE_NORMAL tapOffsetEvery #-}
3425tapOffsetEvery :: Monad m
3426 => Int -> Int -> Fold m a b -> Stream m a -> Stream m a
3427tapOffsetEvery offset n (Fold fstep initial extract) (Stream step state) =
3428 Stream step' Nothing
3430 where
3432 {-# INLINE_LATE step' #-}
3433 step' _ Nothing = do
3434 r <- initial
3435 return $ Skip (Just (r, state, offset `mod` n))
3437 step' gst (Just (acc, st, count)) | count <= 0 = do
3438 r <- step gst st
3439 case r of
3440 Yield x s -> do
3441 !acc' <- fstep acc x
3442 return $ Yield x (Just (acc', s, n - 1))
3443 Skip s -> return $ Skip (Just (acc, s, count))
3444 Stop -> do
3445 void $ extract acc
3446 return $ Stop
3448 step' gst (Just (acc, st, count)) = do
3449 r <- step gst st
3450 case r of
3451 Yield x s -> return $ Yield x (Just (acc, s, count - 1))
3452 Skip s -> return $ Skip (Just (acc, s, count))
3453 Stop -> do
3454 void $ extract acc
3455 return $ Stop
3457{-# INLINE_NORMAL pollCounts #-}
3458pollCounts
3459 :: MonadAsync m
3460 => (Stream m Int -> Stream m Int)
3461 -> Fold m Int b
3462 -> Stream m a
3463 -> Stream m a
3464pollCounts transf fld (Stream step state) = Stream step' Nothing
3465 where
3467 {-# INLINE_LATE step' #-}
3468 step' _ Nothing = do
3469 -- As long as we are using an "Int" for counts lockfree reads from
3470 -- Var should work correctly on both 32-bit and 64-bit machines.
3471 -- However, an Int on a 32-bit machine may overflow quickly.
3472 countVar <- liftIO $ newVar (0 :: Int)
3473 tid <- forkManaged
3474 $ void $ runFold fld
3475 $ transf $ fromPrimVar countVar
3476 return $ Skip (Just (countVar, tid, state))
3478 step' gst (Just (countVar, tid, st)) = do
3479 r <- step gst st
3480 case r of
3481 Yield x s -> do
3482 liftIO $ modifyVar' countVar (+ 1)
3483 return $ Yield x (Just (countVar, tid, s))
3484 Skip s -> return $ Skip (Just (countVar, tid, s))
3485 Stop -> do
3486 liftIO $ killThread tid
3487 return Stop
3489{-# INLINE_NORMAL tapRate #-}
3490tapRate ::
3491 (MonadAsync m, MonadCatch m)
3492 => Double
3493 -> (Int -> m b)
3494 -> Stream m a
3495 -> Stream m a
3496tapRate samplingRate action (Stream step state) = Stream step' Nothing
3497 where
3498 {-# NOINLINE loop #-}
3499 loop countVar prev = do
3500 i <-
3501 MC.catch
3502 (do liftIO $ threadDelay (round $ samplingRate * 1000000)
3503 i <- liftIO $ readVar countVar
3504 let !diff = i - prev
3505 void $ action diff
3506 return i)
3507 (\(e :: AsyncException) -> do
3508 i <- liftIO $ readVar countVar
3509 let !diff = i - prev
3510 void $ action diff
3511 throwM (MC.toException e))
3512 loop countVar i
3514 {-# INLINE_LATE step' #-}
3515 step' _ Nothing = do
3516 countVar <- liftIO $ newVar 0
3517 tid <- fork $ loop countVar 0
3518 ref <- liftIO $ newIORef ()
3519 _ <- liftIO $ mkWeakIORef ref (killThread tid)
3520 return $ Skip (Just (countVar, tid, state, ref))
3522 step' gst (Just (countVar, tid, st, ref)) = do
3523 r <- step gst st
3524 case r of
3525 Yield x s -> do
3526 liftIO $ modifyVar' countVar (+ 1)
3527 return $ Yield x (Just (countVar, tid, s, ref))
3528 Skip s -> return $ Skip (Just (countVar, tid, s, ref))
3529 Stop -> do
3530 liftIO $ killThread tid
3531 return Stop
3534-------------------------------------------------------------------------------
3535-- Filtering
3536-------------------------------------------------------------------------------
3538{-# INLINE_NORMAL takeWhileM #-}
3539takeWhileM :: Monad m => (a -> m Bool) -> Stream m a -> Stream m a
3540takeWhileM f (Stream step state) = Stream step' state
3541 where
3542 {-# INLINE_LATE step' #-}
3543 step' gst st = do
3544 r <- step gst st
3545 case r of
3546 Yield x s -> do
3547 b <- f x
3548 return $ if b then Yield x s else Stop
3549 Skip s -> return $ Skip s
3550 Stop -> return Stop
3552{-# INLINE takeWhile #-}
3553takeWhile :: Monad m => (a -> Bool) -> Stream m a -> Stream m a
3554takeWhile f = takeWhileM (return . f)
3556{-# INLINE_NORMAL drop #-}
3557drop :: Monad m => Int -> Stream m a -> Stream m a
3558drop n (Stream step state) = Stream step' (state, Just n)
3559 where
3560 {-# INLINE_LATE step' #-}
3561 step' gst (st, Just i)
3562 | i > 0 = do
3563 r <- step gst st
3564 return $
3565 case r of
3566 Yield _ s -> Skip (s, Just (i - 1))
3567 Skip s -> Skip (s, Just i)
3568 Stop -> Stop
3569 | otherwise = return $ Skip (st, Nothing)
3571 step' gst (st, Nothing) = do
3572 r <- step gst st
3573 return $
3574 case r of
3575 Yield x s -> Yield x (s, Nothing)
3576 Skip s -> Skip (s, Nothing)
3577 Stop -> Stop
3579data DropWhileState s a
3580 = DropWhileDrop s
3581 | DropWhileYield a s
3582 | DropWhileNext s
3584{-# INLINE_NORMAL dropWhileM #-}
3585dropWhileM :: Monad m => (a -> m Bool) -> Stream m a -> Stream m a
3586dropWhileM f (Stream step state) = Stream step' (DropWhileDrop state)
3587 where
3588 {-# INLINE_LATE step' #-}
3589 step' gst (DropWhileDrop st) = do
3590 r <- step gst st
3591 case r of
3592 Yield x s -> do
3593 b <- f x
3594 if b
3595 then return $ Skip (DropWhileDrop s)
3596 else return $ Skip (DropWhileYield x s)
3597 Skip s -> return $ Skip (DropWhileDrop s)
3598 Stop -> return Stop
3600 step' gst (DropWhileNext st) = do
3601 r <- step gst st
3602 case r of
3603 Yield x s -> return $ Skip (DropWhileYield x s)
3604 Skip s -> return $ Skip (DropWhileNext s)
3605 Stop -> return Stop
3607 step' _ (DropWhileYield x st) = return $ Yield x (DropWhileNext st)
3609{-# INLINE dropWhile #-}
3610dropWhile :: Monad m => (a -> Bool) -> Stream m a -> Stream m a
3611dropWhile f = dropWhileM (return . f)
3613{-# INLINE_NORMAL filterM #-}
3614filterM :: Monad m => (a -> m Bool) -> Stream m a -> Stream m a
3615filterM f (Stream step state) = Stream step' state
3616 where
3617 {-# INLINE_LATE step' #-}
3618 step' gst st = do
3619 r <- step gst st
3620 case r of
3621 Yield x s -> do
3622 b <- f x
3623 return $ if b
3624 then Yield x s
3625 else Skip s
3626 Skip s -> return $ Skip s
3627 Stop -> return Stop
3629{-# INLINE filter #-}
3630filter :: Monad m => (a -> Bool) -> Stream m a -> Stream m a
3631filter f = filterM (return . f)
3633{-# INLINE_NORMAL uniq #-}
3634uniq :: (Eq a, Monad m) => Stream m a -> Stream m a
3635uniq (Stream step state) = Stream step' (Nothing, state)
3636 where
3637 {-# INLINE_LATE step' #-}
3638 step' gst (Nothing, st) = do
3639 r <- step gst st
3640 case r of
3641 Yield x s -> return $ Yield x (Just x, s)
3642 Skip s -> return $ Skip (Nothing, s)
3643 Stop -> return Stop
3644 step' gst (Just x, st) = do
3645 r <- step gst st
3646 case r of
3647 Yield y s | x == y -> return $ Skip (Just x, s)
3648 | otherwise -> return $ Yield y (Just y, s)
3649 Skip s -> return $ Skip (Just x, s)
3650 Stop -> return Stop
3652------------------------------------------------------------------------------
3653-- Transformation by Mapping
3654------------------------------------------------------------------------------
3656{-# INLINE_NORMAL sequence #-}
3657sequence :: Monad m => Stream m (m a) -> Stream m a
3658sequence (Stream step state) = Stream step' state
3659 where
3660 {-# INLINE_LATE step' #-}
3661 step' gst st = do
3662 r <- step (adaptState gst) st
3663 case r of
3664 Yield x s -> x >>= \a -> return (Yield a s)
3665 Skip s -> return $ Skip s
3666 Stop -> return Stop
3668------------------------------------------------------------------------------
3669-- Inserting
3670------------------------------------------------------------------------------
3672data LoopState x s = FirstYield s
3673 | InterspersingYield s
3674 | YieldAndCarry x s
3676{-# INLINE_NORMAL intersperseM #-}
3677intersperseM :: Monad m => m a -> Stream m a -> Stream m a
3678intersperseM m (Stream step state) = Stream step' (FirstYield state)
3679 where
3680 {-# INLINE_LATE step' #-}
3681 step' gst (FirstYield st) = do
3682 r <- step gst st
3683 return $
3684 case r of
3685 Yield x s -> Skip (YieldAndCarry x s)
3686 Skip s -> Skip (FirstYield s)
3687 Stop -> Stop
3689 step' gst (InterspersingYield st) = do
3690 r <- step gst st
3691 case r of
3692 Yield x s -> do
3693 a <- m
3694 return $ Yield a (YieldAndCarry x s)
3695 Skip s -> return $ Skip $ InterspersingYield s
3696 Stop -> return Stop
3698 step' _ (YieldAndCarry x st) = return $ Yield x (InterspersingYield st)
3700data SuffixState s a
3701 = SuffixElem s
3702 | SuffixSuffix s
3703 | SuffixYield a (SuffixState s a)
3705{-# INLINE_NORMAL intersperseSuffix #-}
3706intersperseSuffix :: forall m a. Monad m => m a -> Stream m a -> Stream m a
3707intersperseSuffix action (Stream step state) = Stream step' (SuffixElem state)
3708 where
3709 {-# INLINE_LATE step' #-}
3710 step' gst (SuffixElem st) = do
3711 r <- step gst st
3712 return $ case r of
3713 Yield x s -> Skip (SuffixYield x (SuffixSuffix s))
3714 Skip s -> Skip (SuffixElem s)
3715 Stop -> Stop
3717 step' _ (SuffixSuffix st) = do
3718 action >>= \r -> return $ Skip (SuffixYield r (SuffixElem st))
3720 step' _ (SuffixYield x next) = return $ Yield x next
3722data SuffixSpanState s a
3723 = SuffixSpanElem s Int
3724 | SuffixSpanSuffix s
3725 | SuffixSpanYield a (SuffixSpanState s a)
3726 | SuffixSpanLast
3727 | SuffixSpanStop
3729-- | intersperse after every n items
3730{-# INLINE_NORMAL intersperseSuffixBySpan #-}
3731intersperseSuffixBySpan :: forall m a. Monad m
3732 => Int -> m a -> Stream m a -> Stream m a
3733intersperseSuffixBySpan n action (Stream step state) =
3734 Stream step' (SuffixSpanElem state n)
3735 where
3736 {-# INLINE_LATE step' #-}
3737 step' gst (SuffixSpanElem st i) | i > 0 = do
3738 r <- step gst st
3739 return $ case r of
3740 Yield x s -> Skip (SuffixSpanYield x (SuffixSpanElem s (i - 1)))
3741 Skip s -> Skip (SuffixSpanElem s i)
3742 Stop -> if i == n then Stop else Skip SuffixSpanLast
3743 step' _ (SuffixSpanElem st _) = return $ Skip (SuffixSpanSuffix st)
3745 step' _ (SuffixSpanSuffix st) = do
3746 action >>= \r -> return $ Skip (SuffixSpanYield r (SuffixSpanElem st n))
3748 step' _ (SuffixSpanLast) = do
3749 action >>= \r -> return $ Skip (SuffixSpanYield r SuffixSpanStop)
3751 step' _ (SuffixSpanYield x next) = return $ Yield x next
3753 step' _ (SuffixSpanStop) = return Stop
3755{-# INLINE intersperse #-}
3756intersperse :: Monad m => a -> Stream m a -> Stream m a
3757intersperse a = intersperseM (return a)
3759{-# INLINE_NORMAL insertBy #-}
3760insertBy :: Monad m => (a -> a -> Ordering) -> a -> Stream m a -> Stream m a
3761insertBy cmp a (Stream step state) = Stream step' (state, False, Nothing)
3762 where
3763 {-# INLINE_LATE step' #-}
3764 step' gst (st, False, _) = do
3765 r <- step gst st
3766 case r of
3767 Yield x s -> case cmp a x of
3768 GT -> return $ Yield x (s, False, Nothing)
3769 _ -> return $ Yield a (s, True, Just x)
3770 Skip s -> return $ Skip (s, False, Nothing)
3771 Stop -> return $ Yield a (st, True, Nothing)
3773 step' _ (_, True, Nothing) = return Stop
3775 step' gst (st, True, Just prev) = do
3776 r <- step gst st
3777 case r of
3778 Yield x s -> return $ Yield prev (s, True, Just x)
3779 Skip s -> return $ Skip (s, True, Just prev)
3780 Stop -> return $ Yield prev (st, True, Nothing)
3782------------------------------------------------------------------------------
3783-- Deleting
3784------------------------------------------------------------------------------
3786{-# INLINE_NORMAL deleteBy #-}
3787deleteBy :: Monad m => (a -> a -> Bool) -> a -> Stream m a -> Stream m a
3788deleteBy eq x (Stream step state) = Stream step' (state, False)
3789 where
3790 {-# INLINE_LATE step' #-}
3791 step' gst (st, False) = do
3792 r <- step gst st
3793 case r of
3794 Yield y s -> return $
3795 if eq x y then Skip (s, True) else Yield y (s, False)
3796 Skip s -> return $ Skip (s, False)
3797 Stop -> return Stop
3799 step' gst (st, True) = do
3800 r <- step gst st
3801 case r of
3802 Yield y s -> return $ Yield y (s, True)
3803 Skip s -> return $ Skip (s, True)
3804 Stop -> return Stop
3806------------------------------------------------------------------------------
3807-- Transformation by Map and Filter
3808------------------------------------------------------------------------------
3810-- XXX Will this always fuse properly?
3811{-# INLINE_NORMAL mapMaybe #-}
3812mapMaybe :: Monad m => (a -> Maybe b) -> Stream m a -> Stream m b
3813mapMaybe f = fmap fromJust . filter isJust . map f
3815{-# INLINE_NORMAL mapMaybeM #-}
3816mapMaybeM :: Monad m => (a -> m (Maybe b)) -> Stream m a -> Stream m b
3817mapMaybeM f = fmap fromJust . filter isJust . mapM f
3819------------------------------------------------------------------------------
3820-- Zipping
3821------------------------------------------------------------------------------
3823{-# INLINE_NORMAL indexed #-}
3824indexed :: Monad m => Stream m a -> Stream m (Int, a)
3825indexed (Stream step state) = Stream step' (state, 0)
3826 where
3827 {-# INLINE_LATE step' #-}
3828 step' gst (st, i) = i `seq` do
3829 r <- step (adaptState gst) st
3830 case r of
3831 Yield x s -> return $ Yield (i, x) (s, i+1)
3832 Skip s -> return $ Skip (s, i)
3833 Stop -> return Stop
3835{-# INLINE_NORMAL indexedR #-}
3836indexedR :: Monad m => Int -> Stream m a -> Stream m (Int, a)
3837indexedR m (Stream step state) = Stream step' (state, m)
3838 where
3839 {-# INLINE_LATE step' #-}
3840 step' gst (st, i) = i `seq` do
3841 r <- step (adaptState gst) st
3842 case r of
3843 Yield x s -> let i' = i - 1
3844 in return $ Yield (i, x) (s, i')
3845 Skip s -> return $ Skip (s, i)
3846 Stop -> return Stop
3848{-# INLINE_NORMAL zipWithM #-}
3849zipWithM :: Monad m
3850 => (a -> b -> m c) -> Stream m a -> Stream m b -> Stream m c
3851zipWithM f (Stream stepa ta) (Stream stepb tb) = Stream step (ta, tb, Nothing)
3852 where
3853 {-# INLINE_LATE step #-}
3854 step gst (sa, sb, Nothing) = do
3855 r <- stepa (adaptState gst) sa
3856 return $
3857 case r of
3858 Yield x sa' -> Skip (sa', sb, Just x)
3859 Skip sa' -> Skip (sa', sb, Nothing)
3860 Stop -> Stop
3862 step gst (sa, sb, Just x) = do
3863 r <- stepb (adaptState gst) sb
3864 case r of
3865 Yield y sb' -> do
3866 z <- f x y
3867 return $ Yield z (sa, sb', Nothing)
3868 Skip sb' -> return $ Skip (sa, sb', Just x)
3869 Stop -> return Stop
3871#if __GLASGOW_HASKELL__ >= 801
3872{-# RULES "zipWithM xs xs"
3873 forall f xs. zipWithM @Identity f xs xs = mapM (\x -> f x x) xs #-}
3874#endif
3876{-# INLINE zipWith #-}
3877zipWith :: Monad m => (a -> b -> c) -> Stream m a -> Stream m b -> Stream m c
3878zipWith f = zipWithM (\a b -> return (f a b))
3880------------------------------------------------------------------------------
3881-- Merging
3882------------------------------------------------------------------------------
3884{-# INLINE_NORMAL mergeByM #-}
3885mergeByM
3886 :: (Monad m)
3887 => (a -> a -> m Ordering) -> Stream m a -> Stream m a -> Stream m a
3888mergeByM cmp (Stream stepa ta) (Stream stepb tb) =
3889 Stream step (Just ta, Just tb, Nothing, Nothing)
3890 where
3891 {-# INLINE_LATE step #-}
3893 -- one of the values is missing, and the corresponding stream is running
3894 step gst (Just sa, sb, Nothing, b) = do
3895 r <- stepa gst sa
3896 return $ case r of
3897 Yield a sa' -> Skip (Just sa', sb, Just a, b)
3898 Skip sa' -> Skip (Just sa', sb, Nothing, b)
3899 Stop -> Skip (Nothing, sb, Nothing, b)
3901 step gst (sa, Just sb, a, Nothing) = do
3902 r <- stepb gst sb
3903 return $ case r of
3904 Yield b sb' -> Skip (sa, Just sb', a, Just b)
3905 Skip sb' -> Skip (sa, Just sb', a, Nothing)
3906 Stop -> Skip (sa, Nothing, a, Nothing)
3908 -- both the values are available
3909 step _ (sa, sb, Just a, Just b) = do
3910 res <- cmp a b
3911 return $ case res of
3912 GT -> Yield b (sa, sb, Just a, Nothing)
3913 _ -> Yield a (sa, sb, Nothing, Just b)
3915 -- one of the values is missing, corresponding stream is done
3916 step _ (Nothing, sb, Nothing, Just b) =
3917 return $ Yield b (Nothing, sb, Nothing, Nothing)
3919 step _ (sa, Nothing, Just a, Nothing) =
3920 return $ Yield a (sa, Nothing, Nothing, Nothing)
3922 step _ (Nothing, Nothing, Nothing, Nothing) = return Stop
3924{-# INLINE mergeBy #-}
3925mergeBy
3926 :: (Monad m)
3927 => (a -> a -> Ordering) -> Stream m a -> Stream m a -> Stream m a
3928mergeBy cmp = mergeByM (\a b -> return $ cmp a b)
3930------------------------------------------------------------------------------
3931-- Transformation comprehensions
3932------------------------------------------------------------------------------
3934{-# INLINE_NORMAL the #-}
3935the :: (Eq a, Monad m) => Stream m a -> m (Maybe a)
3936the (Stream step state) = go state
3937 where
3938 go st = do
3939 r <- step defState st
3940 case r of
3941 Yield x s -> go' x s
3942 Skip s -> go s
3943 Stop -> return Nothing
3944 go' n st = do
3945 r <- step defState st
3946 case r of
3947 Yield x s | x == n -> go' n s
3948 | otherwise -> return Nothing
3949 Skip s -> go' n s
3950 Stop -> return (Just n)
3952{-# INLINE runFold #-}
3953runFold :: (Monad m) => Fold m a b -> Stream m a -> m b
3954runFold (Fold step begin done) = foldlMx' step begin done
3956-------------------------------------------------------------------------------
3957-- Concurrent application and fold
3958-------------------------------------------------------------------------------
3960-- XXX These functions should be moved to Stream/Parallel.hs
3962-- Using StreamD the worker stream producing code can fuse with the code to
3963-- queue output to the SVar giving some perf boost.
3965-- Note that StreamD can only be used in limited situations, specifically, we
3966-- cannot implement joinStreamVarPar using this.
3968-- XXX make sure that the SVar passed is a Parallel style SVar.
3970-- | Fold the supplied stream to the SVar asynchronously using Parallel
3971-- concurrency style.
3972-- {-# INLINE_NORMAL toSVarParallel #-}
3973{-# INLINE toSVarParallel #-}
3974toSVarParallel :: MonadAsync m
3975 => State t m a -> SVar t m a -> Stream m a -> m ()
3976toSVarParallel st sv xs =
3977 if svarInspectMode sv
3978 then forkWithDiag
3979 else do
3980 tid <-
3981 case getYieldLimit st of
3982 Nothing -> doFork (work Nothing)
3983 (svarMrun sv)
3984 (handleChildException sv)
3985 Just _ -> doFork (workLim Nothing)
3986 (svarMrun sv)
3987 (handleChildException sv)
3988 modifyThread sv tid
3990 where
3992 {-# NOINLINE work #-}
3993 work info = (runFold (FL.toParallelSVar sv info) xs)
3995 {-# NOINLINE workLim #-}
3996 workLim info = runFold (FL.toParallelSVarLimited sv info) xs
3998 {-# NOINLINE forkWithDiag #-}
3999 forkWithDiag = do
4000 -- We do not use workerCount in case of ParallelVar but still there is
4001 -- no harm in maintaining it correctly.
4002 liftIO $ atomicModifyIORefCAS_ (workerCount sv) $ \n -> n + 1
4003 recordMaxWorkers sv
4004 -- This allocation matters when significant number of workers are being
4005 -- sent. We allocate it only when needed. The overhead increases by 4x.
4006 winfo <-
4007 case yieldRateInfo sv of
4008 Nothing -> return Nothing
4009 Just _ -> liftIO $ do
4010 cntRef <- newIORef 0
4011 t <- getTime Monotonic
4012 lat <- newIORef (0, t)
4013 return $ Just WorkerInfo
4014 { workerYieldMax = 0
4015 , workerYieldCount = cntRef
4016 , workerLatencyStart = lat
4018 tid <-
4019 case getYieldLimit st of
4020 Nothing -> doFork (work winfo)
4021 (svarMrun sv)
4022 (handleChildException sv)
4023 Just _ -> doFork (workLim winfo)
4024 (svarMrun sv)
4025 (handleChildException sv)
4026 modifyThread sv tid
4028{-# INLINE_NORMAL mkParallelD #-}
4029mkParallelD :: MonadAsync m => Stream m a -> Stream m a
4030mkParallelD m = Stream step Nothing
4031 where
4033 step gst Nothing = do
4034 sv <- newParallelVar StopNone gst
4035 toSVarParallel gst sv m
4036 -- XXX use unfold instead?
4037 return $ Skip $ Just $ fromSVar sv
4039 step gst (Just (UnStream step1 st)) = do
4040 r <- step1 gst st
4041 return $ case r of
4042 Yield a s -> Yield a (Just $ Stream step1 s)
4043 Skip s -> Skip (Just $ Stream step1 s)
4044 Stop -> Stop
4046-- Compare with mkAsync. mkAsync uses an Async style SVar whereas this uses a
4047-- parallel style SVar for evaluation. Currently, parallel style cannot use
4048-- rate control whereas Async style can use rate control. In async style SVar
4049-- the worker thread terminates when the buffer is full whereas in Parallel
4050-- style it blocks.
4052-- | Make the stream producer and consumer run concurrently by introducing a
4053-- buffer between them. The producer thread evaluates the input stream until
4054-- the buffer fills, it blocks if the buffer is full until there is space in
4055-- the buffer. The consumer consumes the stream lazily from the buffer.
4057-- /Internal/
4059{-# INLINE_NORMAL mkParallel #-}
4060mkParallel :: (K.IsStream t, MonadAsync m) => t m a -> t m a
4061mkParallel = fromStreamD . mkParallelD . toStreamD
4063-------------------------------------------------------------------------------
4064-- Concurrent tap
4065-------------------------------------------------------------------------------
4067-- | Create an SVar with a fold consumer that will fold any elements sent to it
4068-- using the supplied fold function.
4069{-# INLINE newFoldSVar #-}
4070newFoldSVar :: MonadAsync m => State t m a -> Fold m a b -> m (SVar t m a)
4071newFoldSVar stt f = do
4072 -- Buffer size for the SVar is derived from the current state
4073 sv <- newParallelVar StopAny (adaptState stt)
4074 -- Add the producer thread-id to the SVar.
4075 liftIO myThreadId >>= modifyThread sv
4076 void $ doFork (work sv) (svarMrun sv) (handleFoldException sv)
4077 return sv
4079 where
4081 {-# NOINLINE work #-}
4082 work sv = void $ runFold f $ fromProducer sv
4084data TapState sv st = TapInit | Tapping sv st | TapDone st
4086{-# INLINE_NORMAL tapAsync #-}
4087tapAsync :: MonadAsync m => Fold m a b -> Stream m a -> Stream m a
4088tapAsync f (Stream step1 state1) = Stream step TapInit
4089 where
4091 drainFold svr = do
4092 -- In general, a Stop event would come equipped with the result
4093 -- of the fold. It is not used here but it would be useful in
4094 -- applicative and distribute.
4095 done <- fromConsumer svr
4096 when (not done) $ do
4097 liftIO $ withDiagMVar svr "teeToSVar: waiting to drain"
4098 $ takeMVar (outputDoorBellFromConsumer svr)
4099 drainFold svr
4101 stopFold svr = do
4102 liftIO $ sendStop svr Nothing
4103 -- drain/wait until a stop event arrives from the fold.
4104 drainFold svr
4106 {-# INLINE_LATE step #-}
4107 step gst TapInit = do
4108 sv <- newFoldSVar gst f
4109 return $ Skip (Tapping sv state1)
4111 step gst (Tapping sv st) = do
4112 r <- step1 gst st
4113 case r of
4114 Yield a s -> do
4115 done <- pushToFold sv a
4116 if done
4117 then do
4118 -- XXX we do not need to wait synchronously here
4119 stopFold sv
4120 return $ Yield a (TapDone s)
4121 else return $ Yield a (Tapping sv s)
4122 Skip s -> return $ Skip (Tapping sv s)
4123 Stop -> do
4124 stopFold sv
4125 return $ Stop
4127 step gst (TapDone st) = do
4128 r <- step1 gst st
4129 return $ case r of
4130 Yield a s -> Yield a (TapDone s)
4131 Skip s -> Skip (TapDone s)
4132 Stop -> Stop
4134-- XXX Exported from Array again as this fold is specific to Array
4135-- | Take last 'n' elements from the stream and discard the rest.
4136{-# INLINE lastN #-}
4137lastN :: (Storable a, MonadIO m) => Int -> Fold m a (Array a)
4138lastN n = Fold step initial done
4139 where
4140 step (Tuple3' rb rh i) a = do
4141 rh1 <- liftIO $ RB.unsafeInsert rb rh a
4142 return $ Tuple3' rb rh1 (i + 1)
4143 initial = fmap (\(a, b) -> Tuple3' a b (0 :: Int)) $ liftIO $ RB.new n
4144 done (Tuple3' rb rh i) = do
4145 arr <- liftIO $ A.newArray n
4146 foldFunc i rh snoc' arr rb
4147 snoc' b a = liftIO $ A.unsafeSnoc b a
4148 foldFunc i
4149 | i < n = RB.unsafeFoldRingM
4150 | otherwise = RB.unsafeFoldRingFullM
4152------------------------------------------------------------------------------
4153-- Time related
4154------------------------------------------------------------------------------
4156-- XXX using getTime in the loop can be pretty expensive especially for
4157-- computations where iterations are lightweight. We have the following
4158-- options:
4160-- 1) Run a timeout thread updating a flag asynchronously and check that
4161-- flag here, that way we can have a cheap termination check.
4163-- 2) Use COARSE clock to get time with lower resolution but more efficiently.
4165-- 3) Use rdtscp/rdtsc to get time directly from the processor, compute the
4166-- termination value of rdtsc in the beginning and then in each iteration just
4167-- get rdtsc and check if we should terminate.
4169data TakeByTime st s
4170 = TakeByTimeInit st
4171 | TakeByTimeCheck st s
4172 | TakeByTimeYield st s
4174{-# INLINE_NORMAL takeByTime #-}
4175takeByTime :: (MonadIO m, TimeUnit64 t) => t -> Stream m a -> Stream m a
4176takeByTime duration (Stream step1 state1) = Stream step (TakeByTimeInit state1)
4177 where
4179 lim = toRelTime64 duration
4181 {-# INLINE_LATE step #-}
4182 step _ (TakeByTimeInit _) | lim == 0 = return Stop
4183 step _ (TakeByTimeInit st) = do
4184 t0 <- liftIO $ getTime Monotonic
4185 return $ Skip (TakeByTimeYield st t0)
4186 step _ (TakeByTimeCheck st t0) = do
4187 t <- liftIO $ getTime Monotonic
4188 return $
4189 if diffAbsTime64 t t0 > lim
4190 then Stop
4191 else Skip (TakeByTimeYield st t0)
4192 step gst (TakeByTimeYield st t0) = do
4193 r <- step1 gst st
4194 return $ case r of
4195 Yield x s -> Yield x (TakeByTimeCheck s t0)
4196 Skip s -> Skip (TakeByTimeCheck s t0)
4197 Stop -> Stop
4199data DropByTime st s x
4200 = DropByTimeInit st
4201 | DropByTimeGen st s
4202 | DropByTimeCheck st s x
4203 | DropByTimeYield st
4205{-# INLINE_NORMAL dropByTime #-}
4206dropByTime :: (MonadIO m, TimeUnit64 t) => t -> Stream m a -> Stream m a
4207dropByTime duration (Stream step1 state1) = Stream step (DropByTimeInit state1)
4208 where
4210 lim = toRelTime64 duration
4212 {-# INLINE_LATE step #-}
4213 step _ (DropByTimeInit st) = do
4214 t0 <- liftIO $ getTime Monotonic
4215 return $ Skip (DropByTimeGen st t0)
4216 step gst (DropByTimeGen st t0) = do
4217 r <- step1 gst st
4218 return $ case r of
4219 Yield x s -> Skip (DropByTimeCheck s t0 x)
4220 Skip s -> Skip (DropByTimeGen s t0)
4221 Stop -> Stop
4222 step _ (DropByTimeCheck st t0 x) = do
4223 t <- liftIO $ getTime Monotonic
4224 if diffAbsTime64 t t0 <= lim
4225 then return $ Skip $ DropByTimeGen st t0
4226 else return $ Yield x $ DropByTimeYield st
4227 step gst (DropByTimeYield st) = do
4228 r <- step1 gst st
4229 return $ case r of
4230 Yield x s -> Yield x (DropByTimeYield s)
4231 Skip s -> Skip (DropByTimeYield s)
4232 Stop -> Stop
4234-- XXX we should move this to stream generation section of this file. Also, the
4235-- take/drop combinators above should be moved to filtering section.
4236{-# INLINE_NORMAL currentTime #-}
4237currentTime :: MonadAsync m => Double -> Stream m AbsTime
4238currentTime g = Stream step Nothing
4240 where
4242 g' = g * 10 ^ (6 :: Int)
4244 -- XXX should have a minimum granularity to avoid high CPU usage?
4245 {-# INLINE delayTime #-}
4246 delayTime =
4247 if g' >= fromIntegral (maxBound :: Int)
4248 then maxBound
4249 else round g'
4251 updateTimeVar timeVar = do
4252 threadDelay $ delayTime
4253 MicroSecond64 t <- fromAbsTime <$> getTime Monotonic
4254 modifyVar' timeVar (const t)
4256 {-# INLINE_LATE step #-}
4257 step _ Nothing = do
4258 -- XXX note that this is safe only on a 64-bit machine. On a 32-bit
4259 -- machine a 64-bit 'Var' cannot be read consistently without a lock
4260 -- while another thread is writing to it.
4261 timeVar <- liftIO $ newVar (0 :: Int64)
4262 tid <- forkManaged $ liftIO $ forever (updateTimeVar timeVar)
4263 return $ Skip $ Just (timeVar, tid)
4265 step _ s@(Just (timeVar, _)) = do
4266 a <- liftIO $ readVar timeVar
4267 -- XXX we can perhaps use an AbsTime64 using a 64 bit Int for
4268 -- efficiency. or maybe we can use a representation using Double for
4269 -- floating precision time
4270 return $ Yield (toAbsTime (MicroSecond64 a)) s