@@ -34,6 +34,9 @@ module Streamly.Streams.StreamKType
3434
3535 -- * Construction
3636 , mkStream
37+ , fromStopK
38+ , fromYieldK
39+ , consK
3740
3841 -- * Elimination
3942 , foldStream
@@ -42,6 +45,7 @@ module Streamly.Streams.StreamKType
4245
4346 -- instances
4447 , consMSerial
48+
4549 , nil
4650 , serial
4751 , map
@@ -59,6 +63,39 @@ import Prelude hiding (map)
5963
6064import Streamly.SVar
6165
66+------------------------------------------------------------------------------
67+-- Basic stream type
68+------------------------------------------------------------------------------
69+
70+-- | The type @Stream m a@ represents a monadic stream of values of type 'a'
71+-- constructed using actions in monad 'm'. It uses stop, singleton and yield
72+-- continuations equivalent to the following direct style type:
73+--
74+-- @
75+-- data Stream m a = Stop | Singleton a | Yield a (Stream m a)
76+-- @
77+--
78+-- To facilitate parallel composition we maintain a local state in an 'SVar'
79+-- that is shared across and is used for synchronization of the streams being
80+-- composed.
81+--
82+-- The singleton case can be expressed in terms of stop and yield but we have
83+-- it as a separate case to optimize composition operations for streams with
84+-- single element. We build singleton streams in the implementation of 'pure'
85+-- for Applicative and Monad, and in 'lift' for MonadTrans.
86+--
87+-- XXX remove the Stream type parameter from State as it is always constant.
88+-- We can remove it from SVar as well
89+--
90+newtype Stream m a =
91+ MkStream (forall r.
92+ State Stream m a -- state
93+ -> m r -- stop
94+ -> (a -> m r) -- singleton
95+ -> (a -> Stream m a -> m r) -- yield
96+ -> m r
97+ )
98+
6299------------------------------------------------------------------------------
63100-- Types that can behave as a Stream
64101------------------------------------------------------------------------------
@@ -134,39 +171,6 @@ type Streaming = IsStream
134171adapt :: (IsStream t1, IsStream t2) => t1 m a -> t2 m a
135172adapt = fromStream . toStream
136173
137−------------------------------------------------------------------------------
138−-- Basic stream type
139−------------------------------------------------------------------------------
140−
141−-- | The type @Stream m a@ represents a monadic stream of values of type 'a'
142−-- constructed using actions in monad 'm'. It uses stop, singleton and yield
143−-- continuations equivalent to the following direct style type:
144−--
145−-- @
146−-- data Stream m a = Stop | Singleton a | Yield a (Stream m a)
147−-- @
148−--
149−-- To facilitate parallel composition we maintain a local state in an 'SVar'
150−-- that is shared across and is used for synchronization of the streams being
151−-- composed.
152−--
153−-- The singleton case can be expressed in terms of stop and yield but we have
154−-- it as a separate case to optimize composition operations for streams with
155−-- single element. We build singleton streams in the implementation of 'pure'
156−-- for Applicative and Monad, and in 'lift' for MonadTrans.
157−--
158−-- XXX remove the Stream type parameter from State as it is always constant.
159−-- We can remove it from SVar as well
160−--
161−newtype Stream m a =
162− MkStream (forall r.
163− State Stream m a -- state
164− -> m r -- stop
165− -> (a -> m r) -- singleton
166− -> (a -> Stream m a -> m r) -- yield
167− -> m r
168− )
169−
170174------------------------------------------------------------------------------
171175-- Building a stream
172176------------------------------------------------------------------------------
@@ -194,6 +198,32 @@ mkStream k = fromStream $ MkStream $ \st stp sng yld ->
194198 let yieldk a r = yld a (toStream r)
195199 in k st stp sng yieldk
196200
201+-- | A terminal function that has no continuation to follow.
202+type StopK m = forall r. m r -> m r
203+
204+-- | A monadic continuation, it is a function that yields a value of type "a"
205+-- and calls the argument (a -> m r) as a continuation with that value. We can
206+-- also think of it as a callback with a handler (a -> m r). Category
207+-- theorists call it a codensity type, a special type of right kan extension.
208+type YieldK m a = forall r. (a -> m r) -> m r
209+
210+_wrapM :: Monad m => m a -> YieldK m a
211+_wrapM m = \k -> m >>= k
212+
213+-- | Make an empty stream from a stop function.
214+fromStopK :: IsStream t => StopK m -> t m a
215+fromStopK k = mkStream $ \_ stp _ _ -> k stp
216+
217+-- | Make a singleton stream from a yield function.
218+fromYieldK :: IsStream t => YieldK m a -> t m a
219+fromYieldK k = mkStream $ \_ _ sng _ -> k sng
220+
221+-- | Add a yield function at the head of the stream.
222+consK :: IsStream t => YieldK m a -> t m a -> t m a
223+consK k r = mkStream $ \_ _ _ yld -> k (\x -> yld x r)
224+
225+-- XXX Build a stream from a repeating callback function.
226+
197227------------------------------------------------------------------------------
198228-- Folding a stream
199229------------------------------------------------------------------------------