@@ -75,65 +75,78 @@
7575module Streamly.Internal.Data.Unfold
7676 (
7777 -- * Unfold Type
78− Unfold
78+ Step(..)
79+ , Unfold
7980
80− -- * Operations on Input
81− , lmap
82− , lmapM
83− , supply
84− , supplyFirst
85− , supplySecond
86− , discardFirst
87− , discardSecond
88− , swap
89− -- coapply
90− -- comonad
91−
92− -- * Operations on Output
81+ -- * Folding
9382 , fold
9483 -- pipe
9584
9685 -- * Unfolds
97− , fromStream
98− , fromStreamK
99− , fromStreamD
100− , nilM
101− , consM
102− , effect
86+ -- One to one correspondence with
87+ -- "Streamly.Internal.Data.Stream.IsStream.Generate"
88+ -- ** Primitives
10389 , singletonM
10490 , singleton
10591 , identity
106− , const
107− , unfoldrM
108−
109− , fromList
110− , fromListM
111−
112− , fromSVar
113− , fromProducer
92+ , yieldM
93+ , yield
94+ , nilM
95+ , consM
11496
115− -- ** Specialized Generation
97+ -- ** Generators
11698 -- | Generate a monadic stream from a seed.
117− , replicateM
99+ , unfoldrM
118100 , repeatM
119− , iterateM
101+ , replicateM
120102 , fromIndicesM
103+ , iterateM
121104
122105 -- ** Enumerations
106+ -- *** Enumerate Num
107+ , enumerateFromStepNum
108+ , numFrom
109+
110+ -- *** Enumerate Integral
123111 , enumerateFromStepIntegral
124112 , enumerateFromToIntegral
125113 , enumerateFromIntegral
126114
127− , enumerateFromStepNum
128− , numFrom
115+ -- *** Enumerate Fractional
116+ -- | Use 'Num' enumerations for fractional or floating point number
117+ -- enumerations.
129118 , enumerateFromToFractional
130119
131− -- * Transformations
120+ -- ** From Containers
121+ , fromList
122+ , fromListM
123+
124+ , fromStream
125+ , fromStreamK
126+ , fromStreamD
127+
128+ , fromSVar
129+ , fromProducer
130+
131+ -- * Combinators
132+ -- ** Mapping on Input
133+ , lmap
134+ , lmapM
135+ , supply
136+ , supplyFirst
137+ , supplySecond
138+ , discardFirst
139+ , discardSecond
140+ , swap
141+ -- coapply
142+ -- comonad
143+
144+ -- ** Mapping on Output
132145 , map
133146 , mapM
134147 , mapMWithInput
135148
136− -- * Filtering
149+ -- ** Filtering
137150 , takeWhileM
138151 , takeWhile
139152 , take
@@ -143,18 +156,21 @@ module Streamly.Internal.Data.Unfold
143156 , dropWhile
144157 , dropWhileM
145158
146− -- * Zipping
159+ -- ** Zipping
147160 , zipWithM
148161 , zipWith
149162 , teeZipWith
150163
151− -- * Nesting
164+ -- ** Nesting
165+ , cross
166+ , apply
152167 , ConcatState (..)
153168 , many
154169 , concatMapM
170+ , bind
155171 , outerProduct
156172
157− -- * Exceptions
173+ -- ** Exceptions
158174 , gbracket_
159175 , gbracket
160176 , before
@@ -206,7 +222,7 @@ import Prelude
206222-- | Map an action on the input argument of the 'Unfold'.
207223--
208224-- @
209−-- lmapM f = many (singletonM f)
225+-- lmapM f = Unfold.many (Unfold.singletonM f)
210226-- @
211227--
212228-- /Pre-release/
@@ -214,47 +230,54 @@ import Prelude
214230lmapM :: Monad m => (a -> m c) -> Unfold m c b -> Unfold m a b
215231lmapM f (Unfold ustep uinject) = Unfold ustep (f >=> uinject)
216232
217−-- XXX change the signature to the following?
218−-- supply :: a -> Unfold m a b -> Unfold m Void b
219−--
220233-- | Supply the seed to an unfold closing the input end of the unfold.
221234--
235+-- @
236+-- supply a = Unfold.lmap (Prelude.const a)
237+-- @
238+--
222239-- /Pre-release/
223240--
224241{-# INLINE_NORMAL supply #-}
225−supply :: Unfold m a b -> a -> Unfold m Void b
226−supply unf a = lmap (Prelude.const a) unf
242+supply :: a -> Unfold m a b -> Unfold m Void b
243+supply a = lmap (Prelude.const a)
227244
228−-- XXX change the signature to the following?
229−-- supplyFirst :: a -> Unfold m (a, b) c -> Unfold m b c
230−--
231245-- | Supply the first component of the tuple to an unfold that accepts a tuple
232246-- as a seed resulting in a fold that accepts the second component of the tuple
233247-- as a seed.
234248--
249+-- @
250+-- supplyFirst a = Unfold.lmap (a, )
251+-- @
252+--
235253-- /Pre-release/
236254--
237255{-# INLINE_NORMAL supplyFirst #-}
238−supplyFirst :: Unfold m (a, b) c -> a -> Unfold m b c
239−supplyFirst unf a = lmap (a, ) unf
256+supplyFirst :: a -> Unfold m (a, b) c -> Unfold m b c
257+supplyFirst a = lmap (a, )
240258
241−-- XXX change the signature to the following?
242−-- supplySecond :: b -> Unfold m (a, b) c -> Unfold m a c
243−--
244259-- | Supply the second component of the tuple to an unfold that accepts a tuple
245260-- as a seed resulting in a fold that accepts the first component of the tuple
246261-- as a seed.
247262--
263+-- @
264+-- supplySecond b = Unfold.lmap (, b)
265+-- @
266+--
248267-- /Pre-release/
249268--
250269{-# INLINE_NORMAL supplySecond #-}
251−supplySecond :: Unfold m (a, b) c -> b -> Unfold m a c
252−supplySecond unf b = lmap (, b) unf
270+supplySecond :: b -> Unfold m (a, b) c -> Unfold m a c
271+supplySecond b = lmap (, b)
253272
254273-- | Convert an 'Unfold' into an unfold accepting a tuple as an argument,
255274-- using the argument of the original fold as the second element of tuple and
256275-- discarding the first element of the tuple.
257276--
277+-- @
278+-- discardFirst = Unfold.lmap snd
279+-- @
280+--
258281-- /Pre-release/
259282--
260283{-# INLINE_NORMAL discardFirst #-}
@@ -265,6 +288,10 @@ discardFirst = lmap snd
265288-- using the argument of the original fold as the first element of tuple and
266289-- discarding the second element of the tuple.
267290--
291+-- @
292+-- discardSecond = Unfold.lmap fst
293+-- @
294+--
268295-- /Pre-release/
269296--
270297{-# INLINE_NORMAL discardSecond #-}
@@ -274,6 +301,10 @@ discardSecond = lmap fst
274301-- | Convert an 'Unfold' that accepts a tuple as an argument into an unfold
275302-- that accepts a tuple with elements swapped.
276303--
304+-- @
305+-- swap = Unfold.lmap Tuple.swap
306+-- @
307+--
277308-- /Pre-release/
278309--
279310{-# INLINE_NORMAL swap #-}
@@ -393,7 +424,8 @@ nilM f = Unfold step return
393424 {-# INLINE_LATE step #-}
394425 step x = f x >> return Stop
395426
396−-- | Prepend a monadic single element generator function to an 'Unfold'.
427+-- | Prepend a monadic single element generator function to an 'Unfold'. The
428+-- same seed is used in the action as well as the unfold.
397429--
398430-- /Pre-release/
399431{-# INLINE_NORMAL consM #-}
@@ -414,17 +446,6 @@ consM action unf = Unfold step inject
414446 Skip s -> return $ Skip (Right (Stream step1 s))
415447 Stop -> return Stop
416448
417−-- | Lift a monadic effect into an unfold generating a singleton stream.
418−--
419−{-# INLINE effect #-}
420−effect :: Monad m => m b -> Unfold m Void b
421−effect eff = Unfold step inject
422− where
423− inject _ = return True
424− {-# INLINE_LATE step #-}
425− step True = eff >>= \r -> return $ Yield r False
426− step False = return Stop
427−
428449-- | Convert a list of pure values to a 'Stream'
429450{-# INLINE_LATE fromList #-}
430451fromList :: Monad m => Unfold m [a] a
@@ -514,6 +535,10 @@ iterateM f = Unfold step id
514535-- | @fromIndicesM gen@ generates an infinite stream of values using @gen@
515536-- starting from the seed.
516537--
538+-- @
539+-- fromIndicesM f = Unfold.mapM f $ Unfold.enumerateFrom 0
540+-- @
541+--
517542-- /Pre-release/
518543--
519544{-# INLINE_NORMAL fromIndicesM #-}
@@ -655,9 +680,37 @@ dropWhileM f (Unfold step inject) = Unfold step' inject'
655680dropWhile :: Monad m => (b -> Bool) -> Unfold m a b -> Unfold m a b
656681dropWhile f = dropWhileM (return . f)
657682
658−-------------------------------------------------------------------------------
659−-- Enumeration
660−-------------------------------------------------------------------------------
683+------------------------------------------------------------------------------
684+-- Enumeration of Num
685+------------------------------------------------------------------------------
686+
687+-- | Generate an infinite stream starting from a starting value with increments
688+-- of the given stride. The implementation is numerically stable for floating
689+-- point values.
690+--
691+-- Note 'enumerateFromStepIntegral' is faster for integrals.
692+--
693+-- /Pre-release/
694+--
695+{-# INLINE enumerateFromStepNum #-}
696+enumerateFromStepNum :: (Monad m, Num a) => a -> Unfold m a a
697+enumerateFromStepNum stride = Unfold step return
698+ where
699+ -- XXX This is numerically unstable.
700+ {-# INLINE_LATE step #-}
701+ step !s = return $ (Yield $! s) $! (s + stride)
702+
703+-- | @numFrom = enumerateFromStepNum 1@
704+--
705+-- /Pre-release/
706+--
707+{-# INLINE_NORMAL numFrom #-}
708+numFrom :: (Monad m, Num a) => Unfold m a a
709+numFrom = enumerateFromStepNum 1
710+
711+------------------------------------------------------------------------------
712+-- Enumeration of Integrals
713+------------------------------------------------------------------------------
661714
662715-- | Can be used to enumerate unbounded integrals. This does not check for
663716-- overflow or underflow for bounded integrals.
@@ -674,34 +727,20 @@ enumerateFromStepIntegral = Unfold step inject
674727{-# INLINE enumerateFromToIntegral #-}
675728enumerateFromToIntegral :: (Monad m, Integral a) => a -> Unfold m a a
676729enumerateFromToIntegral to =
677− takeWhile (<= to) $ supplySecond enumerateFromStepIntegral 1
730+ takeWhile (<= to) $ supplySecond 1 enumerateFromStepIntegral
678731
679732{-# INLINE enumerateFromIntegral #-}
680733enumerateFromIntegral :: (Monad m, Integral a, Bounded a) => Unfold m a a
681734enumerateFromIntegral = enumerateFromToIntegral maxBound
682735
683−-- | Generate an infinite stream starting from the seed with increments of the
684−-- given stride.
685−--
686−-- /Pre-release/
687−--
688−{-# INLINE enumerateFromStepNum #-}
689−enumerateFromStepNum :: (Monad m, Num a) => a -> Unfold m a a
690−enumerateFromStepNum stride = Unfold step return
691− where
692− {-# INLINE_LATE step #-}
693− step !s = return $ (Yield $! s) $! (s + stride)
694−
695−-- | @numFrom = enumerateFromStepNum 1@
696−--
697−-- /Pre-release/
698−--
699−{-# INLINE_NORMAL numFrom #-}
700−numFrom :: (Monad m, Num a) => Unfold m a a
701−numFrom = enumerateFromStepNum 1
736+------------------------------------------------------------------------------
737+-- Enumeration of Fractionals
738+------------------------------------------------------------------------------
702739
703740-- | /Internal/
704741--
742+-- > enumerateFromToFractional to = takeWhile (<= to + 1 / 2) $ enumerateFromStepNum 1
743+--
705744{-# INLINE_NORMAL enumerateFromToFractional #-}
706745enumerateFromToFractional :: (Monad m, Fractional a, Ord a) => a -> Unfold m a a
707746enumerateFromToFractional to =
@@ -862,6 +901,7 @@ data OuterProductState s1 s2 sy x y =
862901 OuterProductOuter s1 y | OuterProductInner s1 sy s2 x
863902
864903-- XXX this can be written in terms of "cross".
904+-- XXX Remove this in favor of cross?
865905--
866906-- | Create an outer product (vector product or cartesian product) of the
867907-- output streams of two unfolds.