on cd0c2fd help sign in
81 lines 2.8 kB history raw
1-- |
2-- Module : Streamly.Internal.Data.Producer
3-- Copyright : (c) 2021 Composewell Technologies
4-- License : BSD-3-Clause
5-- Maintainer : streamly@composewell.com
6-- Stability : experimental
7-- Portability : GHC
8--
9-- A 'Producer' is an 'Unfold' with an 'extract' function added to extract
10-- the state. It is more powerful but less general than an Unfold.
11--
12-- A 'Producer' represents steps of a loop generating a sequence of elements.
13-- While unfolds are closed representation of imperative loops with some opaque
14-- internal state, producers are open loops with the state being accessible to
15-- the user.
16--
17-- Unlike an unfold, which runs a loop till completion, a producer can be
18-- stopped in the middle, its state can be extracted, examined, changed, and
19-- then it can be resumed later from the stopped state.
20--
21-- A producer can be used in places where a CPS stream would otherwise be
22-- needed, because the state of the loop can be passed around. However, it can
23-- be much more efficient than CPS because it allows stream fusion and
24-- unecessary function calls can be avoided.
26module Streamly.Internal.Data.Producer
27 (
28 module Streamly.Internal.Data.Producer.Source
29 , module Streamly.Internal.Data.Producer.Type
31 -- * Converting
32 , simplify
33 , fromStreamD
34 )
35where
37#include "inline.hs"
39import Streamly.Internal.Data.Stream.Step (Step(..))
40import Streamly.Internal.Data.Stream.Type (Stream(..))
41import Streamly.Internal.Data.SVar.Type (defState)
42import Streamly.Internal.Data.Unfold.Type (Unfold(..))
44import Streamly.Internal.Data.Producer.Source
45import Streamly.Internal.Data.Producer.Type
46import Prelude hiding (concat)
48-- XXX We should write unfolds as producers where possible and define
49-- unfolds using "simplify".
50--
51-------------------------------------------------------------------------------
52-- Converting to unfolds
53-------------------------------------------------------------------------------
55-- | Simplify a producer to an unfold.
56--
57-- /Pre-release/
58{-# INLINE simplify #-}
59simplify :: Producer m a b -> Unfold m a b
60simplify (Producer step inject _) = Unfold step inject
62-------------------------------------------------------------------------------
63-- Unfolds
64-------------------------------------------------------------------------------
66-- | Convert a StreamD stream into a producer.
67--
68-- /Pre-release/
69{-# INLINE_NORMAL fromStreamD #-}
70fromStreamD :: Monad m => Producer m (Stream m a) a
71fromStreamD = Producer step return return
73 where
75 {-# INLINE_LATE step #-}
76 step (UnStream step1 state1) = do
77 r <- step1 defState state1
78 return $ case r of
79 Yield x s -> Yield x (Stream step1 s)
80 Skip s -> Skip (Stream step1 s)
81 Stop -> Stop