@@ -34,6 +34,9 @@ module Streamly.Streams.StreamKType
35 -- * Construction
35 -- * Construction
36 , mkStream
36 , mkStream
38 -- * Elimination
41 -- * Elimination
39 , foldStream
42 , foldStream
@@ -42,6 +45,7 @@ module Streamly.Streams.StreamKType
43 -- instances
46 -- instances
44 , consMSerial
47 , consMSerial
@@ -59,6 +63,39 @@ import Prelude hiding (map)
60import Streamly.SVar
64import Streamly.SVar
66+------------------------------------------------------------------------------
68+------------------------------------------------------------------------------
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:
75+-- data Stream m a = Stop | Singleton a | Yield a (Stream m a)
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
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.
87+-- XXX remove the Stream type parameter from State as it is always constant.
88+-- We can remove it from SVar as well
92+ State Stream m a -- state
94+ -> (a -> m r) -- singleton
95+ -> (a -> Stream m a -> m r) -- yield
62------------------------------------------------------------------------------
99------------------------------------------------------------------------------
63-- Types that can behave as a Stream
100-- Types that can behave as a Stream
64------------------------------------------------------------------------------
101------------------------------------------------------------------------------
@@ -134,39 +171,6 @@ type Streaming = IsStream
134adapt :: (IsStream t1, IsStream t2) => t1 m a -> t2 m a
171adapt :: (IsStream t1, IsStream t2) => t1 m a -> t2 m a
135adapt = fromStream . toStream
172adapt = fromStream . toStream
137−------------------------------------------------------------------------------
139−------------------------------------------------------------------------------
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:
146−-- data Stream m a = Stop | Singleton a | Yield a (Stream m a)
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
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.
158−-- XXX remove the Stream type parameter from State as it is always constant.
159−-- We can remove it from SVar as well
163− State Stream m a -- state
165− -> (a -> m r) -- singleton
166− -> (a -> Stream m a -> m r) -- yield
170------------------------------------------------------------------------------
174------------------------------------------------------------------------------
171-- Building a stream
175-- Building a stream
172------------------------------------------------------------------------------
176------------------------------------------------------------------------------
@@ -194,6 +198,32 @@ mkStream k = fromStream $ MkStream $ \st stp sng yld ->
194 let yieldk a r = yld a (toStream r)
198 let yieldk a r = yld a (toStream r)
195 in k st stp sng yieldk
199 in k st stp sng yieldk
201+-- | A terminal function that has no continuation to follow.
202+type StopK m = forall r. m r -> m r
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
210+_wrapM :: Monad m => m a -> YieldK m a
211+_wrapM m = \k -> m >>= k
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
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
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)
225+-- XXX Build a stream from a repeating callback function.
197------------------------------------------------------------------------------
227------------------------------------------------------------------------------
198-- Folding a stream
228-- Folding a stream
199------------------------------------------------------------------------------
229------------------------------------------------------------------------------