@@ -75,65 +75,78 @@
75module Streamly.Internal.Data.Unfold
75module Streamly.Internal.Data.Unfold
77 -- * Unfold Type
77 -- * Unfold Type
80− -- * Operations on Input
81+ -- * Folding
92− -- * Operations on Output
96 -- * Unfolds
85 -- * Unfolds
97− , fromStream
86+ -- One to one correspondence with
98− , fromStreamK
87+ -- "Streamly.Internal.Data.Stream.IsStream.Generate"
99− , fromStreamD
88+ -- ** Primitives
103 , singletonM
89 , singletonM
104 , singleton
90 , singleton
105 , identity
91 , identity
107− , unfoldrM
93+ , yield
109− , fromList
95+ , consM
115− -- ** Specialized Generation
97+ -- ** Generators
116 -- | Generate a monadic stream from a seed.
98 -- | Generate a monadic stream from a seed.
117− , replicateM
99+ , unfoldrM
118 , repeatM
100 , repeatM
119− , iterateM
101+ , replicateM
120 , fromIndicesM
102 , fromIndicesM
122 -- ** Enumerations
105 -- ** Enumerations
106+ -- *** Enumerate Num
107+ , enumerateFromStepNum
110+ -- *** Enumerate Integral
123 , enumerateFromStepIntegral
111 , enumerateFromStepIntegral
124 , enumerateFromToIntegral
112 , enumerateFromToIntegral
125 , enumerateFromIntegral
113 , enumerateFromIntegral
127− , enumerateFromStepNum
115+ -- *** Enumerate Fractional
128− , numFrom
116+ -- | Use 'Num' enumerations for fractional or floating point number
129 , enumerateFromToFractional
118 , enumerateFromToFractional
131− -- * Transformations
120+ -- ** From Containers
132+ -- ** Mapping on Input
144+ -- ** Mapping on Output
134 , mapMWithInput
147 , mapMWithInput
136− -- * Filtering
149+ -- ** Filtering
137 , takeWhileM
150 , takeWhileM
138 , takeWhile
151 , takeWhile
@@ -143,18 +156,21 @@ module Streamly.Internal.Data.Unfold
143 , dropWhile
156 , dropWhile
144 , dropWhileM
157 , dropWhileM
146− -- * Zipping
159+ -- ** Zipping
147 , zipWithM
160 , zipWithM
148 , zipWith
161 , zipWith
149 , teeZipWith
162 , teeZipWith
151− -- * Nesting
164+ -- ** Nesting
152 , ConcatState (..)
167 , ConcatState (..)
154 , concatMapM
169 , concatMapM
155 , outerProduct
171 , outerProduct
157− -- * Exceptions
173+ -- ** Exceptions
158 , gbracket_
174 , gbracket_
159 , gbracket
175 , gbracket
@@ -206,7 +222,7 @@ import Prelude
206-- | Map an action on the input argument of the 'Unfold'.
222-- | Map an action on the input argument of the 'Unfold'.
209−-- lmapM f = many (singletonM f)
225+-- lmapM f = Unfold.many (Unfold.singletonM f)
212-- /Pre-release/
228-- /Pre-release/
@@ -214,47 +230,54 @@ import Prelude
214lmapM :: Monad m => (a -> m c) -> Unfold m c b -> Unfold m a b
230lmapM :: Monad m => (a -> m c) -> Unfold m c b -> Unfold m a b
215lmapM f (Unfold ustep uinject) = Unfold ustep (f >=> uinject)
231lmapM f (Unfold ustep uinject) = Unfold ustep (f >=> uinject)
217−-- XXX change the signature to the following?
218−-- supply :: a -> Unfold m a b -> Unfold m Void b
220-- | Supply the seed to an unfold closing the input end of the unfold.
233-- | Supply the seed to an unfold closing the input end of the unfold.
236+-- supply a = Unfold.lmap (Prelude.const a)
222-- /Pre-release/
239-- /Pre-release/
224{-# INLINE_NORMAL supply #-}
241{-# INLINE_NORMAL supply #-}
225−supply :: Unfold m a b -> a -> Unfold m Void b
242+supply :: a -> Unfold m a b -> Unfold m Void b
226−supply unf a = lmap (Prelude.const a) unf
243+supply a = lmap (Prelude.const a)
228−-- XXX change the signature to the following?
229−-- supplyFirst :: a -> Unfold m (a, b) c -> Unfold m b c
231-- | Supply the first component of the tuple to an unfold that accepts a tuple
245-- | Supply the first component of the tuple to an unfold that accepts a tuple
232-- as a seed resulting in a fold that accepts the second component of the tuple
246-- as a seed resulting in a fold that accepts the second component of the tuple
233-- as a seed.
247-- as a seed.
250+-- supplyFirst a = Unfold.lmap (a, )
235-- /Pre-release/
253-- /Pre-release/
237{-# INLINE_NORMAL supplyFirst #-}
255{-# INLINE_NORMAL supplyFirst #-}
238−supplyFirst :: Unfold m (a, b) c -> a -> Unfold m b c
256+supplyFirst :: a -> Unfold m (a, b) c -> Unfold m b c
239−supplyFirst unf a = lmap (a, ) unf
257+supplyFirst a = lmap (a, )
241−-- XXX change the signature to the following?
242−-- supplySecond :: b -> Unfold m (a, b) c -> Unfold m a c
244-- | Supply the second component of the tuple to an unfold that accepts a tuple
259-- | Supply the second component of the tuple to an unfold that accepts a tuple
245-- as a seed resulting in a fold that accepts the first component of the tuple
260-- as a seed resulting in a fold that accepts the first component of the tuple
246-- as a seed.
261-- as a seed.
264+-- supplySecond b = Unfold.lmap (, b)
248-- /Pre-release/
267-- /Pre-release/
250{-# INLINE_NORMAL supplySecond #-}
269{-# INLINE_NORMAL supplySecond #-}
251−supplySecond :: Unfold m (a, b) c -> b -> Unfold m a c
270+supplySecond :: b -> Unfold m (a, b) c -> Unfold m a c
252−supplySecond unf b = lmap (, b) unf
271+supplySecond b = lmap (, b)
254-- | Convert an 'Unfold' into an unfold accepting a tuple as an argument,
273-- | Convert an 'Unfold' into an unfold accepting a tuple as an argument,
255-- using the argument of the original fold as the second element of tuple and
274-- using the argument of the original fold as the second element of tuple and
256-- discarding the first element of the tuple.
275-- discarding the first element of the tuple.
278+-- discardFirst = Unfold.lmap snd
258-- /Pre-release/
281-- /Pre-release/
260{-# INLINE_NORMAL discardFirst #-}
283{-# INLINE_NORMAL discardFirst #-}
@@ -265,6 +288,10 @@ discardFirst = lmap snd
265-- using the argument of the original fold as the first element of tuple and
288-- using the argument of the original fold as the first element of tuple and
266-- discarding the second element of the tuple.
289-- discarding the second element of the tuple.
292+-- discardSecond = Unfold.lmap fst
268-- /Pre-release/
295-- /Pre-release/
270{-# INLINE_NORMAL discardSecond #-}
297{-# INLINE_NORMAL discardSecond #-}
@@ -274,6 +301,10 @@ discardSecond = lmap fst
274-- | Convert an 'Unfold' that accepts a tuple as an argument into an unfold
301-- | Convert an 'Unfold' that accepts a tuple as an argument into an unfold
275-- that accepts a tuple with elements swapped.
302-- that accepts a tuple with elements swapped.
305+-- swap = Unfold.lmap Tuple.swap
277-- /Pre-release/
308-- /Pre-release/
279{-# INLINE_NORMAL swap #-}
310{-# INLINE_NORMAL swap #-}
@@ -393,7 +424,8 @@ nilM f = Unfold step return
393 {-# INLINE_LATE step #-}
424 {-# INLINE_LATE step #-}
394 step x = f x >> return Stop
425 step x = f x >> return Stop
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.
398-- /Pre-release/
430-- /Pre-release/
399{-# INLINE_NORMAL consM #-}
431{-# INLINE_NORMAL consM #-}
@@ -414,17 +446,6 @@ consM action unf = Unfold step inject
414 Skip s -> return $ Skip (Right (Stream step1 s))
446 Skip s -> return $ Skip (Right (Stream step1 s))
415 Stop -> return Stop
447 Stop -> return Stop
417−-- | Lift a monadic effect into an unfold generating a singleton stream.
419−{-# INLINE effect #-}
420−effect :: Monad m => m b -> Unfold m Void b
421−effect eff = Unfold step inject
423− inject _ = return True
424− {-# INLINE_LATE step #-}
425− step True = eff >>= \r -> return $ Yield r False
426− step False = return Stop
428-- | Convert a list of pure values to a 'Stream'
449-- | Convert a list of pure values to a 'Stream'
429{-# INLINE_LATE fromList #-}
450{-# INLINE_LATE fromList #-}
430fromList :: Monad m => Unfold m [a] a
451fromList :: Monad m => Unfold m [a] a
@@ -514,6 +535,10 @@ iterateM f = Unfold step id
514-- | @fromIndicesM gen@ generates an infinite stream of values using @gen@
535-- | @fromIndicesM gen@ generates an infinite stream of values using @gen@
515-- starting from the seed.
536-- starting from the seed.
539+-- fromIndicesM f = Unfold.mapM f $ Unfold.enumerateFrom 0
517-- /Pre-release/
542-- /Pre-release/
519{-# INLINE_NORMAL fromIndicesM #-}
544{-# INLINE_NORMAL fromIndicesM #-}
@@ -655,9 +680,37 @@ dropWhileM f (Unfold step inject) = Unfold step' inject'
655dropWhile :: Monad m => (b -> Bool) -> Unfold m a b -> Unfold m a b
680dropWhile :: Monad m => (b -> Bool) -> Unfold m a b -> Unfold m a b
656dropWhile f = dropWhileM (return . f)
681dropWhile f = dropWhileM (return . f)
658−-------------------------------------------------------------------------------
683+------------------------------------------------------------------------------
684+-- Enumeration of Num
685+------------------------------------------------------------------------------
687+-- | Generate an infinite stream starting from a starting value with increments
688+-- of the given stride. The implementation is numerically stable for floating
691+-- Note 'enumerateFromStepIntegral' is faster for integrals.
695+{-# INLINE enumerateFromStepNum #-}
696+enumerateFromStepNum :: (Monad m, Num a) => a -> Unfold m a a
697+enumerateFromStepNum stride = Unfold step return
699+ -- XXX This is numerically unstable.
700+ {-# INLINE_LATE step #-}
701+ step !s = return $ (Yield $! s) $! (s + stride)
703+-- | @numFrom = enumerateFromStepNum 1@
707+{-# INLINE_NORMAL numFrom #-}
708+numFrom :: (Monad m, Num a) => Unfold m a a
709+numFrom = enumerateFromStepNum 1
711+------------------------------------------------------------------------------
659−-- Enumeration
712+-- Enumeration of Integrals
660−-------------------------------------------------------------------------------
713+------------------------------------------------------------------------------
662-- | Can be used to enumerate unbounded integrals. This does not check for
715-- | Can be used to enumerate unbounded integrals. This does not check for
663-- overflow or underflow for bounded integrals.
716-- overflow or underflow for bounded integrals.
@@ -674,34 +727,20 @@ enumerateFromStepIntegral = Unfold step inject
674{-# INLINE enumerateFromToIntegral #-}
727{-# INLINE enumerateFromToIntegral #-}
675enumerateFromToIntegral :: (Monad m, Integral a) => a -> Unfold m a a
728enumerateFromToIntegral :: (Monad m, Integral a) => a -> Unfold m a a
676enumerateFromToIntegral to =
729enumerateFromToIntegral to =
677− takeWhile (<= to) $ supplySecond enumerateFromStepIntegral 1
730+ takeWhile (<= to) $ supplySecond 1 enumerateFromStepIntegral
679{-# INLINE enumerateFromIntegral #-}
732{-# INLINE enumerateFromIntegral #-}
680enumerateFromIntegral :: (Monad m, Integral a, Bounded a) => Unfold m a a
733enumerateFromIntegral :: (Monad m, Integral a, Bounded a) => Unfold m a a
681enumerateFromIntegral = enumerateFromToIntegral maxBound
734enumerateFromIntegral = enumerateFromToIntegral maxBound
683−-- | Generate an infinite stream starting from the seed with increments of the
736+------------------------------------------------------------------------------
684−-- given stride.
737+-- Enumeration of Fractionals
685−--
738+------------------------------------------------------------------------------
688−{-# INLINE enumerateFromStepNum #-}
689−enumerateFromStepNum :: (Monad m, Num a) => a -> Unfold m a a
690−enumerateFromStepNum stride = Unfold step return
692− {-# INLINE_LATE step #-}
693− step !s = return $ (Yield $! s) $! (s + stride)
695−-- | @numFrom = enumerateFromStepNum 1@
699−{-# INLINE_NORMAL numFrom #-}
700−numFrom :: (Monad m, Num a) => Unfold m a a
701−numFrom = enumerateFromStepNum 1
703-- | /Internal/
740-- | /Internal/
742+-- > enumerateFromToFractional to = takeWhile (<= to + 1 / 2) $ enumerateFromStepNum 1
705{-# INLINE_NORMAL enumerateFromToFractional #-}
744{-# INLINE_NORMAL enumerateFromToFractional #-}
706enumerateFromToFractional :: (Monad m, Fractional a, Ord a) => a -> Unfold m a a
745enumerateFromToFractional :: (Monad m, Fractional a, Ord a) => a -> Unfold m a a
707enumerateFromToFractional to =
746enumerateFromToFractional to =
@@ -862,6 +901,7 @@ data OuterProductState s1 s2 sy x y =
862 OuterProductOuter s1 y | OuterProductInner s1 sy s2 x
901 OuterProductOuter s1 y | OuterProductInner s1 sy s2 x
864-- XXX this can be written in terms of "cross".
903-- XXX this can be written in terms of "cross".
904+-- XXX Remove this in favor of cross?
866-- | Create an outer product (vector product or cartesian product) of the
906-- | Create an outer product (vector product or cartesian product) of the
867-- output streams of two unfolds.
907-- output streams of two unfolds.