module Streamly.Internal.Data.Stream.IsStream.Enumeration
    (
      Enumerable (..)
    
    , enumerate
    , enumerateTo
    , enumerateFromBounded
    
    , enumerateFromToSmall
    , enumerateFromThenToSmall
    , enumerateFromThenSmallBounded
    
    , enumerateFromIntegral
    , enumerateFromThenIntegral
    
    , enumerateFromToIntegral
    , enumerateFromThenToIntegral
    
    , enumerateFromStepIntegral
    
    , enumerateFromFractional
    , enumerateFromToFractional
    , enumerateFromThenFractional
    , enumerateFromThenToFractional
    )
where
import Data.Fixed
import Data.Int
import Data.Ratio
import Data.Word
import Numeric.Natural
import Data.Functor.Identity (Identity(..))
import Streamly.Internal.Data.Stream.IsStream.Type (IsStream(..), fromStreamD)
import qualified Streamly.Internal.Data.Stream.IsStream.Type as IsStream
import qualified Streamly.Internal.Data.Stream.StreamD.Generate as D
import qualified Streamly.Internal.Data.Stream.Serial as Serial (map)
{-# INLINE enumerateFromStepIntegral #-}
enumerateFromStepIntegral
    :: (IsStream t, Monad m, Integral a)
    => a -> a -> t m a
enumerateFromStepIntegral :: a -> a -> t m a
enumerateFromStepIntegral a
from a
stride =
    Stream m a -> t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(IsStream t, Monad m) =>
Stream m a -> t m a
fromStreamD (Stream m a -> t m a) -> Stream m a -> t m a
forall a b. (a -> b) -> a -> b
$ a -> a -> Stream m a
forall a (m :: * -> *).
(Integral a, Monad m) =>
a -> a -> Stream m a
D.enumerateFromStepIntegral a
from a
stride
{-# INLINE enumerateFromIntegral #-}
enumerateFromIntegral
    :: (IsStream t, Monad m, Integral a, Bounded a)
    => a -> t m a
enumerateFromIntegral :: a -> t m a
enumerateFromIntegral a
from = Stream m a -> t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(IsStream t, Monad m) =>
Stream m a -> t m a
fromStreamD (Stream m a -> t m a) -> Stream m a -> t m a
forall a b. (a -> b) -> a -> b
$ a -> Stream m a
forall (m :: * -> *) a.
(Monad m, Integral a, Bounded a) =>
a -> Stream m a
D.enumerateFromIntegral a
from
{-# INLINE enumerateFromThenIntegral #-}
enumerateFromThenIntegral
    :: (IsStream t, Monad m, Integral a, Bounded a)
    => a -> a -> t m a
enumerateFromThenIntegral :: a -> a -> t m a
enumerateFromThenIntegral a
from a
next =
    Stream m a -> t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(IsStream t, Monad m) =>
Stream m a -> t m a
fromStreamD (Stream m a -> t m a) -> Stream m a -> t m a
forall a b. (a -> b) -> a -> b
$ a -> a -> Stream m a
forall (m :: * -> *) a.
(Monad m, Integral a, Bounded a) =>
a -> a -> Stream m a
D.enumerateFromThenIntegral a
from a
next
{-# INLINE enumerateFromToIntegral #-}
enumerateFromToIntegral :: (IsStream t, Monad m, Integral a) => a -> a -> t m a
enumerateFromToIntegral :: a -> a -> t m a
enumerateFromToIntegral a
from a
to =
    Stream m a -> t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(IsStream t, Monad m) =>
Stream m a -> t m a
fromStreamD (Stream m a -> t m a) -> Stream m a -> t m a
forall a b. (a -> b) -> a -> b
$ a -> a -> Stream m a
forall (m :: * -> *) a.
(Monad m, Integral a) =>
a -> a -> Stream m a
D.enumerateFromToIntegral a
from a
to
{-# INLINE enumerateFromThenToIntegral #-}
enumerateFromThenToIntegral
    :: (IsStream t, Monad m, Integral a)
    => a -> a -> a -> t m a
enumerateFromThenToIntegral :: a -> a -> a -> t m a
enumerateFromThenToIntegral a
from a
next a
to =
    Stream m a -> t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(IsStream t, Monad m) =>
Stream m a -> t m a
fromStreamD (Stream m a -> t m a) -> Stream m a -> t m a
forall a b. (a -> b) -> a -> b
$ a -> a -> a -> Stream m a
forall (m :: * -> *) a.
(Monad m, Integral a) =>
a -> a -> a -> Stream m a
D.enumerateFromThenToIntegral a
from a
next a
to
{-# INLINE enumerateFromFractional #-}
enumerateFromFractional :: (IsStream t, Monad m, Fractional a) => a -> t m a
enumerateFromFractional :: a -> t m a
enumerateFromFractional a
from = Stream m a -> t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(IsStream t, Monad m) =>
Stream m a -> t m a
fromStreamD (Stream m a -> t m a) -> Stream m a -> t m a
forall a b. (a -> b) -> a -> b
$ a -> Stream m a
forall (m :: * -> *) a. (Monad m, Num a) => a -> Stream m a
D.enumerateFromNum a
from
{-# INLINE enumerateFromThenFractional #-}
enumerateFromThenFractional
    :: (IsStream t, Monad m, Fractional a)
    => a -> a -> t m a
enumerateFromThenFractional :: a -> a -> t m a
enumerateFromThenFractional a
from a
next = Stream m a -> t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(IsStream t, Monad m) =>
Stream m a -> t m a
fromStreamD (Stream m a -> t m a) -> Stream m a -> t m a
forall a b. (a -> b) -> a -> b
$ a -> a -> Stream m a
forall (m :: * -> *) a. (Monad m, Num a) => a -> a -> Stream m a
D.enumerateFromThenNum a
from a
next
{-# INLINE enumerateFromToFractional #-}
enumerateFromToFractional
    :: (IsStream t, Monad m, Fractional a, Ord a)
    => a -> a -> t m a
enumerateFromToFractional :: a -> a -> t m a
enumerateFromToFractional a
from a
to =
    Stream m a -> t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(IsStream t, Monad m) =>
Stream m a -> t m a
fromStreamD (Stream m a -> t m a) -> Stream m a -> t m a
forall a b. (a -> b) -> a -> b
$ a -> a -> Stream m a
forall (m :: * -> *) a.
(Monad m, Fractional a, Ord a) =>
a -> a -> Stream m a
D.enumerateFromToFractional a
from a
to
{-# INLINE enumerateFromThenToFractional #-}
enumerateFromThenToFractional
    :: (IsStream t, Monad m, Fractional a, Ord a)
    => a -> a -> a -> t m a
enumerateFromThenToFractional :: a -> a -> a -> t m a
enumerateFromThenToFractional a
from a
next a
to =
    Stream m a -> t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(IsStream t, Monad m) =>
Stream m a -> t m a
fromStreamD (Stream m a -> t m a) -> Stream m a -> t m a
forall a b. (a -> b) -> a -> b
$ a -> a -> a -> Stream m a
forall (m :: * -> *) a.
(Monad m, Fractional a, Ord a) =>
a -> a -> a -> Stream m a
D.enumerateFromThenToFractional a
from a
next a
to
{-# INLINE enumerateFromToSmall #-}
enumerateFromToSmall :: (IsStream t, Monad m, Enum a) => a -> a -> t m a
enumerateFromToSmall :: a -> a -> t m a
enumerateFromToSmall a
from a
to =
    SerialT m a -> t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
IsStream t =>
SerialT m a -> t m a
IsStream.fromSerial
        (SerialT m a -> t m a) -> SerialT m a -> t m a
forall a b. (a -> b) -> a -> b
$ (Int -> a) -> SerialT m Int -> SerialT m a
forall (m :: * -> *) a b.
Monad m =>
(a -> b) -> SerialT m a -> SerialT m b
Serial.map Int -> a
forall a. Enum a => Int -> a
toEnum
        (SerialT m Int -> SerialT m a) -> SerialT m Int -> SerialT m a
forall a b. (a -> b) -> a -> b
$ Int -> Int -> SerialT m Int
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(IsStream t, Monad m, Integral a) =>
a -> a -> t m a
enumerateFromToIntegral (a -> Int
forall a. Enum a => a -> Int
fromEnum a
from) (a -> Int
forall a. Enum a => a -> Int
fromEnum a
to)
{-# INLINE enumerateFromThenToSmall #-}
enumerateFromThenToSmall :: (IsStream t, Monad m, Enum a)
    => a -> a -> a -> t m a
enumerateFromThenToSmall :: a -> a -> a -> t m a
enumerateFromThenToSmall a
from a
next a
to =
    SerialT m a -> t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
IsStream t =>
SerialT m a -> t m a
IsStream.fromSerial
        (SerialT m a -> t m a) -> SerialT m a -> t m a
forall a b. (a -> b) -> a -> b
$ (Int -> a) -> SerialT m Int -> SerialT m a
forall (m :: * -> *) a b.
Monad m =>
(a -> b) -> SerialT m a -> SerialT m b
Serial.map Int -> a
forall a. Enum a => Int -> a
toEnum
        (SerialT m Int -> SerialT m a) -> SerialT m Int -> SerialT m a
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int -> SerialT m Int
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(IsStream t, Monad m, Integral a) =>
a -> a -> a -> t m a
enumerateFromThenToIntegral
            (a -> Int
forall a. Enum a => a -> Int
fromEnum a
from) (a -> Int
forall a. Enum a => a -> Int
fromEnum a
next) (a -> Int
forall a. Enum a => a -> Int
fromEnum a
to)
{-# INLINE enumerateFromThenSmallBounded #-}
enumerateFromThenSmallBounded :: (IsStream t, Monad m, Enumerable a, Bounded a)
    => a -> a -> t m a
enumerateFromThenSmallBounded :: a -> a -> t m a
enumerateFromThenSmallBounded a
from a
next =
    if a -> Int
forall a. Enum a => a -> Int
fromEnum a
next Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= a -> Int
forall a. Enum a => a -> Int
fromEnum a
from
    then a -> a -> a -> t m a
forall a (t :: (* -> *) -> * -> *) (m :: * -> *).
(Enumerable a, IsStream t, Monad m) =>
a -> a -> a -> t m a
enumerateFromThenTo a
from a
next a
forall a. Bounded a => a
maxBound
    else a -> a -> a -> t m a
forall a (t :: (* -> *) -> * -> *) (m :: * -> *).
(Enumerable a, IsStream t, Monad m) =>
a -> a -> a -> t m a
enumerateFromThenTo a
from a
next a
forall a. Bounded a => a
minBound
class Enum a => Enumerable a where
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    enumerateFrom :: (IsStream t, Monad m) => a -> t m a
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    enumerateFromTo :: (IsStream t, Monad m) => a -> a -> t m a
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    enumerateFromThen :: (IsStream t, Monad m) => a -> a -> t m a
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    enumerateFromThenTo :: (IsStream t, Monad m) => a -> a -> a -> t m a
{-# INLINE enumerate #-}
enumerate :: (IsStream t, Monad m, Bounded a, Enumerable a) => t m a
enumerate :: t m a
enumerate = a -> t m a
forall a (t :: (* -> *) -> * -> *) (m :: * -> *).
(Enumerable a, IsStream t, Monad m) =>
a -> t m a
enumerateFrom a
forall a. Bounded a => a
minBound
{-# INLINE enumerateTo #-}
enumerateTo :: (IsStream t, Monad m, Bounded a, Enumerable a) => a -> t m a
enumerateTo :: a -> t m a
enumerateTo = a -> a -> t m a
forall a (t :: (* -> *) -> * -> *) (m :: * -> *).
(Enumerable a, IsStream t, Monad m) =>
a -> a -> t m a
enumerateFromTo a
forall a. Bounded a => a
minBound
{-# INLINE enumerateFromBounded #-}
enumerateFromBounded :: (IsStream t, Monad m, Enumerable a, Bounded a)
    => a -> t m a
enumerateFromBounded :: a -> t m a
enumerateFromBounded a
from = a -> a -> t m a
forall a (t :: (* -> *) -> * -> *) (m :: * -> *).
(Enumerable a, IsStream t, Monad m) =>
a -> a -> t m a
enumerateFromTo a
from a
forall a. Bounded a => a
maxBound
#define ENUMERABLE_BOUNDED_SMALL(SMALL_TYPE)           \
instance Enumerable SMALL_TYPE where {                 \
    {-# INLINE enumerateFrom #-};                      \
    enumerateFrom = enumerateFromBounded;              \
    {-# INLINE enumerateFromThen #-};                  \
    enumerateFromThen = enumerateFromThenSmallBounded; \
    {-# INLINE enumerateFromTo #-};                    \
    enumerateFromTo = enumerateFromToSmall;            \
    {-# INLINE enumerateFromThenTo #-};                \
    enumerateFromThenTo = enumerateFromThenToSmall }
ENUMERABLE_BOUNDED_SMALL(())
ENUMERABLE_BOUNDED_SMALL(Bool)
ENUMERABLE_BOUNDED_SMALL(Ordering)
ENUMERABLE_BOUNDED_SMALL(Char)
#define ENUMERABLE_BOUNDED_INTEGRAL(INTEGRAL_TYPE)  \
instance Enumerable INTEGRAL_TYPE where {           \
    {-# INLINE enumerateFrom #-};                   \
    enumerateFrom = enumerateFromIntegral;          \
    {-# INLINE enumerateFromThen #-};               \
    enumerateFromThen = enumerateFromThenIntegral;  \
    {-# INLINE enumerateFromTo #-};                 \
    enumerateFromTo = enumerateFromToIntegral;      \
    {-# INLINE enumerateFromThenTo #-};             \
    enumerateFromThenTo = enumerateFromThenToIntegral }
ENUMERABLE_BOUNDED_INTEGRAL(Int)
ENUMERABLE_BOUNDED_INTEGRAL(Int8)
ENUMERABLE_BOUNDED_INTEGRAL(Int16)
ENUMERABLE_BOUNDED_INTEGRAL(Int32)
ENUMERABLE_BOUNDED_INTEGRAL(Int64)
ENUMERABLE_BOUNDED_INTEGRAL(Word)
ENUMERABLE_BOUNDED_INTEGRAL(Word8)
ENUMERABLE_BOUNDED_INTEGRAL(Word16)
ENUMERABLE_BOUNDED_INTEGRAL(Word32)
ENUMERABLE_BOUNDED_INTEGRAL(Word64)
#define ENUMERABLE_UNBOUNDED_INTEGRAL(INTEGRAL_TYPE)              \
instance Enumerable INTEGRAL_TYPE where {                         \
    {-# INLINE enumerateFrom #-};                                 \
    enumerateFrom from = enumerateFromStepIntegral from 1;        \
    {-# INLINE enumerateFromThen #-};                             \
    enumerateFromThen from next =                                 \
        enumerateFromStepIntegral from (next - from);             \
    {-# INLINE enumerateFromTo #-};                               \
    enumerateFromTo = enumerateFromToIntegral;                    \
    {-# INLINE enumerateFromThenTo #-};                           \
    enumerateFromThenTo = enumerateFromThenToIntegral }
ENUMERABLE_UNBOUNDED_INTEGRAL(Integer)
ENUMERABLE_UNBOUNDED_INTEGRAL(Natural)
#define ENUMERABLE_FRACTIONAL(FRACTIONAL_TYPE,CONSTRAINT)         \
instance (CONSTRAINT) => Enumerable FRACTIONAL_TYPE where {     \
    {-# INLINE enumerateFrom #-};                                 \
    enumerateFrom = enumerateFromFractional;                      \
    {-# INLINE enumerateFromThen #-};                             \
    enumerateFromThen = enumerateFromThenFractional;              \
    {-# INLINE enumerateFromTo #-};                               \
    enumerateFromTo = enumerateFromToFractional;                  \
    {-# INLINE enumerateFromThenTo #-};                           \
    enumerateFromThenTo = enumerateFromThenToFractional }
ENUMERABLE_FRACTIONAL(Float,)
ENUMERABLE_FRACTIONAL(Double,)
ENUMERABLE_FRACTIONAL((Fixed a),HasResolution a)
ENUMERABLE_FRACTIONAL((Ratio a),Integral a)
instance Enumerable a => Enumerable (Identity a) where
    {-# INLINE enumerateFrom #-}
    enumerateFrom :: Identity a -> t m (Identity a)
enumerateFrom (Identity a
from) =
        SerialT m (Identity a) -> t m (Identity a)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
IsStream t =>
SerialT m a -> t m a
IsStream.fromSerial (SerialT m (Identity a) -> t m (Identity a))
-> SerialT m (Identity a) -> t m (Identity a)
forall a b. (a -> b) -> a -> b
$ (a -> Identity a) -> SerialT m a -> SerialT m (Identity a)
forall (m :: * -> *) a b.
Monad m =>
(a -> b) -> SerialT m a -> SerialT m b
Serial.map a -> Identity a
forall a. a -> Identity a
Identity (SerialT m a -> SerialT m (Identity a))
-> SerialT m a -> SerialT m (Identity a)
forall a b. (a -> b) -> a -> b
$ a -> SerialT m a
forall a (t :: (* -> *) -> * -> *) (m :: * -> *).
(Enumerable a, IsStream t, Monad m) =>
a -> t m a
enumerateFrom a
from
    {-# INLINE enumerateFromThen #-}
    enumerateFromThen :: Identity a -> Identity a -> t m (Identity a)
enumerateFromThen (Identity a
from) (Identity a
next) =
        SerialT m (Identity a) -> t m (Identity a)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
IsStream t =>
SerialT m a -> t m a
IsStream.fromSerial (SerialT m (Identity a) -> t m (Identity a))
-> SerialT m (Identity a) -> t m (Identity a)
forall a b. (a -> b) -> a -> b
$ (a -> Identity a) -> SerialT m a -> SerialT m (Identity a)
forall (m :: * -> *) a b.
Monad m =>
(a -> b) -> SerialT m a -> SerialT m b
Serial.map a -> Identity a
forall a. a -> Identity a
Identity (SerialT m a -> SerialT m (Identity a))
-> SerialT m a -> SerialT m (Identity a)
forall a b. (a -> b) -> a -> b
$ a -> a -> SerialT m a
forall a (t :: (* -> *) -> * -> *) (m :: * -> *).
(Enumerable a, IsStream t, Monad m) =>
a -> a -> t m a
enumerateFromThen a
from a
next
    {-# INLINE enumerateFromTo #-}
    enumerateFromTo :: Identity a -> Identity a -> t m (Identity a)
enumerateFromTo (Identity a
from) (Identity a
to) =
        SerialT m (Identity a) -> t m (Identity a)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
IsStream t =>
SerialT m a -> t m a
IsStream.fromSerial (SerialT m (Identity a) -> t m (Identity a))
-> SerialT m (Identity a) -> t m (Identity a)
forall a b. (a -> b) -> a -> b
$ (a -> Identity a) -> SerialT m a -> SerialT m (Identity a)
forall (m :: * -> *) a b.
Monad m =>
(a -> b) -> SerialT m a -> SerialT m b
Serial.map a -> Identity a
forall a. a -> Identity a
Identity (SerialT m a -> SerialT m (Identity a))
-> SerialT m a -> SerialT m (Identity a)
forall a b. (a -> b) -> a -> b
$ a -> a -> SerialT m a
forall a (t :: (* -> *) -> * -> *) (m :: * -> *).
(Enumerable a, IsStream t, Monad m) =>
a -> a -> t m a
enumerateFromTo a
from a
to
    {-# INLINE enumerateFromThenTo #-}
    enumerateFromThenTo :: Identity a -> Identity a -> Identity a -> t m (Identity a)
enumerateFromThenTo (Identity a
from) (Identity a
next) (Identity a
to) =
        SerialT m (Identity a) -> t m (Identity a)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
IsStream t =>
SerialT m a -> t m a
IsStream.fromSerial
            (SerialT m (Identity a) -> t m (Identity a))
-> SerialT m (Identity a) -> t m (Identity a)
forall a b. (a -> b) -> a -> b
$ (a -> Identity a) -> SerialT m a -> SerialT m (Identity a)
forall (m :: * -> *) a b.
Monad m =>
(a -> b) -> SerialT m a -> SerialT m b
Serial.map a -> Identity a
forall a. a -> Identity a
Identity
            (SerialT m a -> SerialT m (Identity a))
-> SerialT m a -> SerialT m (Identity a)
forall a b. (a -> b) -> a -> b
$ a -> a -> a -> SerialT m a
forall a (t :: (* -> *) -> * -> *) (m :: * -> *).
(Enumerable a, IsStream t, Monad m) =>
a -> a -> a -> t m a
enumerateFromThenTo a
from a
next a
to