@@ -27,20 +27,15 @@ module Streamly.Internal.Data.Unfold.Enumeration
27 , enumerateFromStepNum
27 , enumerateFromStepNum
28 , enumerateFromNum
28 , enumerateFromNum
29 , enumerateFromThenNum
29 , enumerateFromThenNum
31− , enumerateFromThenToNum
33 -- ** Enumerating unbounded 'Integral' Types
31 -- ** Enumerating unbounded 'Integral' Types
34 , enumerateFromStepIntegral
32 , enumerateFromStepIntegral
35 , enumerateFromIntegral
33 , enumerateFromIntegral
36 , enumerateFromThenIntegral
34 , enumerateFromThenIntegral
38− , enumerateFromToStepIntegral
39 , enumerateFromToIntegral
35 , enumerateFromToIntegral
40 , enumerateFromThenToIntegral
36 , enumerateFromThenToIntegral
42 -- ** Enumerating 'Bounded' 'Integral' Types
38 -- ** Enumerating 'Bounded' 'Integral' Types
43− , enumerateFromStepIntegralBounded
44 , enumerateFromIntegralBounded
39 , enumerateFromIntegralBounded
45 , enumerateFromThenIntegralBounded
40 , enumerateFromThenIntegralBounded
46 , enumerateFromToIntegralBounded
41 , enumerateFromToIntegralBounded
@@ -160,61 +155,6 @@ enumerateFromThenNum =
160enumerateFromNum :: (Monad m, Num a) => Unfold m a a
155enumerateFromNum :: (Monad m, Num a) => Unfold m a a
161enumerateFromNum = lmap (\from -> (from, 1)) enumerateFromStepNum
156enumerateFromNum = lmap (\from -> (from, 1)) enumerateFromStepNum
163−-- | Generate a finite stream starting from a from and next values with
164−-- stride of (next-from) up to value. The implementation is numerically
165−-- stable for floating point values.
167−-- Note that 'enumerateFromThenToIntegral' is faster for integrals.
171−{-# INLINE enumerateFromThenToNum #-}
172−enumerateFromThenToNum :: (Monad m, Ord a, Fractional a) =>
173− Unfold m (a, a, a) a
174−enumerateFromThenToNum = Unfold step inject
178− inject (!from, !next, !to) = return (from, next - from, to, 0)
180− {-# INLINE_LATE step #-}
181− step (from, stride, to, !i) = return $
183− then if from <= to then Yield from $! (from, stride, to, i + 1) else Stop
187− if (from + i * stride) <= to + stride / 2
188− then (Yield $! (from + i * stride)) $! (from, stride, to, i + 1)
191− if (from + i * stride) >= to + stride / 2
192− then (Yield $! (from + i * stride)) $! (from, stride, to, i + 1)
195−-- | Generate a finite stream starting from a from till to value.
196−-- stride of value 1 will be used. The implementation is numerically
197−-- stable for floating point values.
199−-- Note that 'enumerateFromToIntegral' is faster for integrals.
203−{-# INLINE enumerateFromToNum #-}
204−enumerateFromToNum :: (Monad m, Ord a, Fractional a) =>
206−enumerateFromToNum = Unfold step inject
210− inject (!from, !to) = return (from, 1, to, 0)
212− {-# INLINE_LATE step #-}
213− step (from, !stride, to, !i) = return $
214− if (from + i * stride) <= to + stride / 2
215− then (Yield $! (from + i * stride)) $! (from, stride, to, i + 1)
218------------------------------------------------------------------------------
158------------------------------------------------------------------------------
219-- Enumeration of Integrals
159-- Enumeration of Integrals
220------------------------------------------------------------------------------
160------------------------------------------------------------------------------
@@ -224,147 +164,91 @@ enumerateFromToNum = Unfold step inject
225-- /Internal/
165-- /Internal/
226{-# INLINE_NORMAL enumerateFromStepIntegral #-}
166{-# INLINE_NORMAL enumerateFromStepIntegral #-}
227−enumerateFromStepIntegral :: (Integral a, Monad m) => Unfold m (a, a) a
167+enumerateFromStepIntegral :: (Monad m, Integral a) => Unfold m (a, a) a
228enumerateFromStepIntegral = Unfold step inject
168enumerateFromStepIntegral = Unfold step inject
230− inject (from, next) = from `seq` next `seq` return (from, next - from)
231− {-# INLINE_LATE step #-}
232− step (x, stride) = return $ Yield x $! (x + stride, stride)
234−-- | Can be used to enumerate unbounded integrals. Starting with value from
235−-- with stride of next-from till value of to.
239−{-# INLINE_NORMAL enumerateFromToStepIntegral #-}
240−enumerateFromToStepIntegral :: (Integral a, Monad m) =>
241− Unfold m (a, a, a) a
242−enumerateFromToStepIntegral = Unfold step inject
244− inject (from, next, to) =
245− from `seq` next `seq` to `seq` return (from, next - from, to)
246− {-# INLINE_LATE step #-}
247− step (x, stride, to) = return $
250− if x <= to then Yield x $! (x, stride, to) else Stop
256− then Yield x $! (x + stride, stride, to)
260− then Yield x $! (x + stride, stride, to)
263−------------------------------------------------------------------------------
172+ inject (from, stride) = from `seq` stride `seq` return (from, stride)
264−-- Enumeration of Bounded Integrals
265−------------------------------------------------------------------------------
267−-- | Can be used to enumerate bounded integrals from starting from with
268−-- stride of (next-from) . This check for overflow or underflow for
269−-- bounded integrals.
273−{-# INLINE_NORMAL enumerateFromStepIntegralBounded #-}
274−enumerateFromStepIntegralBounded ::
275− forall a m. (Integral a, Bounded a, Monad m) =>
277−enumerateFromStepIntegralBounded = Unfold step inject
279− inject (from, next) =
280− from `seq` next `seq` return (from, next - from)
281 {-# INLINE_LATE step #-}
174 {-# INLINE_LATE step #-}
282− step (x, stride) = return $
175+ step (x, stride) = return $ Yield x $! (x + stride, stride)
285− Yield x $! (x, stride)
290− if x <= (maxBound :: a)
291− then Yield x $! (x + stride, stride)
294− if x >= (minBound :: a)
295− then Yield x $! (x + stride, stride)
298−-- | Can be used to enumerate bounded integrals from starting from with
299−-- stride of (next-from) till to value. This check for overflow or underflow
300−-- for bounded integrals.
304−{-# INLINE_NORMAL enumerateFromToStepIntegralBounded #-}
305−enumerateFromToStepIntegralBounded ::
306− forall a m. (Integral a, Bounded a, Monad m) =>
307− Unfold m (a, a, a) a
308−enumerateFromToStepIntegralBounded = Unfold step inject
310− inject (from, next, to) =
311− from `seq` next `seq` to `seq` return (from, next - from, to)
312− {-# INLINE_LATE step #-}
313− step (x, stride, to) = return $
316− if x <= to then Yield x $! (x, stride, to) else Stop
321− if x <= to && x <= (maxBound :: a)
322− then Yield x $! (x + stride, stride, to)
325− if x >= to && x >= (minBound :: a)
326− then Yield x $! (x + stride, stride, to)
329-- Enumerate Unbounded Integrals ----------------------------------------------
177-- Enumerate Unbounded Integrals ----------------------------------------------
330{-# INLINE enumerateFromIntegral #-}
178{-# INLINE enumerateFromIntegral #-}
331enumerateFromIntegral :: (Monad m, Integral a) => Unfold m a a
179enumerateFromIntegral :: (Monad m, Integral a) => Unfold m a a
332−enumerateFromIntegral = lmap (\a -> (a, a + 1)) enumerateFromStepIntegral
180+enumerateFromIntegral = lmap (\from -> (from, 1)) enumerateFromStepIntegral
334{-# INLINE enumerateFromThenIntegral #-}
182{-# INLINE enumerateFromThenIntegral #-}
335enumerateFromThenIntegral :: (Monad m, Integral a ) => Unfold m (a, a) a
183enumerateFromThenIntegral :: (Monad m, Integral a ) => Unfold m (a, a) a
336−enumerateFromThenIntegral = enumerateFromStepIntegral
184+enumerateFromThenIntegral =
185+ lmap (\(from, next) -> (from, next - from)) enumerateFromStepIntegral
338{-# INLINE enumerateFromToIntegral #-}
187{-# INLINE enumerateFromToIntegral #-}
339enumerateFromToIntegral :: (Monad m, Integral a) => Unfold m (a, a) a
188enumerateFromToIntegral :: (Monad m, Integral a) => Unfold m (a, a) a
340−enumerateFromToIntegral = lmap (\(a, c) -> (a, a + 1, c)) enumerateFromToStepIntegral
189+enumerateFromToIntegral =
190+ takeWhileMWithInput (\(_, to) b -> return $ b <= to)
191+ $ lmap (\(from, _) -> (from, 1)) enumerateFromStepIntegral
342{-# INLINE enumerateFromThenToIntegral #-}
193{-# INLINE enumerateFromThenToIntegral #-}
343enumerateFromThenToIntegral :: (Monad m, Integral a) => Unfold m (a, a, a) a
194enumerateFromThenToIntegral :: (Monad m, Integral a) => Unfold m (a, a, a) a
344−enumerateFromThenToIntegral = enumerateFromToStepIntegral
195+enumerateFromThenToIntegral =
196+ takeWhileMWithInput cond $ lmap toFromStep enumerateFromStepIntegral
200+ toFromStep (from, next, _) = (from, next - from)
202+ cond (from, next, to) b =
346-- Enumerate Bounded Integrals ------------------------------------------------
208-- Enumerate Bounded Integrals ------------------------------------------------
347{-# INLINE enumerateFromIntegralBounded #-}
209{-# INLINE enumerateFromIntegralBounded #-}
348−enumerateFromIntegralBounded :: (Monad m, Bounded a, Integral a) =>
210+enumerateFromIntegralBounded :: (Monad m, Integral a, Bounded a) =>
349 Unfold m a a
211 Unfold m a a
350−enumerateFromIntegralBounded =
212+enumerateFromIntegralBounded = supplySecond maxBound enumerateFromToIntegral
351− lmap (\a -> (a, a + 1, maxBound)) enumerateFromToStepIntegralBounded
353{-# INLINE enumerateFromThenIntegralBounded #-}
214{-# INLINE enumerateFromThenIntegralBounded #-}
354−enumerateFromThenIntegralBounded :: (Monad m, Bounded a, Integral a ) =>
215+enumerateFromThenIntegralBounded :: (Monad m, Integral a, Bounded a ) =>
355 Unfold m (a, a) a
216 Unfold m (a, a) a
356−enumerateFromThenIntegralBounded = enumerateFromStepIntegralBounded
217+enumerateFromThenIntegralBounded =
218+ takeWhileMWithInput cond $ lmap toFromStep enumerateFromStepIntegral
222+ toFromStep (from, next) = (from, next - from)
224+ cond (from, next) b =
358{-# INLINE enumerateFromToIntegralBounded #-}
230{-# INLINE enumerateFromToIntegralBounded #-}
359enumerateFromToIntegralBounded :: (Monad m, Integral a, Bounded a) =>
231enumerateFromToIntegralBounded :: (Monad m, Integral a, Bounded a) =>
360 Unfold m (a, a) a
232 Unfold m (a, a) a
361enumerateFromToIntegralBounded =
233enumerateFromToIntegralBounded =
362− lmap (\(a, c) -> (a, a + 1, c)) enumerateFromToStepIntegralBounded
234+ takeWhileMWithInput (\(_, to) b -> return $ b <= to)
235+ $ lmap fst enumerateFromIntegralBounded
364{-# INLINE enumerateFromThenToIntegralBounded #-}
237{-# INLINE enumerateFromThenToIntegralBounded #-}
365enumerateFromThenToIntegralBounded :: (Monad m, Integral a, Bounded a) =>
238enumerateFromThenToIntegralBounded :: (Monad m, Integral a, Bounded a) =>
366 Unfold m (a, a, a) a
239 Unfold m (a, a, a) a
367−enumerateFromThenToIntegralBounded = enumerateFromToStepIntegralBounded
240+enumerateFromThenToIntegralBounded =
241+ takeWhileMWithInput cond $ lmap toFromThen enumerateFromThenIntegralBounded
245+ toFromThen (from, next, _) = (from, next)
247+ cond (from, next, to) b =
369------------------------------------------------------------------------------
253------------------------------------------------------------------------------
370-- Enumeration of Fractionals
254-- Enumeration of Fractionals
@@ -378,23 +262,41 @@ enumerateFromFractional = enumerateFromNum
378enumerateFromThenFractional :: (Monad m, Fractional a) => Unfold m (a, a) a
262enumerateFromThenFractional :: (Monad m, Fractional a) => Unfold m (a, a) a
379enumerateFromThenFractional = enumerateFromThenNum
263enumerateFromThenFractional = enumerateFromThenNum
265+-- | Same as 'enumerateFromStepNum' with a step of 1 and enumerating up to the
266+-- specified upper limit rounded to the nearest integral value:
268+-- >>> enumerateFromToFractional =
381{-# INLINE_NORMAL enumerateFromToFractional #-}
272{-# INLINE_NORMAL enumerateFromToFractional #-}
382enumerateFromToFractional :: (Monad m, Fractional a, Ord a) =>
273enumerateFromToFractional :: (Monad m, Fractional a, Ord a) =>
383 Unfold m (a, a) a
274 Unfold m (a, a) a
384−enumerateFromToFractional = enumerateFromToNum
275+enumerateFromToFractional =
276+ takeWhileMWithInput (\(_, to) b -> return $ b <= to + 1 / 2)
277+ $ lmap (\(from, _) -> (from, 1)) enumerateFromStepNum
386−{-# INLINE_NORMAL enumerateFromThenToFractional #-}
279+{-# INLINE enumerateFromThenToFractional #-}
387enumerateFromThenToFractional :: (Monad m, Fractional a, Ord a) =>
280enumerateFromThenToFractional :: (Monad m, Fractional a, Ord a) =>
388 Unfold m (a, a, a) a
281 Unfold m (a, a, a) a
389−enumerateFromThenToFractional = enumerateFromThenToNum
282+enumerateFromThenToFractional =
283+ takeWhileMWithInput cond $ lmap toFromStep enumerateFromStepNum
287+ toFromStep (from, next, _) = (from, next - from)
289+ cond (from, next, to) b =
290+ let stride = next - from
293+ then b <= to + stride / 2
294+ else b >= to + stride / 2
391-------------------------------------------------------------------------------
296-------------------------------------------------------------------------------
392-- Enumeration of Enum types not larger than Int
297-- Enumeration of Enum types not larger than Int
393-------------------------------------------------------------------------------
298-------------------------------------------------------------------------------
395−-- XXX should we check for bounds here? Otherwise it will cycle back to "to" if
398-- | Enumerate from given starting Enum value 'from' and to Enum value 'to'
300-- | Enumerate from given starting Enum value 'from' and to Enum value 'to'
399-- with stride of 1 till to value.
301-- with stride of 1 till to value.
@@ -402,16 +304,8 @@ enumerateFromThenToFractional = enumerateFromThenToNum
403{-# INLINE enumerateFromToSmall #-}
305{-# INLINE enumerateFromToSmall #-}
404enumerateFromToSmall :: (Monad m, Enum a) => Unfold m (a, a) a
306enumerateFromToSmall :: (Monad m, Enum a) => Unfold m (a, a) a
405−enumerateFromToSmall = map toEnum $
307+enumerateFromToSmall =
406− Unfold step inject
308+ fmap toEnum (lmap (bimap fromEnum fromEnum) enumerateFromToIntegral)
411− `seq` return (fromEnum from, 1, fromEnum to)
412− {-# INLINE_LATE step #-}
413− step (x, stride, to) = return $
414− if x <= to then Yield x $! (x + stride, stride, to) else Stop
416-- | Enumerate from given starting Enum value 'from' and then Enum value 'next'
310-- | Enumerate from given starting Enum value 'from' and then Enum value 'next'
417-- and to Enum value 'to' with stride of (fromEnum next - fromEnum from)
311-- and to Enum value 'to' with stride of (fromEnum next - fromEnum from)
@@ -421,31 +315,9 @@ enumerateFromToSmall = map toEnum $
422{-# INLINE enumerateFromThenToSmall #-}
316{-# INLINE enumerateFromThenToSmall #-}
423enumerateFromThenToSmall :: (Monad m, Enum a) => Unfold m (a, a, a) a
317enumerateFromThenToSmall :: (Monad m, Enum a) => Unfold m (a, a, a) a
424−enumerateFromThenToSmall = map toEnum $
318+enumerateFromThenToSmall =
425− Unfold step inject
319+ let toInts (x, y, z) = (fromEnum x, fromEnum y, fromEnum z)
426− where
320+ in fmap toEnum (lmap toInts enumerateFromThenToIntegral)
427− inject (from, next, to) =
432− (fromEnum from, fromEnum next - fromEnum from, fromEnum to)
433− {-# INLINE_LATE step #-}
434− step (x, stride, to) = return $
437− if x <= to then Yield x $! (x, stride, to) else Stop
443− then Yield x $! (x + stride, stride, to)
446− if x >= 0 && x >= to
447− then Yield x $! (x + stride, stride, to)
450-------------------------------------------------------------------------------
322-------------------------------------------------------------------------------
451-- Bounded Enumeration of Enum types not larger than Int
323-- Bounded Enumeration of Enum types not larger than Int
@@ -457,16 +329,8 @@ enumerateFromThenToSmall = map toEnum $
457-- /Internal/
329-- /Internal/
459{-# INLINE enumerateFromSmallBounded #-}
331{-# INLINE enumerateFromSmallBounded #-}
460−enumerateFromSmallBounded :: forall a m. (Monad m, Bounded a, Enum a) => Unfold m a a
332+enumerateFromSmallBounded :: (Monad m, Enum a, Bounded a) => Unfold m a a
461−enumerateFromSmallBounded = map toEnum $
333+enumerateFromSmallBounded = supplySecond maxBound enumerateFromToSmall
466− `seq` return (fromEnum from, 1, fromEnum (maxBound :: a))
467− {-# INLINE_LATE step #-}
468− step (x, stride, to) = return $
469− if x <= to then Yield x $! (x + stride, stride, to) else Stop
471-- | Enumerate from given starting Enum value 'from' and next Enum value 'next'
335-- | Enumerate from given starting Enum value 'from' and next Enum value 'next'
472-- with stride of (fromEnum next - fromEnum from) till maxBound.
336-- with stride of (fromEnum next - fromEnum from) till maxBound.
@@ -474,35 +338,18 @@ enumerateFromSmallBounded = map toEnum $
474-- /Internal/
338-- /Internal/
476{-# INLINE enumerateFromThenSmallBounded #-}
340{-# INLINE enumerateFromThenSmallBounded #-}
477−enumerateFromThenSmallBounded :: forall a m. (Monad m, Bounded a, Enum a) =>
341+enumerateFromThenSmallBounded :: forall m a. (Monad m, Enum a, Bounded a) =>
478 Unfold m (a, a) a
342 Unfold m (a, a) a
479−enumerateFromThenSmallBounded = map toEnum $
343+enumerateFromThenSmallBounded =
482− inject (from, next) =
344+ let adapt (from, next) =
486− ( fromEnum from
345+ let frm = fromEnum from
487− , fromEnum next - fromEnum from
488− , fromEnum (maxBound :: a)
346+ nxt = fromEnum next
489− )
347+ stride = nxt - frm
490− {-# INLINE_LATE step #-}
348+ to = if stride >= 0
491− step (x, stride, to) = return $
349+ then fromEnum (maxBound :: a)
492− if stride == 0
350+ else fromEnum (minBound :: a)
493− then
351+ in (frm, nxt, to)
494− if x <= to then Yield x $! (x, stride, to) else Stop
352+ in fmap toEnum (lmap adapt enumerateFromThenToIntegral)
500− then Yield x $! (x + stride, stride, to)
504− then Yield x $! (x + stride, stride, to)
507-------------------------------------------------------------------------------
354-------------------------------------------------------------------------------
508-- Enumerable type class
355-- Enumerable type class