@@ -21,6 +21,13 @@ module Streamly.Internal.Data.Stream.Generate
2121 , Stream.fromPure
2222 , Stream.fromEffect
2323
24+ -- * Time Enumeration
25+ , times
26+ , absTimes
27+ , absTimesWith
28+ , relTimes
29+ , relTimesWith
30+
2431 -- * Cyclic Elements
2532 , mfix
2633
@@ -40,7 +47,10 @@ import Control.Monad.IO.Class (MonadIO)
4047import Data.Word (Word8)
4148import Foreign.Storable (Storable)
4249import GHC.Exts (Addr#, Ptr (Ptr))
50+import Streamly.Internal.Data.Stream.Bottom
51+ (absTimesWith, relTimesWith, timesWith)
4352import Streamly.Internal.Data.Stream.Type (Stream, fromStreamK, toStreamK)
53+import Streamly.Internal.Data.Time.Units (AbsTime, RelTime64, addToAbsTime64)
4454import Streamly.Internal.Data.Unfold.Type (Unfold)
4555
4656import qualified Streamly.Internal.Data.Stream.StreamD as D
@@ -49,12 +59,14 @@ import qualified Streamly.Internal.Data.Stream.Type as Stream
4959
5060-- $setup
5161-- >>> :m
62+-- >>> import Control.Concurrent (threadDelay)
63+-- >>> import Data.Function (fix)
64+-- >>> import Prelude hiding (take)
5265-- >>> import qualified Streamly.Data.Fold as Fold
5366-- >>> import qualified Streamly.Data.Unfold as Unfold
5467-- >>> import qualified Streamly.Internal.Data.Stream as Stream
5568-- >>> import GHC.Exts (Ptr (Ptr))
5669
57−
5870------------------------------------------------------------------------------
5971-- From Unfold
6072------------------------------------------------------------------------------
@@ -72,6 +84,60 @@ import qualified Streamly.Internal.Data.Stream.Type as Stream
7284unfold :: Monad m => Unfold m a b -> a -> Stream m b
7385unfold unf = Stream.fromStreamD . D.unfold unf
7486
87+------------------------------------------------------------------------------
88+-- Time Enumeration
89+------------------------------------------------------------------------------
90+
91+-- | @times@ returns a stream of time value tuples with clock of 10 ms
92+-- granularity. The first component of the tuple is an absolute time reference
93+-- (epoch) denoting the start of the stream and the second component is a time
94+-- relative to the reference.
95+--
96+-- >>> Stream.mapM_ (\x -> print x >> threadDelay 1000000) $ Stream.take 3 $ Stream.times
97+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),RelTime64 (NanoSecond64 ...))
98+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),RelTime64 (NanoSecond64 ...))
99+-- (AbsTime (TimeSpec {sec = ..., nsec = ...}),RelTime64 (NanoSecond64 ...))
100+--
101+-- Note: This API is not safe on 32-bit machines.
102+--
103+-- /Pre-release/
104+--
105+{-# INLINE times #-}
106+times :: MonadIO m => Stream m (AbsTime, RelTime64)
107+times = timesWith 0.01
108+
109+-- | @absTimes@ returns a stream of absolute timestamps using a clock of 10 ms
110+-- granularity.
111+--
112+-- >>> Stream.mapM_ print $ Stream.delayPre 1 $ Stream.take 3 $ Stream.absTimes
113+-- AbsTime (TimeSpec {sec = ..., nsec = ...})
114+-- AbsTime (TimeSpec {sec = ..., nsec = ...})
115+-- AbsTime (TimeSpec {sec = ..., nsec = ...})
116+--
117+-- Note: This API is not safe on 32-bit machines.
118+--
119+-- /Pre-release/
120+--
121+{-# INLINE absTimes #-}
122+absTimes :: MonadIO m => Stream m AbsTime
123+absTimes = fmap (uncurry addToAbsTime64) times
124+
125+-- | @relTimes@ returns a stream of relative time values starting from 0,
126+-- using a clock of granularity 10 ms.
127+--
128+-- >>> Stream.mapM_ print $ Stream.delayPre 1 $ Stream.take 3 $ Stream.relTimes
129+-- RelTime64 (NanoSecond64 ...)
130+-- RelTime64 (NanoSecond64 ...)
131+-- RelTime64 (NanoSecond64 ...)
132+--
133+-- Note: This API is not safe on 32-bit machines.
134+--
135+-- /Pre-release/
136+--
137+{-# INLINE relTimes #-}
138+relTimes :: MonadIO m => Stream m RelTime64
139+relTimes = fmap snd times
140+
75141-- | We can define cyclic structures using @let@:
76142--
77143-- >>> let (a, b) = ([1, b], head a) in (a, b)