streamly-core-0.2.0: src/Streamly/Data/StreamK.hs
{-# 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 functions calls using Continuation Passing
-- Style (CPS), suitable for dynamically composing potentially large number of
-- 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 to efficiently 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. For more details See the @Stream vs
-- StreamK@ section in the "Streamly.Data.Stream" module.
--
-- 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".
-- 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
-- * Overview
-- $overview
-- * Type
StreamK
-- * 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
-- * Elimination
-- ** Primitives
, uncons
, drain
-- -- ** Folding
-- , foldBreak
-- ** Parsing
, parse
, parseBreak
, parseBreakChunks
, parseChunks
-- * Transformation
, mapM
, dropWhile
, take
-- * 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
, concatMapWith
, 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
)
where
import Streamly.Internal.Data.StreamK
import Prelude hiding (reverse, zipWith, mapM, dropWhile, take)
#include "DocTestDataStreamK.hs"
-- $overview
--
-- Continuation passing style (CPS) stream implementation. The 'K' in 'StreamK'
-- stands for Kontinuation.
--
-- StreamK can be constructed like lists, except that they use 'nil' instead of
-- '[]' and 'cons' instead of ':'.
--
-- `cons` adds a pure value at the head of the stream:
--
-- >>> import Streamly.Data.StreamK (StreamK, cons, consM, nil)
-- >>> stream = 1 `cons` 2 `cons` nil :: StreamK IO Int
--
-- You can use operations from "Streamly.Data.Stream" 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]
--
-- `consM` adds an effect at the head of the stream:
--
-- >>> stream = effect 1 `consM` effect 2 `consM` nil
-- >>> Stream.fold Fold.toList $ StreamK.toStream stream
-- 1
-- 2
-- [1,2]