on master help sign in
Rearrange, update docs of enumeration functions
commitde06529fef6eb2d9e8cbff38a56e4d85b7b1b428 authorHarendra Kumar <harendra@composewell.com> dateTue 23 Mar 2021, 02:50 (6 years ago) parent82c177a
1 file changed+47−40
src/Streamly/Internal/Data/Stream/StreamD/Generate.hs+47−40
src/Streamly/Internal/Data/Stream/StreamD/Generate.hs+47−40
@@ -175,20 +175,38 @@ replicate :: Monad m => Int -> a -> Stream m a
175175replicate n x = replicateM n (return x)
176176
177177------------------------------------------------------------------------------
178−-- Enumeration
178+-- Enumeration of Num
179179------------------------------------------------------------------------------
180180
181−-- This would not work properly for floats, therefore we put an Integral
182−-- constraint.
183−-- | Can be used to enumerate unbounded integrals. This does not check for
184−-- overflow or underflow for bounded integrals.
185−{-# INLINE_NORMAL enumerateFromStepIntegral #-}
186−enumerateFromStepIntegral :: (Integral a, Monad m) => a -> a -> Stream m a
187−enumerateFromStepIntegral from stride =
188− from `seq` stride `seq` Stream step from
181+-- | For floating point numbers if the increment is less than the precision then
182+-- it just gets lost. Therefore we cannot always increment it correctly by just
183+-- repeated addition.
184+-- 9007199254740992 + 1 + 1 :: Double => 9.007199254740992e15
185+-- 9007199254740992 + 2 :: Double => 9.007199254740994e15
186+--
187+-- Instead we accumulate the increment counter and compute the increment
188+-- every time before adding it to the starting number.
189+--
190+-- This works for Integrals as well as floating point numbers, but
191+-- enumerateFromStepIntegral is faster for integrals.
192+{-# INLINE_NORMAL enumerateFromStepNum #-}
193+enumerateFromStepNum :: (Monad m, Num a) => a -> a -> Stream m a
194+enumerateFromStepNum from stride = Stream step 0
189195 where
190− {-# INLINE_LATE step #-}
191− step _ !x = return $ Yield x $! (x + stride)
196+ {-# INLINE_LATE step #-}
197+ step _ !i = return $ (Yield $! (from + i * stride)) $! (i + 1)
198+
199+{-# INLINE_NORMAL numFrom #-}
200+numFrom :: (Monad m, Num a) => a -> Stream m a
201+numFrom from = enumerateFromStepNum from 1
202+
203+{-# INLINE_NORMAL numFromThen #-}
204+numFromThen :: (Monad m, Num a) => a -> a -> Stream m a
205+numFromThen from next = enumerateFromStepNum from (next - from)
206+
207+------------------------------------------------------------------------------
208+-- Enumeration of Integrals
209+------------------------------------------------------------------------------
192210
193211data EnumState a = EnumInit | EnumYield a a a | EnumStop
194212
@@ -258,8 +276,19 @@ enumerateFromThenIntegral from next =
258276 then enumerateFromThenToIntegralUp from next maxBound
259277 else enumerateFromThenToIntegralDn from next minBound
260278
261−-- We are assuming that "to" is constrained by the type to be within
262−-- max/min bounds.
279+-- | Can be used to enumerate unbounded integrals. This does not check for
280+-- overflow or underflow for bounded integrals.
281+--
282+{-# INLINE_NORMAL enumerateFromStepIntegral #-}
283+enumerateFromStepIntegral :: (Integral a, Monad m) => a -> a -> Stream m a
284+enumerateFromStepIntegral from stride =
285+ from `seq` stride `seq` Stream step from
286+ where
287+ {-# INLINE_LATE step #-}
288+ step _ !x = return $ Yield x $! (x + stride)
289+
290+-- | Enumerate upwards from @from@ to @to@. We are assuming that "to" is
291+-- constrained by the type to be within max/min bounds.
263292{-# INLINE enumerateFromToIntegral #-}
264293enumerateFromToIntegral :: (Monad m, Integral a) => a -> a -> Stream m a
265294enumerateFromToIntegral from to =
@@ -269,7 +298,11 @@ enumerateFromToIntegral from to =
269298enumerateFromIntegral :: (Monad m, Integral a, Bounded a) => a -> Stream m a
270299enumerateFromIntegral from = enumerateFromToIntegral from maxBound
271300
272−-- We cannot write a general function for Num. The only way to write code
301+------------------------------------------------------------------------------
302+-- Enumeration of Fractionals
303+------------------------------------------------------------------------------
304+
305+-- | We cannot write a general function for Num. The only way to write code
273306-- portable between the two is to use a 'Real' constraint and convert between
274307-- Fractional and Integral using fromRational which is horribly slow.
275308{-# INLINE_NORMAL enumerateFromToFractional #-}
@@ -290,32 +323,6 @@ enumerateFromThenToFractional from next to =
290323 predicate | next >= from = (<= to + mid)
291324 | otherwise = (>= to + mid)
292325
293−-- For floating point numbers if the increment is less than the precision then
294−-- it just gets lost. Therefore we cannot always increment it correctly by just
295−-- repeated addition.
296−-- 9007199254740992 + 1 + 1 :: Double => 9.007199254740992e15
297−-- 9007199254740992 + 2 :: Double => 9.007199254740994e15
298−
299−-- Instead we accumulate the increment counter and compute the increment
300−-- every time before adding it to the starting number.
301−--
302−-- This works for Integrals as well as floating point numbers, but
303−-- enumerateFromStepIntegral is faster for integrals.
304−{-# INLINE_NORMAL enumerateFromStepNum #-}
305−enumerateFromStepNum :: (Monad m, Num a) => a -> a -> Stream m a
306−enumerateFromStepNum from stride = Stream step 0
307− where
308− {-# INLINE_LATE step #-}
309− step _ !i = return $ (Yield $! (from + i * stride)) $! (i + 1)
310−
311−{-# INLINE_NORMAL numFrom #-}
312−numFrom :: (Monad m, Num a) => a -> Stream m a
313−numFrom from = enumerateFromStepNum from 1
314−
315−{-# INLINE_NORMAL numFromThen #-}
316−numFromThen :: (Monad m, Num a) => a -> a -> Stream m a
317−numFromThen from next = enumerateFromStepNum from (next - from)
318−
319326------------------------------------------------------------------------------
320327-- Time Enumeration
321328------------------------------------------------------------------------------