2{-# LANGUAGE ConstraintKinds #-}
3{-# LANGUAGE FlexibleContexts #-}
4{-# LANGUAGE FlexibleInstances #-}
5{-# LANGUAGE GeneralizedNewtypeDeriving#-}
6{-# LANGUAGE InstanceSigs #-}
7{-# LANGUAGE MultiParamTypeClasses #-}
8{-# LANGUAGE StandaloneDeriving #-}
9{-# LANGUAGE UndecidableInstances #-} -- XXX
12-- Module : Streamly.Streams.Serial
13-- Copyright : (c) 2017 Harendra Kumar
16-- Maintainer : harendra.kumar@gmail.com
17-- Stability : experimental
21module Streamly.Streams.Serial
23 -- * Serial appending stream
25 , StreamT -- deprecated
30 -- * Serial interleaving stream
32 , InterleavedT -- deprecated
37 , interleaving -- deprecated
40 , runStreamT -- deprecated
41 , runInterleavedT -- deprecated
45import Control.Monad (ap)
46import Control.Monad.Base (MonadBase(..), liftBaseDefault)
47import Control.Monad.Catch (MonadThrow, throwM)
48-- import Control.Monad.Error.Class (MonadError(..))
49import Control.Monad.IO.Class (MonadIO(..))
50import Control.Monad.Reader.Class (MonadReader(..))
51import Control.Monad.State.Class (MonadState(..))
52import Control.Monad.Trans.Class (MonadTrans(lift))
53import Data.Semigroup (Semigroup(..))
55import Streamly.Streams.StreamK hiding (serial)
56import qualified Streamly.Streams.StreamK as C
58#include "Instances.hs"
60------------------------------------------------------------------------------
62------------------------------------------------------------------------------
64-- | Deep serial composition or serial composition with depth first traversal.
65-- The 'Semigroup' instance of 'SerialT' appends two streams serially in a
66-- depth first manner, yielding all elements from the first stream, and then
67-- all elements from the second stream.
71-- import qualified "Streamly.Prelude" as S
73-- main = ('toList' . 'serially' $ (fromFoldable [1,2]) \<\> (fromFoldable [3,4])) >>= print
79-- The 'Monad' instance runs the /monadic continuation/ for each
80-- element of the stream, serially.
83-- main = 'runStream' . 'serially' $ do
84-- x <- return 1 \<\> return 2
92-- 'SerialT' nests streams serially in a depth first manner.
95-- main = 'runStream' . 'serially' $ do
96-- x <- return 1 \<\> return 2
97-- y <- return 3 \<\> return 4
98-- S.once $ print (x, y)
107-- This behavior of 'SerialT' is exactly like a list transformer. We call the
108-- monadic code being run for each element of the stream a monadic
109-- continuation. In imperative paradigm we can think of this composition as
110-- nested @for@ loops and the monadic continuation is the body of the loop. The
111-- loop iterates for all elements of the stream.
113-- The 'serially' combinator can be omitted as the default stream type is
115-- Note that serial composition with depth first traversal can be used to
116-- combine an infinite number of streams as it explores only one stream at a
120newtype SerialT m a = SerialT {getSerialT :: Stream m a}
121 deriving (Semigroup, Monoid, Functor, MonadTrans)
123-- | A serial IO stream of elements of type @a@. See 'SerialT' documentation
127type Serial a = SerialT IO a
131{-# DEPRECATED StreamT "Please use 'SerialT' instead." #-}
132type StreamT = SerialT
134-- | Fix the type of a polymorphic stream as 'SerialT'.
137serially :: IsStream t => SerialT m a -> t m a
140instance IsStream SerialT where
141 toStream = getSerialT
145 {-# SPECIALIZE consM :: IO a -> SerialT IO a -> SerialT IO a #-}
146 consM :: Monad m => m a -> SerialT m a -> SerialT m a
147 consM m r = fromStream $ consMSerial m (toStream r)
150 {-# SPECIALIZE (|:) :: IO a -> SerialT IO a -> SerialT IO a #-}
151 (|:) :: Monad m => m a -> SerialT m a -> SerialT m a
152 m |: r = fromStream $ consMSerial m (toStream r)
154------------------------------------------------------------------------------
156------------------------------------------------------------------------------
158-- | Polymorphic version of the 'Semigroup' operation '<>' of 'SerialT'.
159-- Appends two streams sequentially, yielding all elements from the first
160-- stream, and then all elements from the second stream.
164serial :: IsStream t => t m a -> t m a -> t m a
165serial m1 m2 = fromStream $ C.serial (toStream m1) (toStream m2)
167------------------------------------------------------------------------------
169------------------------------------------------------------------------------
171instance Monad m => Monad (SerialT m) where
173 (SerialT (Stream m)) >>= f = SerialT $ Stream $ \_ stp sng yld ->
174 let run x = (unStream x) Nothing stp sng yld
175 single a = run $ toStream (f a)
176 yieldk a r = run $ toStream $ f a <> (fromStream r >>= f)
177 in m Nothing stp single yieldk
179------------------------------------------------------------------------------
181------------------------------------------------------------------------------
183MONAD_APPLICATIVE_INSTANCE(SerialT,)
184MONAD_COMMON_INSTANCES(SerialT,)
186------------------------------------------------------------------------------
188------------------------------------------------------------------------------
190-- | Wide serial composition or serial composition with a breadth first
191-- traversal. The 'Semigroup' instance of 'WSerialT' traverses
192-- the two streams in a breadth first manner. In other words, it interleaves
193-- two streams, yielding one element from each stream alternately.
197-- import qualified "Streamly.Prelude" as S
199-- main = ('toList' . 'wSerially' $ (fromFoldable [1,2]) \<\> (fromFoldable [3,4])) >>= print
205-- Similarly, the 'Monad' instance interleaves the iterations of the
206-- inner and the outer loop, nesting loops in a breadth first manner.
210-- main = 'runStream' . 'wSerially' $ do
211-- x <- return 1 \<\> return 2
212-- y <- return 3 \<\> return 4
213-- S.once $ print (x, y)
222-- Note that a serial composition with breadth first traversal can only combine
223-- a finite number of streams as it needs to retain state for each unfinished
227newtype WSerialT m a = WSerialT {getWSerialT :: Stream m a}
228 deriving (Functor, MonadTrans)
230-- | An interleaving serial IO stream of elements of type @a@. See 'WSerialT'
231-- documentation for more details.
234type WSerial a = WSerialT IO a
238{-# DEPRECATED InterleavedT "Please use 'WSerialT' instead." #-}
239type InterleavedT = WSerialT
241-- | Fix the type of a polymorphic stream as 'WSerialT'.
244wSerially :: IsStream t => WSerialT m a -> t m a
247-- | Same as 'wSerially'.
250{-# DEPRECATED interleaving "Please use wSerially instead." #-}
251interleaving :: IsStream t => WSerialT m a -> t m a
252interleaving = wSerially
254instance IsStream WSerialT where
255 toStream = getWSerialT
256 fromStream = WSerialT
259 {-# SPECIALIZE consM :: IO a -> WSerialT IO a -> WSerialT IO a #-}
260 consM :: Monad m => m a -> WSerialT m a -> WSerialT m a
261 consM m r = fromStream $ consMSerial m (toStream r)
264 {-# SPECIALIZE (|:) :: IO a -> WSerialT IO a -> WSerialT IO a #-}
265 (|:) :: Monad m => m a -> WSerialT m a -> WSerialT m a
266 m |: r = fromStream $ consMSerial m (toStream r)
268------------------------------------------------------------------------------
270------------------------------------------------------------------------------
272{-# INLINE interleave #-}
273interleave :: Stream m a -> Stream m a -> Stream m a
274interleave m1 m2 = Stream $ \_ stp sng yld -> do
275 let stop = (unStream m2) Nothing stp sng yld
277 yieldk a r = yld a (interleave m2 r)
278 (unStream m1) Nothing stop single yieldk
280-- | Polymorphic version of the 'Semigroup' operation '<>' of 'WSerialT'.
281-- Interleaves two streams, yielding one element from each stream alternately.
284{-# INLINE wSerial #-}
285wSerial :: IsStream t => t m a -> t m a -> t m a
286wSerial m1 m2 = fromStream $ interleave (toStream m1) (toStream m2)
288instance Semigroup (WSerialT m a) where
293-- | Same as 'wSerial'.
296{-# DEPRECATED (<=>) "Please use 'wSerial' instead." #-}
298(<=>) :: IsStream t => t m a -> t m a -> t m a
301------------------------------------------------------------------------------
303------------------------------------------------------------------------------
305instance Monoid (WSerialT m a) where
309------------------------------------------------------------------------------
311------------------------------------------------------------------------------
313instance Monad m => Monad (WSerialT m) where
315 (WSerialT (Stream m)) >>= f = WSerialT $ Stream $ \_ stp sng yld ->
316 let run x = (unStream x) Nothing stp sng yld
317 single a = run $ toStream (f a)
318 yieldk a r = run $ toStream $ f a <> (fromStream r >>= f)
319 in m Nothing stp single yieldk
321------------------------------------------------------------------------------
323------------------------------------------------------------------------------
325MONAD_APPLICATIVE_INSTANCE(WSerialT,)
326MONAD_COMMON_INSTANCES(WSerialT,)
328-------------------------------------------------------------------------------
330-------------------------------------------------------------------------------
332-- | Same as @runStream@.
335{-# DEPRECATED runStreamT "Please use runStream instead." #-}
336runStreamT :: Monad m => SerialT m a -> m ()
337runStreamT = runStream
339-- | Same as @runStream . wSerially@.
342{-# DEPRECATED runInterleavedT "Please use 'runStream . interleaving' instead." #-}
343runInterleavedT :: Monad m => InterleavedT m a -> m ()
344runInterleavedT = runStream
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list