2{-# LANGUAGE ConstraintKinds #-}
3{-# LANGUAGE FlexibleContexts #-}
4{-# LANGUAGE FlexibleInstances #-}
5{-# LANGUAGE GeneralizedNewtypeDeriving#-}
6{-# LANGUAGE InstanceSigs #-}
7{-# LANGUAGE MultiParamTypeClasses #-}
8{-# LANGUAGE TypeFamilies #-}
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
45import Control.Applicative (liftA2)
46import Control.DeepSeq (NFData(..), NFData1(..), rnf1)
47import Control.Monad (ap)
48import Control.Monad.Base (MonadBase(..), liftBaseDefault)
49import Control.Monad.Catch (MonadThrow, throwM)
50-- import Control.Monad.Error.Class (MonadError(..))
51import Control.Monad.IO.Class (MonadIO(..))
52import Control.Monad.Reader.Class (MonadReader(..))
53import Control.Monad.State.Class (MonadState(..))
54import Control.Monad.Trans.Class (MonadTrans(lift))
55import Data.Functor.Identity (Identity(..), runIdentity)
56import Data.Foldable (fold)
57import Data.Semigroup (Semigroup(..))
58import GHC.Exts (IsList(..), IsString(..))
59import Text.Read (Lexeme(Ident), lexP, parens, prec, readPrec, readListPrec,
61import Prelude hiding (map, mapM)
63import Streamly.Streams.StreamK (IsStream(..), adapt, Stream, mkStream,
65import qualified Streamly.Streams.Prelude as P
66import qualified Streamly.Streams.StreamK as K
67import qualified Streamly.Streams.StreamD as D
69#include "Instances.hs"
72------------------------------------------------------------------------------
74------------------------------------------------------------------------------
76-- | Deep serial composition or serial composition with depth first traversal.
77-- The 'Semigroup' instance of 'SerialT' appends two streams serially in a
78-- depth first manner, yielding all elements from the first stream, and then
79-- all elements from the second stream.
83-- import qualified "Streamly.Prelude" as S
85-- main = ('toList' . 'serially' $ (fromFoldable [1,2]) \<\> (fromFoldable [3,4])) >>= print
91-- The 'Monad' instance runs the /monadic continuation/ for each
92-- element of the stream, serially.
95-- main = 'runStream' . 'serially' $ do
96-- x <- return 1 \<\> return 2
104-- 'SerialT' nests streams serially in a depth first manner.
107-- main = 'runStream' . 'serially' $ do
108-- x <- return 1 \<\> return 2
109-- y <- return 3 \<\> return 4
110-- S.yieldM $ print (x, y)
119-- This behavior of 'SerialT' is exactly like a list transformer. We call the
120-- monadic code being run for each element of the stream a monadic
121-- continuation. In imperative paradigm we can think of this composition as
122-- nested @for@ loops and the monadic continuation is the body of the loop. The
123-- loop iterates for all elements of the stream.
125-- The 'serially' combinator can be omitted as the default stream type is
127-- Note that serial composition with depth first traversal can be used to
128-- combine an infinite number of streams as it explores only one stream at a
132newtype SerialT m a = SerialT {getSerialT :: Stream m a}
133 deriving (Semigroup, Monoid, MonadTrans)
135-- | A serial IO stream of elements of type @a@. See 'SerialT' documentation
139type Serial = SerialT IO
143{-# DEPRECATED StreamT "Please use 'SerialT' instead." #-}
144type StreamT = SerialT
146-- | Fix the type of a polymorphic stream as 'SerialT'.
149serially :: IsStream t => SerialT m a -> t m a
152consMSerial :: Monad m => m a -> SerialT m a -> SerialT m a
153consMSerial m ms = fromStream $ K.consMStream m (toStream ms)
155instance IsStream SerialT where
156 toStream = getSerialT
160 {-# SPECIALIZE consM :: IO a -> SerialT IO a -> SerialT IO a #-}
161 consM :: Monad m => m a -> SerialT m a -> SerialT m a
165 {-# SPECIALIZE (|:) :: IO a -> SerialT IO a -> SerialT IO a #-}
166 (|:) :: Monad m => m a -> SerialT m a -> SerialT m a
169------------------------------------------------------------------------------
171------------------------------------------------------------------------------
173instance Monad m => Monad (SerialT m) where
175 (>>=) = K.bindWith K.serial
177------------------------------------------------------------------------------
179------------------------------------------------------------------------------
181{-# INLINE_EARLY mapM #-}
182mapM :: (IsStream t, Monad m) => (a -> m b) -> t m a -> t m b
183mapM f m = fromStream $ D.toStreamK $ D.mapM f $ D.fromStreamK (toStream m)
193-- > S.toList $ S.map (+1) $ S.fromList [1,2,3]
199map :: (IsStream t, Monad m) => (a -> b) -> t m a -> t m b
200map f = mapM (return . f)
202MONAD_APPLICATIVE_INSTANCE(SerialT,)
203MONAD_COMMON_INSTANCES(SerialT,)
205------------------------------------------------------------------------------
207------------------------------------------------------------------------------
209-- | Wide serial composition or serial composition with a breadth first
210-- traversal. The 'Semigroup' instance of 'WSerialT' traverses
211-- the two streams in a breadth first manner. In other words, it interleaves
212-- two streams, yielding one element from each stream alternately.
216-- import qualified "Streamly.Prelude" as S
218-- main = ('toList' . 'wSerially' $ (fromFoldable [1,2]) \<\> (fromFoldable [3,4])) >>= print
224-- Similarly, the 'Monad' instance interleaves the iterations of the
225-- inner and the outer loop, nesting loops in a breadth first manner.
229-- main = 'runStream' . 'wSerially' $ do
230-- x <- return 1 \<\> return 2
231-- y <- return 3 \<\> return 4
232-- S.yieldM $ print (x, y)
241-- Note that a serial composition with breadth first traversal can only combine
242-- a finite number of streams as it needs to retain state for each unfinished
246newtype WSerialT m a = WSerialT {getWSerialT :: Stream m a}
247 deriving (MonadTrans)
249-- | An interleaving serial IO stream of elements of type @a@. See 'WSerialT'
250-- documentation for more details.
253type WSerial = WSerialT IO
257{-# DEPRECATED InterleavedT "Please use 'WSerialT' instead." #-}
258type InterleavedT = WSerialT
260-- | Fix the type of a polymorphic stream as 'WSerialT'.
263wSerially :: IsStream t => WSerialT m a -> t m a
266-- | Same as 'wSerially'.
269{-# DEPRECATED interleaving "Please use wSerially instead." #-}
270interleaving :: IsStream t => WSerialT m a -> t m a
271interleaving = wSerially
273consMWSerial :: Monad m => m a -> WSerialT m a -> WSerialT m a
274consMWSerial m ms = fromStream $ K.consMStream m (toStream ms)
276instance IsStream WSerialT where
277 toStream = getWSerialT
278 fromStream = WSerialT
281 {-# SPECIALIZE consM :: IO a -> WSerialT IO a -> WSerialT IO a #-}
282 consM :: Monad m => m a -> WSerialT m a -> WSerialT m a
286 {-# SPECIALIZE (|:) :: IO a -> WSerialT IO a -> WSerialT IO a #-}
287 (|:) :: Monad m => m a -> WSerialT m a -> WSerialT m a
290------------------------------------------------------------------------------
292------------------------------------------------------------------------------
294-- | Polymorphic version of the 'Semigroup' operation '<>' of 'WSerialT'.
295-- Interleaves two streams, yielding one element from each stream alternately.
298{-# INLINE wSerial #-}
299wSerial :: IsStream t => t m a -> t m a -> t m a
300wSerial m1 m2 = mkStream $ \st yld sng stp -> do
301 let stop = foldStream st yld sng stp m2
303 yieldk a r = yld a (wSerial m2 r)
304 foldStream st yieldk single stop m1
306instance Semigroup (WSerialT m a) where
311-- | Same as 'wSerial'.
314{-# DEPRECATED (<=>) "Please use 'wSerial' instead." #-}
316(<=>) :: IsStream t => t m a -> t m a -> t m a
319------------------------------------------------------------------------------
321------------------------------------------------------------------------------
323instance Monoid (WSerialT m a) where
327------------------------------------------------------------------------------
329------------------------------------------------------------------------------
331instance Monad m => Monad (WSerialT m) where
333 (>>=) = K.bindWith wSerial
335------------------------------------------------------------------------------
337------------------------------------------------------------------------------
339MONAD_APPLICATIVE_INSTANCE(WSerialT,)
340MONAD_COMMON_INSTANCES(WSerialT,)
342LIST_INSTANCES(SerialT)
343LIST_INSTANCES(WSerialT)
345FOLDABLE_INSTANCE(SerialT)
346FOLDABLE_INSTANCE(WSerialT)
348TRAVERSABLE_INSTANCE(SerialT)
349TRAVERSABLE_INSTANCE(WSerialT)
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