on master help sign in
Revert "Split Serial module into Serial and WSerial"

This reverts commit 5ddfb4576482b2ec712fffa0771b114c3e821958.

commitd3ec4917d9a7601e4272e2f55ada47c809ab31b5 authorHarendra Kumar <harendra@composewell.com> dateThu 13 Oct 2022, 01:27 (4 years ago) parent98da856
7 files changed+193−220
src/Streamly/Internal/Data/Stream/IsStream/Expand.hs+3−3 src/Streamly/Internal/Data/Stream/IsStream/Generate.hs+1−2 src/Streamly/Internal/Data/Stream/IsStream/Type.hs+4−5 src/Streamly/Internal/Data/Stream/Serial.hs+183−2 src/Streamly/Internal/Data/Stream/WSerial.hs−205 streamly.cabal−1 test/Streamly/Test/Prelude/WSerial.hs+2−2
src/Streamly/Internal/Data/Stream/IsStream/Expand.hs+3−3
@@ -52,8 +52,8 @@ module Streamly.Internal.Data.Stream.IsStream.Expand
5252 -- streams that come earlier in the composition.
5353 --
5454 , wSerial
55− , WSerial.wSerialFst
56− , WSerial.wSerialMin
55+ , Serial.wSerialFst
56+ , Serial.wSerialMin
5757
5858 -- ** Interleave
5959 -- | 'interleave' is like 'wSerial' but using a direct style
@@ -175,7 +175,7 @@ import Streamly.Data.Unfold (Unfold)
175175
176176import qualified Streamly.Internal.Data.Stream.IsStream.Type as IsStream
177177import qualified Streamly.Internal.Data.Stream.Parallel as Par
178−import qualified Streamly.Internal.Data.Stream.WSerial as WSerial
178+import qualified Streamly.Internal.Data.Stream.Serial as Serial
179179import qualified Streamly.Internal.Data.Stream.StreamD as D
180180 (append, interleave, interleaveSuffix, interleaveInfix, interleaveMin
181181 , roundRobin, mergeByM, unfoldMany, unfoldManyInterleave, intersperse
src/Streamly/Internal/Data/Stream/IsStream/Generate.hs+1−2
@@ -100,8 +100,7 @@ import Streamly.Internal.Data.Stream.IsStream.Common
100100 , yield, yieldM, repeatM)
101101import Streamly.Internal.Data.Stream.IsStream.Type
102102 (IsStream (..), fromSerial, consM, fromStreamD)
103−import Streamly.Internal.Data.Stream.Serial (SerialT)
104−import Streamly.Internal.Data.Stream.WSerial (WSerialT)
103+import Streamly.Internal.Data.Stream.Serial (SerialT, WSerialT)
105104import Streamly.Internal.Data.Stream.Zip (ZipSerialM)
106105import Streamly.Internal.Data.Time.Units (AbsTime , RelTime64, addToAbsTime64)
107106import Streamly.Internal.Data.Unboxed (Unboxed)
src/Streamly/Internal/Data/Stream/IsStream/Type.hs+4−5
@@ -101,8 +101,8 @@ where
101101
102102import Streamly.Internal.Control.Concurrent (MonadAsync)
103103import Streamly.Internal.Data.Fold.Type (Fold (..))
104−import Streamly.Internal.Data.Stream.Serial (SerialT, Serial)
105−import Streamly.Internal.Data.Stream.WSerial (WSerialT(..), WSerial)
104+import Streamly.Internal.Data.Stream.Serial
105+ (SerialT, Serial, WSerialT(..), WSerial)
106106import Streamly.Internal.Data.Stream.Async
107107 (AsyncT(..), Async, WAsyncT(..), WAsync)
108108import Streamly.Internal.Data.Stream.Ahead (AheadT(..), Ahead)
@@ -116,7 +116,6 @@ import qualified Streamly.Internal.Data.Stream.Ahead as Ahead
116116import qualified Streamly.Internal.Data.Stream.Async as Async
117117import qualified Streamly.Internal.Data.Stream.Parallel as Parallel
118118import qualified Streamly.Internal.Data.Stream.Serial as Serial
119−import qualified Streamly.Internal.Data.Stream.WSerial as WSerial
120119import qualified Streamly.Internal.Data.Stream.StreamD.Type as D
121120 (Stream(..), toStreamK, fromStreamK
122121 , drain, eqBy, cmpBy, fromList, toList, foldrMx, foldlMx'
@@ -470,12 +469,12 @@ instance IsStream WSerialT where
470469 {-# INLINE consM #-}
471470 {-# SPECIALIZE consM :: IO a -> WSerialT IO a -> WSerialT IO a #-}
472471 consM :: Monad m => m a -> WSerialT m a -> WSerialT m a
473− consM = WSerial.consMWSerial
472+ consM = Serial.consMWSerial
474473
475474 {-# INLINE (|:) #-}
476475 {-# SPECIALIZE (|:) :: IO a -> WSerialT IO a -> WSerialT IO a #-}
477476 (|:) :: Monad m => m a -> WSerialT m a -> WSerialT m a
478− (|:) = WSerial.consMWSerial
477+ (|:) = Serial.consMWSerial
479478
480479-------------------------------------------------------------------------------
481480-- Async
src/Streamly/Internal/Data/Stream/Serial.hs+183−2
@@ -1,3 +1,5 @@
1+{-# LANGUAGE UndecidableInstances #-}
2+
13-- |
24-- Module : Streamly.Internal.Data.Stream.Serial
35-- Copyright : (c) 2017 Composewell Technologies
@@ -10,6 +12,7 @@
1012-- To run examples in this module:
1113--
1214-- >>> import qualified Streamly.Data.Stream as Stream
15+-- >>> import qualified Streamly.Prelude as IsStream
1316--
1417module Streamly.Internal.Data.Stream.Serial
1518 (
@@ -18,6 +21,14 @@ module Streamly.Internal.Data.Stream.Serial
1821 , Serial
1922 , serial
2023
24+ -- * Serial interleaving stream
25+ , WSerialT(..)
26+ , WSerial
27+ , wSerial
28+ , wSerialFst
29+ , wSerialMin
30+ , consMWSerial
31+
2132 -- * Construction
2233 , Stream.cons
2334 , Stream.consM
@@ -34,15 +45,42 @@ module Streamly.Internal.Data.Stream.Serial
3445 )
3546where
3647
37−import GHC.Exts (IsList(..))
48+import Control.Applicative (liftA2)
49+import Control.DeepSeq (NFData(..), NFData1(..))
50+import Control.Monad.Base (MonadBase(..), liftBaseDefault)
51+import Control.Monad.Catch (MonadThrow, throwM)
52+import Control.Monad.IO.Class (MonadIO(..))
53+import Control.Monad.Reader.Class (MonadReader(..))
54+import Control.Monad.State.Class (MonadState(..))
55+import Control.Monad.Trans.Class (MonadTrans(lift))
56+import Data.Foldable (Foldable(foldl'), fold)
57+import Data.Functor.Identity (Identity(..), runIdentity)
58+import Data.Maybe (fromMaybe)
59+import Data.Semigroup (Endo(..))
60+import GHC.Exts (IsList(..), IsString(..), oneShot)
61+import Text.Read
62+ ( Lexeme(Ident), lexP, parens, prec, readPrec, readListPrec
63+ , readListPrecDefault)
64+import Streamly.Internal.BaseCompat ((#.))
65+import Streamly.Internal.Data.Maybe.Strict (Maybe'(..), toMaybe)
3866import Streamly.Data.Stream (Stream)
3967
4068import qualified Streamly.Data.Stream as Stream
69+import qualified Streamly.Internal.Data.Stream.Common as P
70+import qualified Streamly.Internal.Data.Stream.StreamD as D
71+ (fromStreamK, toStreamK, mapM)
72+import qualified Streamly.Internal.Data.Stream.StreamK.Type as K
73+ (Stream, cons, consM, nil, concatMapWith, fromPure, bindWith
74+ , withLocal, interleave, interleaveFst, interleaveMin)
4175
42−import Prelude hiding (map)
76+import Prelude hiding (map, mapM, repeat, filter)
77+
78+#include "Instances.hs"
79+#include "inline.hs"
4380
4481-- $setup
4582-- >>> import qualified Streamly.Data.Stream as Stream
83+-- >>> import qualified Streamly.Prelude as IsStream
4684
4785------------------------------------------------------------------------------
4886-- SerialT
@@ -82,3 +120,146 @@ serial = (<>)
82120{-# INLINE map #-}
83121map :: Monad m => (a -> b) -> SerialT m a -> SerialT m b
84122map f = Stream.mapM (return . f)
123+
124+------------------------------------------------------------------------------
125+-- WSerialT
126+------------------------------------------------------------------------------
127+
128+-- | For 'WSerialT' streams:
129+--
130+-- @
131+-- (<>) = 'Streamly.Prelude.wSerial' -- 'Semigroup'
132+-- (>>=) = flip . 'Streamly.Prelude.concatMapWith' 'Streamly.Prelude.wSerial' -- 'Monad'
133+-- @
134+--
135+-- Note that '<>' is associative only if we disregard the ordering of elements
136+-- in the resulting stream.
137+--
138+-- A single 'Monad' bind behaves like a @for@ loop:
139+--
140+-- >>> :{
141+-- IsStream.toList $ IsStream.fromWSerial $ do
142+-- x <- IsStream.fromList [1,2] -- foreach x in stream
143+-- return x
144+-- :}
145+-- [1,2]
146+--
147+-- Nested monad binds behave like interleaved nested @for@ loops:
148+--
149+-- >>> :{
150+-- IsStream.toList $ IsStream.fromWSerial $ do
151+-- x <- IsStream.fromList [1,2] -- foreach x in stream
152+-- y <- IsStream.fromList [3,4] -- foreach y in stream
153+-- return (x, y)
154+-- :}
155+-- [(1,3),(2,3),(1,4),(2,4)]
156+--
157+-- It is a result of interleaving all the nested iterations corresponding to
158+-- element @1@ in the first stream with all the nested iterations of element
159+-- @2@:
160+--
161+-- >>> import Streamly.Prelude (wSerial)
162+-- >>> IsStream.toList $ IsStream.fromList [(1,3),(1,4)] `IsStream.wSerial` IsStream.fromList [(2,3),(2,4)]
163+-- [(1,3),(2,3),(1,4),(2,4)]
164+--
165+-- The @W@ in the name stands for @wide@ or breadth wise scheduling in
166+-- contrast to the depth wise scheduling behavior of 'Stream'.
167+--
168+-- /Since: 0.2.0 ("Streamly")/
169+--
170+-- @since 0.8.0
171+newtype WSerialT m a = WSerialT {getWSerialT :: K.Stream m a}
172+ deriving (MonadTrans)
173+
174+-- | An interleaving serial IO stream of elements of type @a@. See 'WSerialT'
175+-- documentation for more details.
176+--
177+-- /Since: 0.2.0 ("Streamly")/
178+--
179+-- @since 0.8.0
180+type WSerial = WSerialT IO
181+
182+{-# INLINE consMWSerial #-}
183+{-# SPECIALIZE consMWSerial :: IO a -> WSerialT IO a -> WSerialT IO a #-}
184+consMWSerial :: Monad m => m a -> WSerialT m a -> WSerialT m a
185+consMWSerial m (WSerialT ms) = WSerialT $ K.consM m ms
186+
187+------------------------------------------------------------------------------
188+-- Semigroup
189+------------------------------------------------------------------------------
190+
191+infixr 6 `wSerial`
192+
193+-- | Interleaves two streams, yielding one element from each stream
194+-- alternately. When one stream stops the rest of the other stream is used in
195+-- the output stream.
196+--
197+-- This gives exponential priority to earlier streams than the ones joining
198+-- later. Because of exponential weighting it can be used with 'concatMapWith'.
199+--
200+-- /Not fused/
201+
202+-- NOTE:
203+--
204+-- Note that evaluation of @a \`wSerial` b \`wSerial` c@ does not interleave
205+-- @a@, @b@ and @c@ with equal priority. This expression is equivalent to @a
206+-- \`wSerial` (b \`wSerial` c)@, therefore, it fairly interleaves @a@ with the
207+-- result of @b \`wSerial` c@. For example, @Stream.fromList [1,2] \`wSerial`
208+-- Stream.fromList [3,4] \`wSerial` Stream.fromList [5,6]@ would result in
209+-- [1,3,2,5,4,6]. In other words, the leftmost stream gets the same scheduling
210+-- priority as the rest of the streams taken together. The same is true for
211+-- each subexpression on the right.
212+--
213+{-# INLINE wSerial #-}
214+wSerial :: WSerialT m a -> WSerialT m a -> WSerialT m a
215+wSerial (WSerialT m1) (WSerialT m2) = WSerialT $ K.interleave m1 m2
216+
217+{-# INLINE wSerialFst #-}
218+wSerialFst :: WSerialT m a -> WSerialT m a -> WSerialT m a
219+wSerialFst (WSerialT m1) (WSerialT m2) = WSerialT $ K.interleaveFst m1 m2
220+
221+{-# INLINE wSerialMin #-}
222+wSerialMin :: WSerialT m a -> WSerialT m a -> WSerialT m a
223+wSerialMin (WSerialT m1) (WSerialT m2) = WSerialT $ K.interleaveMin m1 m2
224+
225+instance Semigroup (WSerialT m a) where
226+ (<>) = wSerial
227+
228+------------------------------------------------------------------------------
229+-- Monoid
230+------------------------------------------------------------------------------
231+
232+instance Monoid (WSerialT m a) where
233+ mempty = WSerialT K.nil
234+ mappend = (<>)
235+
236+{-# INLINE apWSerial #-}
237+apWSerial :: Monad m => WSerialT m (a -> b) -> WSerialT m a -> WSerialT m b
238+apWSerial (WSerialT m1) (WSerialT m2) =
239+ let f x1 = K.concatMapWith K.interleave (pure . x1) m2
240+ in WSerialT $ K.concatMapWith K.interleave f m1
241+
242+instance Monad m => Applicative (WSerialT m) where
243+ {-# INLINE pure #-}
244+ pure = WSerialT . K.fromPure
245+ {-# INLINE (<*>) #-}
246+ (<*>) = apWSerial
247+
248+------------------------------------------------------------------------------
249+-- Monad
250+------------------------------------------------------------------------------
251+
252+instance Monad m => Monad (WSerialT m) where
253+ return = pure
254+ {-# INLINE (>>=) #-}
255+ (>>=) (WSerialT m) f = WSerialT $ K.bindWith K.interleave m (getWSerialT . f)
256+
257+------------------------------------------------------------------------------
258+-- Other instances
259+------------------------------------------------------------------------------
260+
261+MONAD_COMMON_INSTANCES(WSerialT,)
262+LIST_INSTANCES(WSerialT)
263+NFDATA1_INSTANCE(WSerialT)
264+FOLDABLE_INSTANCE(WSerialT)
265+TRAVERSABLE_INSTANCE(WSerialT)
src/Streamly/Internal/Data/Stream/WSerial.hsdeleted−205
@@ -1,205 +0,0 @@
1−{-# LANGUAGE UndecidableInstances #-}
2−
3−-- |
4−-- Module : Streamly.Internal.Data.Stream.WSerial
5−-- Copyright : (c) 2017 Composewell Technologies
6−--
7−-- License : BSD3
8−-- Maintainer : streamly@composewell.com
9−-- Stability : experimental
10−-- Portability : GHC
11−--
12−-- To run examples in this module:
13−--
14−-- >>> import qualified Streamly.Prelude as Stream
15−--
16−module Streamly.Internal.Data.Stream.WSerial
17− (
18− -- * Serial interleaving stream
19− WSerialT(..)
20− , WSerial
21− , wSerial
22− , wSerialFst
23− , wSerialMin
24− , consMWSerial
25− )
26−where
27−
28−import Control.Applicative (liftA2)
29−import Control.DeepSeq (NFData(..))
30−import Control.DeepSeq (NFData1(..))
31−import Control.Monad.Base (MonadBase(..), liftBaseDefault)
32−import Control.Monad.Catch (MonadThrow, throwM)
33−import Control.Monad.IO.Class (MonadIO(..))
34−import Control.Monad.Reader.Class (MonadReader(..))
35−import Control.Monad.State.Class (MonadState(..))
36−import Control.Monad.Trans.Class (MonadTrans(lift))
37−import Data.Foldable (Foldable(foldl'), fold)
38−import Data.Functor.Identity (Identity(..), runIdentity)
39−import Data.Maybe (fromMaybe)
40−import Data.Semigroup (Endo(..))
41−import GHC.Exts (IsList(..), IsString(..), oneShot)
42−import Text.Read
43− ( Lexeme(Ident), lexP, parens, prec, readPrec, readListPrec
44− , readListPrecDefault)
45−import Streamly.Internal.BaseCompat ((#.))
46−import Streamly.Internal.Data.Maybe.Strict (Maybe'(..), toMaybe)
47−import Streamly.Internal.Data.Stream.StreamK.Type (Stream)
48−
49−import qualified Streamly.Internal.Data.Stream.Common as P
50−import qualified Streamly.Internal.Data.Stream.StreamD as D
51− (fromStreamK, toStreamK, mapM)
52−import qualified Streamly.Internal.Data.Stream.StreamK.Type as K
53− (cons, consM, nil, concatMapWith, fromPure, bindWith
54− , withLocal, interleave, interleaveFst, interleaveMin)
55−
56−import Prelude hiding (map, mapM, repeat, filter)
57−
58−#include "Instances.hs"
59−#include "inline.hs"
60−
61−-- $setup
62−-- >>> import qualified Streamly.Prelude as Stream
63−
64−------------------------------------------------------------------------------
65−-- WSerialT
66−------------------------------------------------------------------------------
67−
68−-- | For 'WSerialT' streams:
69−--
70−-- @
71−-- (<>) = 'Streamly.Prelude.wSerial' -- 'Semigroup'
72−-- (>>=) = flip . 'Streamly.Prelude.concatMapWith' 'Streamly.Prelude.wSerial' -- 'Monad'
73−-- @
74−--
75−-- Note that '<>' is associative only if we disregard the ordering of elements
76−-- in the resulting stream.
77−--
78−-- A single 'Monad' bind behaves like a @for@ loop:
79−--
80−-- >>> :{
81−-- Stream.toList $ Stream.fromWSerial $ do
82−-- x <- Stream.fromList [1,2] -- foreach x in stream
83−-- return x
84−-- :}
85−-- [1,2]
86−--
87−-- Nested monad binds behave like interleaved nested @for@ loops:
88−--
89−-- >>> :{
90−-- Stream.toList $ Stream.fromWSerial $ do
91−-- x <- Stream.fromList [1,2] -- foreach x in stream
92−-- y <- Stream.fromList [3,4] -- foreach y in stream
93−-- return (x, y)
94−-- :}
95−-- [(1,3),(2,3),(1,4),(2,4)]
96−--
97−-- It is a result of interleaving all the nested iterations corresponding to
98−-- element @1@ in the first stream with all the nested iterations of element
99−-- @2@:
100−--
101−-- >>> import Streamly.Prelude (wSerial)
102−-- >>> Stream.toList $ Stream.fromList [(1,3),(1,4)] `Stream.wSerial` Stream.fromList [(2,3),(2,4)]
103−-- [(1,3),(2,3),(1,4),(2,4)]
104−--
105−-- The @W@ in the name stands for @wide@ or breadth wise scheduling in
106−-- contrast to the depth wise scheduling behavior of 'Stream'.
107−--
108−-- /Since: 0.2.0 ("Streamly")/
109−--
110−-- @since 0.8.0
111−newtype WSerialT m a = WSerialT {getWSerialT :: Stream m a}
112− deriving (MonadTrans)
113−
114−-- | An interleaving serial IO stream of elements of type @a@. See 'WSerialT'
115−-- documentation for more details.
116−--
117−-- /Since: 0.2.0 ("Streamly")/
118−--
119−-- @since 0.8.0
120−type WSerial = WSerialT IO
121−
122−{-# INLINE consMWSerial #-}
123−{-# SPECIALIZE consMWSerial :: IO a -> WSerialT IO a -> WSerialT IO a #-}
124−consMWSerial :: Monad m => m a -> WSerialT m a -> WSerialT m a
125−consMWSerial m (WSerialT ms) = WSerialT $ K.consM m ms
126−
127−------------------------------------------------------------------------------
128−-- Semigroup
129−------------------------------------------------------------------------------
130−
131−infixr 6 `wSerial`
132−
133−-- | Interleaves two streams, yielding one element from each stream
134−-- alternately. When one stream stops the rest of the other stream is used in
135−-- the output stream.
136−--
137−-- This gives exponential priority to earlier streams than the ones joining
138−-- later. Because of exponential weighting it can be used with 'concatMapWith'.
139−--
140−-- /Not fused/
141−
142−-- NOTE:
143−--
144−-- Note that evaluation of @a \`wSerial` b \`wSerial` c@ does not interleave
145−-- @a@, @b@ and @c@ with equal priority. This expression is equivalent to @a
146−-- \`wSerial` (b \`wSerial` c)@, therefore, it fairly interleaves @a@ with the
147−-- result of @b \`wSerial` c@. For example, @Stream.fromList [1,2] \`wSerial`
148−-- Stream.fromList [3,4] \`wSerial` Stream.fromList [5,6]@ would result in
149−-- [1,3,2,5,4,6]. In other words, the leftmost stream gets the same scheduling
150−-- priority as the rest of the streams taken together. The same is true for
151−-- each subexpression on the right.
152−--
153−{-# INLINE wSerial #-}
154−wSerial :: WSerialT m a -> WSerialT m a -> WSerialT m a
155−wSerial (WSerialT m1) (WSerialT m2) = WSerialT $ K.interleave m1 m2
156−
157−{-# INLINE wSerialFst #-}
158−wSerialFst :: WSerialT m a -> WSerialT m a -> WSerialT m a
159−wSerialFst (WSerialT m1) (WSerialT m2) = WSerialT $ K.interleaveFst m1 m2
160−
161−{-# INLINE wSerialMin #-}
162−wSerialMin :: WSerialT m a -> WSerialT m a -> WSerialT m a
163−wSerialMin (WSerialT m1) (WSerialT m2) = WSerialT $ K.interleaveMin m1 m2
164−
165−instance Semigroup (WSerialT m a) where
166− (<>) = wSerial
167−
168−------------------------------------------------------------------------------
169−-- Monoid
170−------------------------------------------------------------------------------
171−
172−instance Monoid (WSerialT m a) where
173− mempty = WSerialT K.nil
174− mappend = (<>)
175−
176−{-# INLINE apWSerial #-}
177−apWSerial :: Monad m => WSerialT m (a -> b) -> WSerialT m a -> WSerialT m b
178−apWSerial (WSerialT m1) (WSerialT m2) =
179− let f x1 = K.concatMapWith K.interleave (pure . x1) m2
180− in WSerialT $ K.concatMapWith K.interleave f m1
181−
182−instance Monad m => Applicative (WSerialT m) where
183− {-# INLINE pure #-}
184− pure = WSerialT . K.fromPure
185− {-# INLINE (<*>) #-}
186− (<*>) = apWSerial
187−
188−------------------------------------------------------------------------------
189−-- Monad
190−------------------------------------------------------------------------------
191−
192−instance Monad m => Monad (WSerialT m) where
193− return = pure
194− {-# INLINE (>>=) #-}
195− (>>=) (WSerialT m) f = WSerialT $ K.bindWith K.interleave m (getWSerialT . f)
196−
197−------------------------------------------------------------------------------
198−-- Other instances
199−------------------------------------------------------------------------------
200−
201−MONAD_COMMON_INSTANCES(WSerialT,)
202−LIST_INSTANCES(WSerialT)
203−NFDATA1_INSTANCE(WSerialT)
204−FOLDABLE_INSTANCE(WSerialT)
205−TRAVERSABLE_INSTANCE(WSerialT)
streamly.cabal−1
@@ -344,7 +344,6 @@ library
344344 , Streamly.Internal.Data.Stream.SVar.Eliminate
345345
346346 , Streamly.Internal.Data.Stream.Serial
347− , Streamly.Internal.Data.Stream.WSerial
348347 , Streamly.Internal.Data.Stream.Async
349348 , Streamly.Internal.Data.Stream.Parallel
350349 , Streamly.Internal.Data.Stream.Channel.Types
test/Streamly/Test/Prelude/WSerial.hs+2−2
@@ -15,7 +15,7 @@ import Test.Hspec.QuickCheck
1515import Test.QuickCheck.Monadic (monadicIO, run)
1616import Test.Hspec as H
1717
18−import qualified Streamly.Internal.Data.Stream.WSerial as WSerial
18+import qualified Streamly.Internal.Data.Stream.Serial as Serial
1919
2020import Streamly.Prelude hiding (repeat)
2121import qualified Streamly.Prelude as S
@@ -64,7 +64,7 @@ wSerialMinLengthProp =
6464
6565 finiteStream len = S.take len $ S.repeat (1 :: Int)
6666 infiniteStream = S.repeat 1
67− combined len = infiniteStream `WSerial.wSerialMin` finiteStream len
67+ combined len = infiniteStream `Serial.wSerialMin` finiteStream len
6868
6969moduleName :: String
7070moduleName = "Prelude.WSerial"