{-# LANGUAGE CPP #-}
-- |
-- Module      : Streamly.Internal.Data.Scanl
-- Copyright   : (c) 2024 Composewell Technologies
-- License     : BSD3
-- Maintainer  : streamly@composewell.com
-- Stability   : experimental
-- Portability : GHC
--
-- Left scans.
--
-- == Scanl vs Fold
--
-- Folds and scans both are consumers of streams. A left scan is a
-- generalization of a fold. While the output of a fold is a singleton value,
-- the output of a scan is a stream. A fold is equivalent to a left scan which
-- produces only the final value in the output stream.
--
-- Like folds, a scan has an internal state. Unlike a fold, a scan produces an
-- output on each input, the output is a function of the scan state and the
-- input.
--
-- A @Scanl m a b@ can represent a @Fold m a b@ by discarding the intermediate
-- outputs and keeping only the final output of the scan.
--
-- Since folds do not care about intermediate values, we do not need the
-- extract function for folds. Because folds do not have a requirement for
-- intermediate values, they can be used for implementing combinators like
-- splitWith where intermediate values are not meaningful and are expensive to
-- compute. Folds provide an applicative and monad behavior to consume the
-- stream in parts and compose the folded results. Scans provide Category like
-- composition and stream zip applicative behavior. The finalization function
-- of a fold would return a single value whereas for scan it may be a stream
-- draining the scan buffer. For these reasons, scans and folds are required as
-- independent abstractions.
--
-- == Scanl vs Pipe
--
-- A scan is a simpler version of the consumer side of pipes. A left scan
-- always produces an output whereas a pipe has an additional ability to skip
-- output. Scans are simpler abstractions to think about compared to pipes and
-- easier for the compiler to optimize and fuse.
--
-- == Compositions
--
-- Scans can be chained in the same way as function composition (Category) and
-- can distribute input (tee Applicative). Folds provide an applicative and
-- monad behavior to consume the stream in parts and compose the folded
-- results. Folds are also a special case of parsers.

-- TBD: A scan can produce more than one output on an input, in other words,
-- it can produce output on its own.
--
module Streamly.Internal.Data.Scanl
    (
    -- * Imports
    -- $setup

      module Streamly.Internal.Data.Scanl.Type
    , module Streamly.Internal.Data.Scanl.Window
    , module Streamly.Internal.Data.Scanl.Combinators
    , module Streamly.Internal.Data.Scanl.Container
    )
where

import Streamly.Internal.Data.Scanl.Window
import Streamly.Internal.Data.Scanl.Combinators
import Streamly.Internal.Data.Scanl.Container
import Streamly.Internal.Data.Scanl.Type

#include "DocTestDataFold.hs"