content: {-# LANGUAGE CPP #-}
  -- |
  -- Module      : Streamly.Data.StreamK
  -- Copyright   : (c) 2017 Composewell Technologies
  --
  -- License     : BSD3
  -- Maintainer  : streamly@composewell.com
  -- Stability   : released
  -- Portability : GHC
  --
  -- Streams represented as chains of function calls using Continuation Passing
  -- Style (CPS), suitable for dynamically and recursively composing potentially
  -- large number of streams. The 'K' in 'StreamK' stands for Kontinuation.
  --
  -- In addition to the combinators in this module, you can use operations from
  -- "Streamly.Data.Stream" for StreamK as well by converting StreamK to Stream
  -- ('toStream'), and vice-versa ('fromStream'). Please refer to
  -- "Streamly.Internal.Data.StreamK" for more functions that have not yet been
  -- released.
  --
  -- For documentation see the corresponding combinators in
  -- "Streamly.Data.Stream". Documentation has been omitted in this module unless
  -- there is a difference worth mentioning or if the combinator does not exist
  -- in "Streamly.Data.Stream".
  --
  -- == Fused vs CPS Streams
  --
  -- Unlike the statically fused operations in "Streamly.Data.Stream", StreamK
  -- operations are less efficient, involving a function call overhead for each
  -- element, but they exhibit linear O(n) time complexity wrt to the number of
  -- stream compositions. Therefore, they are suitable for dynamically composing
  -- streams e.g. appending potentially infinite streams in recursive loops.
  -- While fused streams can be used efficiently to process elements as small as
  -- a single byte, CPS streams are typically used on bigger chunks of data to
  -- avoid the larger overhead per element.
  --
  -- = Overview
  --
  -- StreamK can be constructed like lists, except that they use 'nil' instead of
  -- '[]' and 'cons' instead of ':'.
  --
  -- >>> import Streamly.Data.StreamK (StreamK, cons, consM, nil)
  --
  -- `cons` constructs a stream from pure values:
  --
  -- >>> stream = 1 `cons` 2 `cons` nil :: StreamK IO Int
  --
  -- Operations from "Streamly.Data.Stream" can be used for StreamK as well by
  -- converting StreamK to Stream ('toStream'), and vice-versa ('fromStream').
  --
  -- >>> Stream.fold Fold.toList $ StreamK.toStream stream -- IO [Int]
  -- [1,2]
  --
  -- Stream can also be constructed from effects not just pure values:
  --
  -- >>> effect n = print n >> return n
  -- >>> stream = effect 1 `consM` effect 2 `consM` nil
  -- >>> Stream.fold Fold.toList $ StreamK.toStream stream
  -- 1
  -- 2
  -- [1,2]
  
  -- Notes:
  --
  -- primitive/open loop operations that can be used recursively e.g. uncons,
  -- foldBreak, parseBreak should not be converted from StreamD for use in
  -- StreamK, instead native StreamK impl should be used.
  --
  -- Closed loop operations like repeat, replicate, iterate etc can be converted
  -- from StreamD.
  --
  -- In the last phase any operation like (toStreamK . f . toStreamD) should be
  -- rewritten to a K version of f.
  -- XXX Need to add rewrite rules for all missing StreamD operations.
  --
  module Streamly.Data.StreamK
      (
      -- * Setup
      -- | To execute the code examples provided in this module in ghci, please
      -- run the following commands first.
      --
      -- $setup
  
      -- * Type
        StreamK
  
      -- -- * Nested
      -- -- | List transformers and logic programming monads.
      -- , Nested(..) -- need to decide on mtl instances
      -- , FairNested(..) -- bind is not associative
  
      -- * Construction
      -- ** Primitives
      -- | Primitives to construct a stream from pure values or monadic actions.
      -- All other stream construction and generation combinators described later
      -- can be expressed in terms of these primitives. However, the special
      -- versions provided in this module can be much more efficient in some
      -- cases. Users can create custom combinators using these primitives.
      , nil
      , nilM
      , cons
      , consM
  
      -- ** From Values
      , fromPure
      , fromEffect
  
      -- ** From Stream
      -- | Please note that 'Stream' type does not observe any exceptions from
      -- the consumer of the stream whereas 'StreamK' does.
      , fromStream
      , toStream
  
      -- ** From Containers
      , fromFoldable
  
      -- ** To Containers
      , toList
  
      -- * Elimination
  
      -- ** Primitives
      , uncons
      , drain
  
      -- -- ** Folding
      -- , foldBreak
  
      -- ** Parsing
      , toParserK
      , parse
      , parseBreak
      , parsePos
      , parseBreakPos
  
      -- * Transformation
      , mapM
      , dropWhile
      , take
      , filter
  
      -- * Combining Two Streams
      -- | Unlike the operations in "Streamly.Data.Stream", these operations can
      -- be used to dynamically compose large number of streams e.g. using the
      -- 'concatMapWith' and 'mergeMapWith' operations. They have a linear O(n)
      -- time complexity wrt to the number of streams being composed.
  
      -- ** Appending
      , append
  
      -- ** Interleaving
      , interleave
  
      -- ** Merging
      , mergeBy
      , mergeByM
  
      -- ** Zipping
      , zipWith
      , zipWithM
  
      -- ** Cross Product
      -- XXX is "bind/concatFor" better to have than crossWith?
      -- crossWith f xs1 xs2 = concatFor xs1 (\x -> fmap (f x) xs2)
      , crossWith
      -- , cross
      -- , joinInner
      -- , CrossStreamK (..)
  
      -- * Stream of streams
      -- | Some useful idioms:
      --
      -- >>> concatFoldableWith f = Prelude.foldr f StreamK.nil
      -- >>> concatMapFoldableWith f g = Prelude.foldr (f . g) StreamK.nil
      -- >>> concatForFoldableWith f xs g = Prelude.foldr (f . g) StreamK.nil xs
      --
      , concatEffect
      , concatMap
      , bfsConcatMap
      , fairConcatMap
      , concatMapWith
  
      , concatFor
      , bfsConcatFor
      , fairConcatFor
  
      , concatForM
      , bfsConcatForM
      , fairConcatForM
  
      , mergeMapWith
  
      -- * Buffered Operations
      , reverse
      , sortBy
  
      -- * Exceptions
      -- | Please note that 'Stream' type does not observe any exceptions from
      -- the consumer of the stream whereas 'StreamK' does.
      , handle
  
      -- * Resource Management
      -- | Please note that 'Stream' type does not observe any exceptions from
      -- the consumer of the stream whereas 'StreamK' does.
      , bracketIO
  
      -- * Deprecated
      , parseBreakChunks
      , parseChunks
      )
  where
  
  import Streamly.Internal.Data.StreamK
  import Prelude hiding
      (reverse, zipWith, mapM, dropWhile, take, filter, concatMap)
  
  #include "DocTestDataStreamK.hs"
  