HORIZON HASKELLDocslts/ghc-9.14.x45dd5372026-10-11Search names, modules, packages, or :: a typeCtrl K

GHC 9.14.1 · lts/ghc-9.14.x · 45dd537 · 2026-10-11

Modulestreamly-core-0.3.1Haskell2010

Streamly.Internal.Data.Fold

See Streamly.Data.Fold for an overview and Streamly.Internal.Data.Fold.Type for design notes.

  • 4 types
  • 233 values

Imports

237 declarations
Example10 expressions
:m:set -XFlexibleContextsimport Control.Monad (void)import qualified Data.Foldable as Foldableimport Data.Bifunctor(bimap)import Data.Function ((&))import Data.Functor.Identity (Identity, runIdentity)import Data.IORef (newIORef, readIORef, writeIORef)import Data.Maybe (fromJust, isJust)import Data.Monoid (Endo(..), Last(..), Sum(..))
Example3 expressions
import Streamly.Data.Array (Array)import Streamly.Data.Fold (Fold, Tee(..))import Streamly.Data.Stream (Stream)
Example10 expressions
import qualified Data.Map as Mapimport qualified Data.Set as Setimport qualified Data.IntSet as IntSetimport qualified Streamly.Data.Array as Arrayimport qualified Streamly.Data.Fold as Foldimport qualified Streamly.Data.MutArray as MutArrayimport qualified Streamly.Data.Parser as Parserimport qualified Streamly.Data.Stream as Streamimport qualified Streamly.Data.StreamK as StreamKimport qualified Streamly.Data.Unfold as Unfold

For APIs that have not been released yet.

Example3 expressions
import qualified Streamly.Internal.Data.Fold as Foldimport qualified Streamly.Internal.Data.Scanl as Scanlimport qualified Streamly.Internal.Data.Stream as Stream
valueaddOne :: Monad m => a -> Fold m a b -> m (Fold m a b)
#

Append a singleton value to the fold.

See examples under addStream.

Pre-release

valuecatEithers :: Fold m a b -> Fold m (Either a a) b
#

Remove the either wrapper and flatten both lefts and as well as rights in the output stream.

Definition:

Example1 expression
catEithers = Fold.lmap (either id id)

Pre-release

valuecatMaybes :: Monad m => Fold m a b -> Fold m (Maybe a) b
#

Modify a fold to receive a Maybe input, the Just values are unwrapped and sent to the original fold, Nothing values are discarded.

Example2 expressions
catMaybes = Fold.mapMaybe idcatMaybes = Fold.filter isJust . Fold.lmap fromJust
valueclose :: Monad m => Fold m a b -> Fold m a b
#

Close a fold so that it does not accept any more input.

valueconcatMap :: Monad m => (b -> Fold m a c) -> Fold m a b -> Fold m a c
#

Map a Fold returning function on the result of a Fold and run the returned fold. This is akin to an n-ary version of splitWith where the next fold for splitting the input is decided dynamically using the previous result. This operation can be used to express data dependencies between fold operations.

Let's say the first element in the stream is a count of the following elements that we have to add, then:

Example4 expressions
import Data.Maybe (fromJust)count = fmap fromJust Fold.onetotal n = Fold.take n Fold.sumStream.fold (Fold.concatMap total count) $ Stream.fromList [10,9..1]45

This does not fuse completely, see refold for a fusible alternative.

Time: O(n^2) where n is the number of compositions.

See also: foldIterateM, refold

valuedrain :: Monad m => Fold m a ()
#

A fold that drains all its input, running the effects and discarding the results.

Example2 expressions
drain = Fold.drainMapM (const (return ()))drain = Fold.foldl' (\_ _ -> ()) ()
valueduplicate :: Monad m => Fold m a b -> Fold m a (Fold m a b)
#

duplicate provides the ability to run a fold in parts. The duplicated fold consumes the input and returns the same fold as output instead of returning the final result, the returned fold can be run later to consume more input.

duplicate essentially appends a stream to the fold without finishing the fold. Compare with snoc which appends a singleton value to the fold.

Pre-release

valueextractM :: Monad m => Fold m a b -> m b
#

Deprecated. Please use finalM instead

Extract the accumulated result of the fold.

Definition:

Example1 expression
extractM = Fold.drive Stream.nil

Pre-release

valuefilter :: Monad m => (a -> Bool) -> Fold m a r -> Fold m a r
#

Include only those elements that pass a predicate.

Example1 expression
Stream.fold (Fold.filter (> 5) Fold.sum) $ Stream.fromList [1..10]40
Example2 expressions
filter p = Fold.filterM (return . p)filter p = Fold.mapMaybe (\x -> if p x then Just x else Nothing)
valuefilterM :: Monad m => (a -> m Bool) -> Fold m a r -> Fold m a r
#

Like filter but with a monadic predicate.

Example2 expressions
f p x = p x >>= \r -> return $ if r then Just x else NothingfilterM p = Fold.mapMaybeM (f p)
valuefinalM :: Monad m => Fold m a b -> m b
#

Finalize a fold and extract the accumulated result of the fold.

Definition:

Example1 expression
finalM = Fold.drive Stream.nil

Example:

Example1 expression
Fold.finalM Fold.toList[]

Pre-release

valuefoldl' :: Monad m => (b -> a -> b) -> b -> Fold m a b
#

Make a fold from a left fold style pure step function and initial value of the accumulator.

If your Fold returns only Partial (i.e. never returns a Done) then you can use foldl'* constructors.

A fold with an extract function can be expressed using fmap:

mkfoldlx :: Monad m => (s -> a -> s) -> s -> (s -> b) -> Fold m a b
mkfoldlx step initial extract = fmap extract (foldl' step initial)
valuefoldl1' :: Monad m => (a -> a -> a) -> Fold m a (Maybe a)
#

Make a strict left fold, for non-empty streams, using first element as the starting value. Returns Nothing if the stream is empty.

Pre-release

valuefoldl1M' :: Monad m => (a -> a -> m a) -> Fold m a (Maybe a)
#

Like 'foldl1'' but with a monadic step function.

Pre-release

valuefoldlM' :: Monad m => (b -> a -> m b) -> m b -> Fold m a b
#

Make a fold from a left fold style monadic step function and initial value of the accumulator.

A fold with an extract function can be expressed using rmapM:

mkFoldlxM :: Functor m => (s -> a -> m s) -> m s -> (s -> m b) -> Fold m a b
mkFoldlxM step initial extract = rmapM extract (foldlM' step initial)
valuefoldlM1' :: Monad m => (a -> a -> m a) -> Fold m a (Maybe a)
#

Deprecated. Please use foldl1M' instead

Like 'foldl1'' but with a monadic step function.

Pre-release

valuefoldr :: Monad m => (a -> b -> b) -> b -> Fold m a b
#

Deprecated. Please use foldr' instead.

valuefoldr' :: Monad m => (a -> b -> b) -> b -> Fold m a b
#

Make a fold using a right fold style step function and a terminal value. It performs a strict right fold via a left fold using function composition. Note that a strict right fold can only be useful for constructing strict structures in memory. For reductions this will be very inefficient.

Definitions:

Example2 expressions
foldr' f z = fmap (flip appEndo z) $ Fold.foldMap (Endo . f)foldr' f z = fmap ($ z) $ Fold.foldl' (\g x -> g . f x) id

Example:

Example1 expression
Stream.fold (Fold.foldr' (:) []) $ Stream.enumerateFromTo 1 5[1,2,3,4,5]
valuefoldrM' :: Monad m => (a -> b -> m b) -> m b -> Fold m a b
#

Like foldr' but with a monadic step function.

Example:

Example1 expression
toList = Fold.foldrM' (\a xs -> return $ a : xs) (return [])

See also: foldrM

Pre-release

valuefoldt'
  1. :: Monad m
  2. => s -> a -> Step s b
  3. -> Step s b
  4. -> s -> b
  5. -> Fold m a b
#

Make a terminating fold using a pure step function, a pure initial state and a pure state extraction function.

Pre-release

valuefoldtM'
  1. :: s -> a -> m (Step s b)
  2. -> m (Step s b)
  3. -> s -> m b
  4. -> Fold m a b
#

Make a terminating fold with an effectful step function and initial state, and a state extraction function.

Example1 expression
foldtM' = Fold.Fold

We can just use Fold but it is provided for completeness.

Pre-release

valuefromEffect :: Applicative m => m b -> Fold m a b
#

Make a fold that yields the result of the supplied effectful action without consuming any further input.

Pre-release

valuefromPure :: Applicative m => b -> Fold m a b
#

Make a fold that yields the supplied value without consuming any further input.

Pre-release

valuegeneralizeInner :: Monad m => Fold Identity a b -> Fold m a b
#

Adapt a pure fold to any monad.

Example1 expression
generalizeInner = Fold.morphInner (return . runIdentity)

Pre-release

valuegenericLength :: (Monad m, Num b) => Fold m a b
#

Like length, except with a more general Num return value

Definition:

Example2 expressions
genericLength = fmap getSum $ Fold.foldMap (Sum . const  1)genericLength = Fold.foldl' (\n _ -> n + 1) 0

Pre-release

valuegroupsOf :: Monad m => Int -> Fold m a b -> Fold m b c -> Fold m a c
#

groupsOf n split collect repeatedly applies the split fold to chunks of n items in the input stream and supplies the result to the collect fold.

Definition:

Example1 expression
groupsOf n split = Fold.many (Fold.take n split)

Example:

Example2 expressions
twos = Fold.groupsOf 2 Fold.toList Fold.toListStream.fold twos $ Stream.fromList [1..10][[1,2],[3,4],[5,6],[7,8],[9,10]]

Stops when collect stops.

valueifThen :: Monad m => m Bool -> Fold m a b -> Fold m a b -> Fold m a b
#

Evaluate a condition, if True then use the first fold otherwise use the second fold.

valueisClosed :: Monad m => Fold m a b -> m Bool
#

Check if the fold has terminated and can take no more input.

Pre-release

valuelatest :: Monad m => Fold m a (Maybe a)
#

Returns the latest element of the input stream, if any.

Example2 expressions
latest = Fold.foldl1' (\_ x -> x)latest = fmap getLast $ Fold.foldMap (Last . Just)
valuelength :: Monad m => Fold m a Int
#

Determine the length of the input stream.

Definition:

Example2 expressions
length = Fold.genericLengthlength = fmap getSum $ Fold.foldMap (Sum . const  1)
valuelmap :: (a -> b) -> Fold m b r -> Fold m a r
#

lmap f fold maps the function f on the input of the fold.

Definition:

Example1 expression
lmap = Fold.lmapM return

Example:

Example2 expressions
sumSquared = Fold.lmap (\x -> x * x) Fold.sumStream.fold sumSquared (Stream.enumerateFromTo 1 100)338350
valuelmapM :: Monad m => (a -> m b) -> Fold m b r -> Fold m a r
#

lmapM f fold maps the monadic function f on the input of the fold.

valuelongest :: Monad m => Fold m x a -> Fold m x b -> Fold m x (Either a b)
#

Longest alternative. Apply both folds in parallel but choose the result from the one which consumed more input i.e. take the longest succeeding fold.

If both the folds finish at the same time or if the result is extracted before any of the folds could finish then the left one is taken.

Pre-release

valuemany :: Monad m => Fold m a b -> Fold m b c -> Fold m a c
#

Collect zero or more applications of a fold. many first second applies the first fold repeatedly on the input stream and accumulates it's results using the second fold.

Example3 expressions
two = Fold.take 2 Fold.toListtwos = Fold.many two Fold.toListStream.fold twos $ Stream.fromList [1..10][[1,2],[3,4],[5,6],[7,8],[9,10]]

Stops when second fold stops.

See also: Data.Stream.concatMap, Data.Stream.foldMany

valuemanyPost :: Monad m => Fold m a b -> Fold m b c -> Fold m a c
#

Like many, but the "first" fold emits an output at the end even if no input is received.

Internal

See also: Data.Stream.concatMap, Data.Stream.foldMany

valuemorphInner :: (forall x. m x -> n x) -> Fold m a b -> Fold n a b
#

Change the underlying monad of a fold. Also known as hoist.

Pre-release

valuepostscan :: Monad m => Fold m a b -> Fold m b c -> Fold m a c
#

Deprecated. Please use postscanl instead.

Postscan the input of a Fold to change it in a stateful manner using another Fold.

postscan scanner collector

Pre-release

valuepostscanl :: Monad m => Scanl m a b -> Fold m b c -> Fold m a c
#

postscanl scanner collector postscans the input of the collector fold to change it in a stateful manner using scanner.

Pre-release

valuepostscanlMaybe :: Monad m => Scanl m a (Maybe b) -> Fold m b c -> Fold m a c
#

Use a Maybe returning left scan for filtering the input of a fold.

Example1 expression
scanlMaybe p f = Fold.postscanl p (Fold.catMaybes f)

Pre-release

valuereduce :: Monad m => Fold m a b -> m (Fold m a b)
#

Evaluate the initialization effect of a fold. If we are building the fold by chaining lazy actions in fold init this would reduce the actions to a strict accumulator value.

Pre-release

valuermapM :: Monad m => (b -> m c) -> Fold m a b -> Fold m a c
#

Map a monadic function on the output of a fold.

valuescan :: Monad m => Fold m a b -> Fold m b c -> Fold m a c
#

Deprecated. Please use scanl instead.

Scan the input of a Fold to change it in a stateful manner using another Fold. The scan stops as soon as the fold terminates.

Pre-release

valuescanMany :: Monad m => Fold m a b -> Fold m b c -> Fold m a c
#

Deprecated. Please use scanlMany instead.

Scan the input of a Fold to change it in a stateful manner using another Fold. The scan restarts with a fresh state if the fold terminates.

Pre-release

valuescanl :: Monad m => Scanl m a b -> Fold m b c -> Fold m a c
#

Scan the input of a Fold to change it in a stateful manner using a Scanl. The scan stops as soon as the fold terminates.

Pre-release

valuescanlMany :: Monad m => Scanl m a b -> Fold m b c -> Fold m a c
#

Scan the input of a Fold to change it in a stateful manner using a Scanl. The scan restarts with a fresh state if it terminates.

Pre-release

valueshortest :: Monad m => Fold m x a -> Fold m x b -> Fold m x (Either a b)
#

Shortest alternative. Apply both folds in parallel but choose the result from the one which consumed least input i.e. take the shortest succeeding fold.

If both the folds finish at the same time or if the result is extracted before any of the folds could finish then the left one is taken.

Pre-release

valuesnoc :: Monad m => Fold m a b -> a -> m (Fold m a b)
#

Append a singleton value to the fold, in other words run a single step of the fold.

Example:

Example2 expressions
import qualified Data.Foldable as FoldableFoldable.foldlM Fold.snoc Fold.toList [1..3] >>= Fold.drive Stream.nil[1,2,3]

Pre-release

valuesnocM :: Monad m => Fold m a b -> m a -> m (Fold m a b)
#

Append a singleton value to the fold in other words run a single step of the fold.

Definition:

Example1 expression
snocM f = Fold.reduce . Fold.snoclM f

Pre-release

valuesnocl :: Monad m => Fold m a b -> a -> Fold m a b
#

Append a singleton value to the fold lazily, in other words run a single step of the fold.

Definition:

Example1 expression
snocl f = Fold.snoclM f . return

Example:

Example2 expressions
import qualified Data.Foldable as FoldableFold.finalM $ Foldable.foldl Fold.snocl Fold.toList [1..3][1,2,3]

Pre-release

valuesnoclM :: Monad m => Fold m a b -> m a -> Fold m a b
#

Append an effect to the fold lazily, in other words run a single step of the fold.

Pre-release

valuesplitWith
  1. :: Monad m
  2. => a -> b -> c
  3. -> Fold m x a
  4. -> Fold m x b
  5. -> Fold m x c
#

Sequential fold application. Apply two folds sequentially to an input stream. The input is provided to the first fold, when it is done - the remaining input is provided to the second fold. When the second fold is done or if the input stream is over, the outputs of the two folds are combined using the supplied function.

Example:

Example4 expressions
header = Fold.take 8 Fold.toListline = Fold.takeEndBy (== '\n') Fold.toListf = Fold.splitWith (,) header lineStream.fold f $ Stream.fromList "header: hello\n"("header: ","hello\n")

Note: This is dual to appending streams using Data.Stream.append.

Note: this implementation allows for stream fusion but has quadratic time complexity, because each composition adds a new branch that each subsequent fold's input element has to traverse, therefore, it cannot scale to a large number of compositions. After around 100 compositions the performance starts dipping rapidly compared to a CPS style implementation.

For larger number of compositions you can convert the fold to a parser and use ParserK.

Time: O(n^2) where n is the number of compositions.

valuesplit_ :: Monad m => Fold m x a -> Fold m x b -> Fold m x b
#

Same as applicative *>. Run two folds serially one after the other discarding the result of the first.

This was written in the hope that it might be faster than implementing it using splitWith, but the current benchmarks show that it has the same performance. So do not expose it unless some benchmark shows benefit.

valuetake :: Monad m => Int -> Fold m a b -> Fold m a b
#

Take at most n input elements and fold them using the supplied fold. A negative count is treated as 0.

Example1 expression
Stream.fold (Fold.take 2 Fold.toList) $ Stream.fromList [1..10][1,2]
valuetakeEndBy :: Monad m => (a -> Bool) -> Fold m a b -> Fold m a b
#

Take the input, stop when the predicate succeeds taking the succeeding element as well.

Example:

Example3 expressions
input = Stream.fromList "hello\nthere\n"line = Fold.takeEndBy (== '\n') Fold.toListStream.fold line input"hello\n"
Example1 expression
Stream.fold Fold.toList $ Stream.foldMany line input["hello\n","there\n"]
valuetakeEndBy_ :: Monad m => (a -> Bool) -> Fold m a b -> Fold m a b
#

Like takeEndBy but drops the element on which the predicate succeeds.

Example:

Example3 expressions
input = Stream.fromList "hello\nthere\n"line = Fold.takeEndBy_ (== '\n') Fold.toListStream.fold line input"hello"
Example1 expression
Stream.fold Fold.toList $ Stream.foldMany line input["hello","there"]
valueteeWith
  1. :: Monad m
  2. => a -> b -> c
  3. -> Fold m x a
  4. -> Fold m x b
  5. -> Fold m x c
#

teeWith k f1 f2 distributes its input to both f1 and f2 until both of them terminate and combines their output using k.

Definition:

Example1 expression
teeWith k f1 f2 = fmap (uncurry k) (Fold.tee f1 f2)

Example:

Example2 expressions
avg = Fold.teeWith (/) Fold.sum (fmap fromIntegral Fold.length)Stream.fold avg $ Stream.fromList [1.0..100.0]50.5

For applicative composition using this combinator see Streamly.Data.Fold.Tee.

See also: Streamly.Data.Fold.Tee

Note that nested applications of teeWith do not fuse.

valuetoList :: Monad m => Fold m a [a]
#

Folds the input stream to a list.

Warning! working on large lists accumulated as buffers in memory could be very inefficient, consider using Streamly.Data.Array instead.

Example1 expression
toList = Fold.foldr' (:) []
valuetoListRev :: Monad m => Fold m a [a]
#

Buffers the input stream to a list in the reverse order of the input.

Definition:

Example1 expression
toListRev = Fold.foldl' (flip (:)) []

Warning! working on large lists accumulated as buffers in memory could be very inefficient, consider using Streamly.Array instead.

valuetoStreamK :: Monad m => Fold m a (StreamK n a)
#

A fold that buffers its input to a pure stream.

Example2 expressions
toStreamK = foldr StreamK.cons StreamK.niltoStreamK = fmap StreamK.reverse Fold.toStreamKRev

Internal

valuetoStreamKRev :: Monad m => Fold m a (StreamK n a)
#

Buffers the input stream to a pure stream in the reverse order of the input.

Example1 expression
toStreamKRev = Foldable.foldl' (flip StreamK.cons) StreamK.nil

This is more efficient than toStreamK. toStreamK has exactly the same performance as reversing the stream after toStreamKRev.

Pre-release

datadata Step s b
#

Represents the result of the step of a Fold. Partial returns an intermediate state of the fold, the fold step can be called again with the state or the driver can use extract on the state to get the result out. Done returns the final result and the fold cannot be driven further.

Pre-release

Constructors

Instances2Bifunctor, Functor
  • Bifunctor StepDefined in streamly-core-0.3.1 · Streamly.Internal.Data.Fold.Step

    first maps over the fold state and second maps over the fold result.

  • Functor (Step s)Defined in streamly-core-0.3.1 · Streamly.Internal.Data.Fold.Step

    fmap maps over Done.

    fmap = second
    
datadata Fold (m :: Type -> Type) a b
#

The type Fold m a b represents a consumer of an input stream of values of type a and returning a final value of type b in Monad m. The constructor of a fold is Fold step initial extract final.

The fold uses an internal state of type s. The initial value of the state s is created by initial. This function is called once and only once before the fold starts consuming input. Any resource allocation can be done in this function.

The step function is called on each input, it consumes an input and returns the next intermediate state (see Step) or the final result b if the fold terminates.

Folds are no longer used for scanning, please see the Streamly.Data.Scanl module for scanning. The extract operation is no longer used and will be removed in future.

Before a fold terminates, final is called once and only once (unless the fold terminated in initial itself). Any resources allocated by initial can be released in final.

When implementing fold combinators, care should be taken to cleanup any state of the argument folds held by the fold by calling the respective final at all exit points of the fold. Also, final should not be called more than once. Note that if a fold terminates by Done constructor, there is no state to cleanup.

NOTE: The constructor is not yet released, smart constructors are provided to create folds.

Constructors

  • forall s. Fold (s -> a -> m (Step s b)) (m (Step s b)) (s -> m b) (s -> m b)

    Fold step initial extract final

Instances2Functor, Applicative
  • Functor m => Functor (Fold m a)Defined in streamly-core-0.3.1 · Streamly.Internal.Data.Fold.Type

    Maps a function on the output of the fold (the type b).

  • Monad m => Applicative (Fold m a)Defined in streamly-core-0.3.1 · Streamly.Internal.Data.Fold.Type

    Applicative form of splitWith. Split the input serially over two folds. Note that this fuses but performance degrades quadratically with respect to the number of compositions. It should be good to use for less than 8 compositions.

newtypenewtype Tee (m :: Type -> Type) a b
#

Tee is a newtype wrapper over the Fold type providing distributing Applicative, Semigroup, Monoid, Num, Floating and Fractional instances.

The input received by the composed Tee is replicated and distributed to the constituent folds of the Tee.

For example, to compute the average of numbers in a stream without going through the stream twice:

Example2 expressions
avg = (/) <$> (Tee Fold.sum) <*> (Tee $ fmap fromIntegral Fold.length)Stream.fold (unTee avg) $ Stream.fromList [1.0..100.0]50.5

Similarly, the Semigroup and Monoid instances of Tee distribute the input to both the folds and combine the outputs using Monoid or Semigroup instances of the output types:

Example3 expressions
import Data.Monoid (Sum(..))t = Tee Fold.one <> Tee Fold.latestStream.fold (unTee t) (fmap Sum $ Stream.enumerateFromTo 1.0 100.0)Just (Sum {getSum = 101.0})

The Num, Floating, and Fractional instances work in the same way.

Constructors

Instances7Functor, Applicative, Floating, Fractional, Num, Semigroup, …
  • Functor m => Functor (Tee m a)Defined in streamly-core-0.3.1 · Streamly.Internal.Data.Fold.Tee
  • Monad m => Applicative (Tee m a)Defined in streamly-core-0.3.1 · Streamly.Internal.Data.Fold.Tee

    <*> distributes the input to both the argument Tees and combines their outputs using function application.

  • (Monad m, Floating b) => Floating (Tee m a b)Defined in streamly-core-0.3.1 · Streamly.Internal.Data.Fold.Tee

    Binary Floating operations distribute the input to both the argument Tees and combine their outputs using the Floating instance of the output type.

  • (Monad m, Fractional b) => Fractional (Tee m a b)Defined in streamly-core-0.3.1 · Streamly.Internal.Data.Fold.Tee

    Binary Fractional operations distribute the input to both the argument Tees and combine their outputs using the Fractional instance of the output type.

  • (Monad m, Num b) => Num (Tee m a b)Defined in streamly-core-0.3.1 · Streamly.Internal.Data.Fold.Tee

    Binary Num operations distribute the input to both the argument Tees and combine their outputs using the Num instance of the output type.

  • (Semigroup b, Monad m) => Semigroup (Tee m a b)Defined in streamly-core-0.3.1 · Streamly.Internal.Data.Fold.Tee

    <> distributes the input to both the argument Tees and combines their outputs using the Semigroup instance of the output type.

  • (Monoid b, Monad m) => Monoid (Tee m a b)Defined in streamly-core-0.3.1 · Streamly.Internal.Data.Fold.Tee

    <> distributes the input to both the argument Tees and combines their outputs using the Monoid instance of the output type.

valueaddStream :: Monad m => Stream m a -> Fold m a b -> m (Fold m a b)
#

Append a stream to a fold to build the fold accumulator incrementally. We can repeatedly call addStream on the same fold to continue building the fold and finally use drive to finish the fold and extract the result. Also see the Streamly.Data.Fold.addOne operation which is a singleton version of addStream.

Definitions:

Example1 expression
addStream stream = Fold.drive stream . Fold.duplicate

Example, build a list incrementally:

Example1 expression
:{pure (Fold.toList :: Fold IO Int [Int])    >>= Fold.addOne 1    >>= Fold.addStream (Stream.enumerateFromTo 2 4)    >>= Fold.drive Stream.nil    >>= print:}[1,2,3,4]

This can be used as an O(n) list append compared to the O(n^2) ++ when used for incrementally building a list.

Example, build a stream incrementally:

Example1 expression
:{pure (Fold.toStream :: Fold IO Int (Stream Identity Int))    >>= Fold.addOne 1    >>= Fold.addStream (Stream.enumerateFromTo 2 4)    >>= Fold.drive Stream.nil    >>= print:}fromList [1,2,3,4]

This can be used as an O(n) stream append compared to the O(n^2) <> when used for incrementally building a stream.

Example, build an array incrementally:

Example1 expression
:{pure (Array.create :: Fold IO Int (Array Int))    >>= Fold.addOne 1    >>= Fold.addStream (Stream.enumerateFromTo 2 4)    >>= Fold.drive Stream.nil    >>= print:}fromList [1,2,3,4]

Example, build an array stream incrementally:

Example1 expression
:{let f :: Fold IO Int (Stream Identity (Array Int))    f = Fold.groupsOf 2 (Array.createOf 3) Fold.toStreamin pure f    >>= Fold.addOne 1    >>= Fold.addStream (Stream.enumerateFromTo 2 4)    >>= Fold.drive Stream.nil    >>= print:}fromList [fromList [1,2],fromList [3,4]]
valueall :: Monad m => (a -> Bool) -> Fold m a Bool
#

Returns True if all elements of the input satisfy the predicate.

Definition:

Example1 expression
all p = Fold.lmap p Fold.and

Example:

Example1 expression
Stream.fold (Fold.all (== 0)) $ Stream.fromList [1,0,1]False
valueany :: Monad m => (a -> Bool) -> Fold m a Bool
#

Returns True if any element of the input satisfies the predicate.

Definition:

Example1 expression
any p = Fold.lmap p Fold.or

Example:

Example1 expression
Stream.fold (Fold.any (== 0)) $ Stream.fromList [1,0,1]True
valuebottom :: (MonadIO m, Unbox a, Ord a) => Int -> Fold m a (MutArray a)
#

Fold the input stream to bottom n elements.

Definition:

Example1 expression
bottom = Fold.bottomBy compare
Example2 expressions
stream = Stream.fromList [2::Int,7,9,3,1,5,6,11,17]Stream.fold (Fold.bottom 3) stream >>= MutArray.toList[1,2,3]

Pre-release

valuechunksBetween :: Int -> Int -> Fold m a b -> Fold m b c -> Fold m a c
#

Group the input stream into groups of elements between low and high. Collection starts in chunks of low and then keeps doubling until we reach high. Each chunk is folded using the provided fold function.

This could be useful, for example, when we are folding a stream of unknown size to a stream of arrays and we want to minimize the number of allocations.

NOTE: this would be an application of "many" using a terminating fold.

Unimplemented

valueconcatSequence :: Fold m b c -> t (Fold m a b) -> Fold m a c
#

concatSequence f t applies folds from stream t sequentially and collects the results using the fold f.

Unimplemented

valuedeleteBy :: Monad m => (a -> a -> Bool) -> a -> Fold m a (Maybe a)
#

Returns the latest element omitting the first occurrence that satisfies the given equality predicate.

Example:

Example1 expression
input = Stream.fromList [1,3,3,5]
> Stream.toList $ Stream.scanMaybe (Fold.deleteBy (==) 3) input
1,3,5
valuedistribute :: Monad m => [Fold m a b] -> Fold m a [b]
#

Distribute one copy of the stream to each fold and collect the results in a container.


                |-------Fold m a b--------|
---stream m a---|                         |---m [b]
                |-------Fold m a b--------|
                |                         |
                           ...
Example1 expression
Stream.fold (Fold.distribute [Fold.sum, Fold.length]) (Stream.enumerateFromTo 1 5)[15,5]
Example1 expression
distribute = Prelude.foldr (Fold.teeWith (:)) (Fold.fromPure [])

This is the consumer side dual of the producer side sequence operation.

Stops when all the folds stop.

valuedistributeScan :: Monad m => m [Fold m a b] -> Scanl m a [b]
#

Distribute the input to the folds returned by an effect. The effect is executed every time an input is processed, and the folds returned by it are added to the distribution list. The scan returns the results of the folds as they complete. To avoid adding the same folds repeatedly, the action must return the folds only once e.g. it can be implemented using modifyIORef replacing the original value by an empty list before returning it.

Example4 expressions
import Data.IORefref <- newIORef [Fold.take 2 Fold.sum, Fold.take 2 Fold.length :: Fold IO Int Int]gen = atomicModifyIORef ref (\xs -> ([], xs))Stream.toList $ Stream.scanl (Fold.distributeScan gen) (Stream.enumerateFromTo 1 10)[[],[],[],[2,3],[],[],[],[],[],[],[]]
valuedrainMapM :: Monad m => (a -> m b) -> Fold m a ()
#

Definitions:

Example2 expressions
drainMapM f = Fold.lmapM f Fold.draindrainMapM f = Fold.foldMapM (void . f)

Drain all input after passing it through a monadic function. This is the dual of mapM_ on stream producers.

valuedrainN :: Monad m => Int -> Fold m a ()
#

A fold that drains the first n elements of its input, running the effects and discarding the results.

Definition:

Example1 expression
drainN n = Fold.take n Fold.drain

Pre-release

valuedrive :: Monad m => Stream m a -> Fold m a b -> m b
#

Drive a fold using the supplied Stream, reducing the resulting expression strictly at each step.

Definition:

Example1 expression
drive = flip Stream.fold

Example:

Example1 expression
Fold.drive (Stream.enumerateFromTo 1 100) Fold.sum5050
valueelem :: (Eq a, Monad m) => a -> Fold m a Bool
#

Return True if the given element is present in the stream.

Definition:

Example1 expression
elem a = Fold.any (== a)
valueelemIndex :: (Eq a, Monad m) => a -> Fold m a (Maybe Int)
#

Returns the first index where a given value is found in the stream.

Definition:

Example1 expression
elemIndex a = Fold.findIndex (== a)
valueelemIndices :: (Monad m, Eq a) => a -> Fold m a (Maybe Int)
#

Returns the index of the latest element if the element matches the given value.

Definition:

Example1 expression
elemIndices a = Fold.findIndices (== a)
valuefind :: Monad m => (a -> Bool) -> Fold m a (Maybe a)
#

Returns the first element that satisfies the given predicate.

valuefindM :: Monad m => (a -> m Bool) -> Fold m a (Maybe a)
#

Returns the first element that satisfies the given predicate.

Pre-release

valuefoldMap :: (Monad m, Monoid b) => (a -> b) -> Fold m a b
#

Definition:

Example1 expression
foldMap f = Fold.lmap f Fold.mconcat

Make a fold from a pure function that folds the output of the function using mappend and mempty.

Example2 expressions
sum = Fold.foldMap Data.Monoid.SumStream.fold sum $ Stream.enumerateFromTo 1 10Sum {getSum = 55}
valuefoldMapM :: (Monad m, Monoid b) => (a -> m b) -> Fold m a b
#

Definition:

Example1 expression
foldMapM f = Fold.lmapM f Fold.mconcat

Make a fold from a monadic function that folds the output of the function using mappend and mempty.

Example2 expressions
sum = Fold.foldMapM (return . Data.Monoid.Sum)Stream.fold sum $ Stream.enumerateFromTo 1 10Sum {getSum = 55}
valuehead :: Monad m => Fold m a (Maybe a)
#

Deprecated. Please use "one" instead

Extract the first element of the stream, if any.

Example1 expression
head = Fold.one
valueindex :: Monad m => Int -> Fold m a (Maybe a)
#

Return the element at the given index.

Definition:

Example1 expression
index = Fold.genericIndex
valueindexed :: Monad m => Fold m (Int, a) b -> Fold m a b
#

Pair each element of a fold input with its index, starting from index 0.

Example1 expression
indexed = Fold.postscanlMaybe Scanl.indexing
valueindexing :: Monad m => Fold m a (Maybe (Int, a))
#

Deprecated. Use Scanl.indexing instead

> indexing = Fold.indexingWith 0 (+ 1)
valueindexingRev :: Monad m => Int -> Fold m a (Maybe (Int, a))
#

Deprecated. Use Scanl.indexingRev instead

> indexingRev n = Fold.indexingWith n (subtract 1)
valueindexingWith :: Monad m => Int -> (Int -> Int) -> Fold m a (Maybe (Int, a))
#

Deprecated. Use Scanl.indexingWith instead

Pair each element of a fold input with its index, starting from index 0.

valuelookup :: (Eq a, Monad m) => a -> Fold m (a, b) (Maybe b)
#

In a stream of (key-value) pairs (a, b), return the value b of the first pair where the key equals the given value a.

Definition:

Example1 expression
lookup x = fmap snd <$> Fold.find ((== x) . fst)
valuemapM :: Monad m => (b -> m c) -> Fold m a b -> Fold m a c
#

Deprecated. Use rmapM instead

Map a monadic function on the output of a fold.

valuemapMaybe :: Monad m => (a -> Maybe b) -> Fold m b r -> Fold m a r
#

mapMaybe f fold maps a Maybe returning function f on the input of the fold, filters out Nothing elements, and return the values extracted from Just.

Example2 expressions
mapMaybe f = Fold.lmap f . Fold.catMaybesmapMaybe f = Fold.mapMaybeM (return . f)
Example3 expressions
f x = if even x then Just x else Nothingfld = Fold.mapMaybe f Fold.toListStream.fold fld (Stream.enumerateFromTo 1 10)[2,4,6,8,10]
valuemapMaybeM :: Monad m => (a -> m (Maybe b)) -> Fold m b r -> Fold m a r
#
Example1 expression
mapMaybeM f = Fold.lmapM f . Fold.catMaybes
valuemaximum :: (Monad m, Ord a) => Fold m a (Maybe a)
#

Determine the maximum element in a stream.

Definitions:

Example2 expressions
maximum = Fold.maximumBy comparemaximum = Fold.foldl1' max

Same as the following but without a default maximum. The Max Monoid uses the minBound as the default maximum:

Example1 expression
maximum = fmap Data.Semigroup.getMax $ Fold.foldMap Data.Semigroup.Max
valuemaybe :: Monad m => (a -> Maybe b) -> Fold m a (Maybe b)
#

Consume a single input and transform it using the supplied Maybe returning function.

Pre-release

valuemconcat :: (Monad m, Monoid a) => Fold m a a
#

Monoid concat. Fold an input stream consisting of monoidal elements using mappend and mempty.

Definition:

Example1 expression
mconcat = Fold.sconcat mempty
Example2 expressions
monoids = fmap Data.Monoid.Sum $ Stream.enumerateFromTo 1 10Stream.fold Fold.mconcat monoidsSum {getSum = 55}
valuemean :: (Monad m, Fractional a) => Fold m a a
#

Compute a numerically stable arithmetic mean of all elements in the input stream.

valueminimum :: (Monad m, Ord a) => Fold m a (Maybe a)
#

Determine the minimum element in a stream using the supplied comparison function.

Definitions:

Example2 expressions
minimum = Fold.minimumBy compareminimum = Fold.foldl1' min

Same as the following but without a default minimum. The Min Monoid uses the maxBound as the default maximum:

Example1 expression
maximum = fmap Data.Semigroup.getMin $ Fold.foldMap Data.Semigroup.Min
valuenotElem :: (Eq a, Monad m) => a -> Fold m a Bool
#

Returns True if the given element is not present in the stream.

Definition:

Example1 expression
notElem a = Fold.all (/= a)
valuenull :: Monad m => Fold m a Bool
#

Consume one element, return True if successful else return False. In other words, test if the input is empty or not.

WARNING! It consumes one element if the stream is not empty. If that is not what you want please use the eof parser instead.

Definition:

Example1 expression
null = fmap isJust Fold.one
valueone :: Monad m => Fold m a (Maybe a)
#

Take one element from the stream and stop.

Definition:

Example1 expression
one = Fold.maybe Just

This is similar to the stream Stream.uncons operation.

valuepartition
  1. :: Monad m
  2. => Fold m b x
  3. -> Fold m c y
  4. -> Fold m (Either b c) (x, y)
#

Compose two folds such that the combined fold accepts a stream of Either and routes the Left values to the first fold and Right values to the second fold.

Definition:

Example1 expression
partition = Fold.partitionBy id
valuepartitionBy
  1. :: Monad m
  2. => a -> Either b c
  3. -> Fold m b x
  4. -> Fold m c y
  5. -> Fold m a (x, y)
#

Same as partitionByM but with a pure partition function.

Example, count even and odd numbers in a stream:

Example1 expression
:{ let f = Fold.partitionBy (\n -> if even n then Left n else Right n)                     (fmap (("Even " ++) . show) Fold.length)                     (fmap (("Odd "  ++) . show) Fold.length)  in Stream.fold f (Stream.enumerateFromTo 1 100):}("Even 50","Odd 50")

Pre-release

valuepartitionByM
  1. :: Monad m
  2. => a -> m (Either b c)
  3. -> Fold m b x
  4. -> Fold m c y
  5. -> Fold m a (x, y)
#

Partition the input over two folds using an Either partitioning predicate.


                                    |-------Fold b x--------|
-----stream m a --> (Either b c)----|                       |----(x,y)
                                    |-------Fold c y--------|

Example, send input to either fold randomly:

Example5 expressions
:set -package randomimport System.Random (randomIO)randomly a = randomIO >>= \x -> return $ if x then Left a else Right af = Fold.partitionByM randomly Fold.length Fold.lengthStream.fold f (Stream.enumerateFromTo 1 100)...

Example, send input to the two folds in a proportion of 2:1:

Example3 expressions
:set -fno-warn-unrecognised-warning-flags:set -fno-warn-x-partial:{proportionately m n = do ref <- newIORef $ cycle $ concat [replicate m Left, replicate n Right] return $ \a -> do     r <- readIORef ref     writeIORef ref $ tail r     return $ Prelude.head r a:}
Example1 expression
:{main = do g <- proportionately 2 1 let f = Fold.partitionByM g Fold.length Fold.length r <- Stream.fold f (Stream.enumerateFromTo (1 :: Int) 100) print r:}
Example1 expression
main(67,33)

This is the consumer side dual of the producer side mergeBy operation.

When one fold is done, any input meant for it is ignored until the other fold is also done.

Stops when both the folds stop.

See also: partitionByFstM and partitionByMinM.

Pre-release

valueproduct :: (Monad m, Num a, Eq a) => Fold m a a
#

Determine the product of all elements of a stream of numbers. Returns multiplicative identity (1) when the stream is empty. The fold terminates when it encounters (0) in its input.

Same as the following but terminates on multiplication by 0:

Example1 expression
product = fmap Data.Monoid.getProduct $ Fold.foldMap Data.Monoid.Product
valueprune :: (a -> Bool) -> Fold m a (Maybe a)
#

Strip all leading and trailing occurrences of an element passing a predicate and make all other consecutive occurrences uniq.

> prune p = Stream.dropWhileAround p $ Stream.uniqBy (x y -> p x && p y)
> Stream.prune isSpace (Stream.fromList "  hello      world!   ")
"hello world!"

Space: O(1)

Unimplemented

valuerollingHash :: (Monad m, Enum a) => Fold m a Int64
#

Compute an Int sized polynomial rolling hash of a stream.

Example1 expression
rollingHash = Fold.rollingHashWithSalt Fold.defaultSalt
valuerollingHashFirstN :: (Monad m, Enum a) => Int -> Fold m a Int64
#

Compute an Int sized polynomial rolling hash of the first n elements of a stream.

Example1 expression
rollingHashFirstN n = Fold.take n Fold.rollingHash

Pre-release

valuerollingMap :: Monad m => (Maybe a -> a -> b) -> Fold m a b
#
Example1 expression
rollingMap f = Fold.rollingMapM (\x y -> return $ f x y)
valuerollingMapM :: Monad m => (Maybe a -> a -> m b) -> Fold m a b
#

Apply a function on every two successive elements of a stream. The first argument of the map function is the previous element and the second argument is the current element. When processing the very first element in the stream, the previous element is Nothing.

Pre-release

valuesampleFromthen :: Monad m => Int -> Int -> Fold m a b -> Fold m a b
#

sampleFromthen offset stride samples the element at offset index and then every element at strides of stride.

valuesatisfy :: Monad m => (a -> Bool) -> Fold m a (Maybe a)
#

Consume a single element and return it if it passes the predicate else return Nothing.

Definition:

Example1 expression
satisfy f = Fold.maybe (\a -> if f a then Just a else Nothing)

Pre-release

valuesconcat :: (Monad m, Semigroup a) => a -> Fold m a a
#

Semigroup concat. Append the elements of an input stream to a provided starting value.

Definition:

Example1 expression
sconcat = Fold.foldl' (<>)
Example2 expressions
semigroups = fmap Data.Monoid.Sum $ Stream.enumerateFromTo 1 10Stream.fold (Fold.sconcat 10) semigroupsSum {getSum = 65}
valuesequence :: Monad m => Fold m a (m b) -> Fold m a b
#

Deprecated. Use "rmapM id" instead

Flatten the monadic output of a fold to pure output.

valueslide2 :: Monad m => Fold m (a, Maybe a) b -> Fold m a b
#

Provide a sliding window of length 2 elements.

See Streamly.Internal.Data.Fold.Window.

valuesplitAt :: Monad m => Int -> Fold m a b -> Fold m a c -> Fold m a (b, c)
#

splitAt n f1 f2 composes folds f1 and f2 such that first n elements of its input are consumed by fold f1 and the rest of the stream is consumed by fold f2.

Example1 expression
let splitAt_ n xs = Stream.fold (Fold.splitAt n Fold.toList Fold.toList) $ Stream.fromList xs
Example1 expression
splitAt_ 6 "Hello World!"("Hello ","World!")
Example1 expression
splitAt_ (-1) [1,2,3]([],[1,2,3])
Example1 expression
splitAt_ 0 [1,2,3]([],[1,2,3])
Example1 expression
splitAt_ 1 [1,2,3]([1],[2,3])
Example1 expression
splitAt_ 3 [1,2,3]([1,2,3],[])
Example1 expression
splitAt_ 4 [1,2,3]([1,2,3],[])
splitAt n f1 f2 = Fold.splitWith (,) (Fold.take n f1) f2

Internal

valuestdDev :: (Monad m, Floating a) => Fold m a a
#

Deprecated. Use the streamly-statistics package instead

Compute a numerically stable (population) standard deviation over all elements in the input stream.

valuesum :: (Monad m, Num a) => Fold m a a
#

Determine the sum of all elements of a stream of numbers. Returns additive identity (0) when the stream is empty. Note that this is not numerically stable for floating point numbers.

Example1 expression
sum = Fold.fromScanl (Scanl.cumulativeScan Scanl.incrSum)

Same as following but numerically stable:

Example2 expressions
sum = Fold.foldl' (+) 0sum = fmap Data.Monoid.getSum $ Fold.foldMap Data.Monoid.Sum
valuetakeEndBySeq
  1. :: (MonadIO m, Unbox a, Enum a, Eq a)
  2. => Array a
  3. -> Fold m a b
  4. -> Fold m a b
#

Continue taking the input until the input sequence matches the supplied sequence, taking the supplied sequence as well. If the pattern is empty this acts as an identity fold.

Example3 expressions
s = Stream.fromList "Gauss---Euler---Noether"f = Fold.takeEndBySeq (Array.fromList "---") Fold.toListStream.fold f s"Gauss---"
Example1 expression
Stream.fold Fold.toList $ Stream.foldMany f s["Gauss---","Euler---","Noether"]

Uses Rabin-Karp algorithm for substring search.

See also: Streamly.Data.Stream.splitOnSeq and Streamly.Data.Stream.splitEndBySeq.

Pre-release

valuetakeEndBySeq_
  1. :: (MonadIO m, Unbox a, Enum a, Eq a)
  2. => Array a
  3. -> Fold m a b
  4. -> Fold m a b
#

Like takeEndBySeq but discards the matched sequence.

Example3 expressions
s = Stream.fromList "Gauss---Euler---Noether"f = Fold.takeEndBySeq_ (Array.fromList "---") Fold.toListStream.fold f s"Gauss"
Example1 expression
Stream.fold Fold.toList $ Stream.foldMany f s["Gauss","Euler","Noether"]

See also: Streamly.Data.Stream.splitOnSeq and Streamly.Data.Stream.splitEndBySeq_.

Pre-release

valuetee :: Monad m => Fold m a b -> Fold m a c -> Fold m a (b, c)
#

Distribute one copy of the stream to each fold and zip the results.

                |-------Fold m a b--------|
---stream m a---|                         |---m (b,c)
                |-------Fold m a c--------|

Definition:

Example1 expression
tee = Fold.teeWith (,)

Example:

Example2 expressions
t = Fold.tee Fold.sum Fold.lengthStream.fold t (Stream.enumerateFromTo 1.0 100.0)(5050.0,100)
valuethe :: (Monad m, Eq a) => Fold m a (Maybe a)
#

Terminates with Nothing as soon as it finds an element different than the previous one, returns the element if the entire input consists of the same element.

valuetoStream :: (Monad m, Monad n) => Fold m a (Stream n a)
#

A fold that buffers its input to a pure stream.

Warning! working on large streams accumulated as buffers in memory could be very inefficient, consider using Streamly.Data.Array instead.

Example1 expression
toStream = fmap Stream.fromList Fold.toList

Pre-release

valuetoStreamRev :: (Monad m, Monad n) => Fold m a (Stream n a)
#

Buffers the input stream to a pure stream in the reverse order of the input.

Example1 expression
toStreamRev = fmap Stream.fromList Fold.toListRev

Warning! working on large streams accumulated as buffers in memory could be very inefficient, consider using Streamly.Data.Array instead.

Pre-release

valuetop :: (MonadIO m, Unbox a, Ord a) => Int -> Fold m a (MutArray a)
#

Fold the input stream to top n elements.

Definition:

Example1 expression
top = Fold.topBy compare
Example2 expressions
stream = Stream.fromList [2::Int,7,9,3,1,5,6,11,17]Stream.fold (Fold.top 3) stream >>= MutArray.toList[17,11,9]

Pre-release

valuetopBy
  1. :: (MonadIO m, Unbox a)
  2. => a -> a -> Ordering
  3. -> Int
  4. -> Fold m a (MutArray a)
#

Get the top n elements using the supplied comparison function.

To get bottom n elements instead:

Example1 expression
bottomBy cmp = Fold.topBy (flip cmp)

Example:

Example2 expressions
stream = Stream.fromList [2::Int,7,9,3,1,5,6,11,17]Stream.fold (Fold.topBy compare 3) stream >>= MutArray.toList[17,11,9]

Pre-release

valuetrace :: Monad m => (a -> m b) -> Fold m a r -> Fold m a r
#

Apply a monadic function to each element flowing through and discard the results.

Example1 expression
Stream.fold (Fold.trace print Fold.drain) $ (Stream.enumerateFromTo (1 :: Int) 2)12
Example1 expression
trace f = Fold.lmapM (Fold.tracing f)

Pre-release

valuetracing :: Monad m => (a -> m b) -> a -> m a
#

Apply a monadic function on the input and return the input.

Example1 expression
Stream.fold (Fold.lmapM (Fold.tracing print) Fold.drain) $ (Stream.enumerateFromTo (1 :: Int) 2)12

Pre-release

valueunfoldMany :: Monad m => Unfold m a b -> Fold m b c -> Fold m a c
#

Unfold and flatten the input stream of a fold.

Stream.fold (unfoldMany u f) = Stream.fold f . Stream.unfoldMany u

Pre-release

valueuniqBy :: Monad m => (a -> a -> Bool) -> Fold m a (Maybe a)
#

Return the latest unique element using the supplied comparison function. Returns Nothing if the current element is same as the last element otherwise returns Just.

Example, strip duplicate path separators:

Example2 expressions
input = Stream.fromList "//a//b"f x y = x == '/' && y == '/'
> Stream.toList $ Stream.scanMaybe (Fold.uniqBy f) input

"ab"

Space: O(1)

Pre-release

valueunzip :: Monad m => Fold m a x -> Fold m b y -> Fold m (a, b) (x, y)
#

Send the elements of tuples in a stream of tuples through two different folds.


                          |-------Fold m a x--------|
---------stream of (a,b)--|                         |----m (x,y)
                          |-------Fold m b y--------|

Definition:

Example1 expression
unzip = Fold.unzipWith id

This is the consumer side dual of the producer side zip operation.

valueunzipWith
  1. :: Monad m
  2. => a -> (b, c)
  3. -> Fold m b x
  4. -> Fold m c y
  5. -> Fold m a (x, y)
#

Split elements in the input stream into two parts using a pure splitter function, direct each part to a different fold and zip the results.

Definitions:

Example2 expressions
unzipWith f = Fold.unzipWithM (return . f)unzipWith f fld1 fld2 = Fold.lmap f (Fold.unzip fld1 fld2)

This fold terminates when both the input folds terminate.

Pre-release

valueunzipWithM
  1. :: Monad m
  2. => a -> m (b, c)
  3. -> Fold m b x
  4. -> Fold m c y
  5. -> Fold m a (x, y)
#

Like unzipWith but with a monadic splitter function.

Definition:

Example1 expression
unzipWithM k f1 f2 = Fold.lmapM k (Fold.unzip f1 f2)

Pre-release

valuevariance :: (Monad m, Fractional a) => Fold m a a
#

Deprecated. Use the streamly-statistics package instead

Compute a numerically stable (population) variance over all elements in the input stream.

valuewith
  1. :: Fold m (s, a) b -> Fold m a b
  2. -> ((s, a) -> c) -> Fold m (s, a) b -> Fold m (s, a) b
  3. -> (s, a) -> c
  4. -> Fold m a b
  5. -> Fold m a b
#

Change the predicate function of a Fold from a -> b to accept an additional state input (s, a) -> b. Convenient to filter with an addiitonal index or time input.

Example1 expression
filterWithIndex = Fold.with Fold.indexed Fold.filter
filterWithAbsTime = with timestamped filter
filterWithRelTime = with timeIndexed filter

Pre-release

valuezipStream :: Monad m => Stream m a -> Fold m (a, b) x -> Fold m b x
#

Zip a stream with the input of a fold.

Example1 expression
zip = Fold.zipStreamWithM (curry return)

Unimplemented

valuezipStreamWithM :: (a -> b -> m c) -> Stream m a -> Fold m c x -> Fold m b x
#

Zip a stream with the input of a fold using the supplied function.

Unimplemented

valueclassify
  1. :: (Monad m, Ord k)
  2. => a -> k
  3. -> Fold m a b
  4. -> Fold m a (m (Map k b), Maybe (k, b))
#

Deprecated. Use classifyScan instead

Folds the values for each key using the supplied fold. When scanning, as soon as the fold is complete, its result is available in the second component of the tuple. The first component of the tuple is a snapshot of the in-progress folds.

Once the fold for a key is done, any future values of the key are ignored.

Definition:

> classify f fld = Fold.demux f (const fld)
valueclassifyIO
  1. :: (MonadIO m, Ord k)
  2. => a -> k
  3. -> Fold m a b
  4. -> Fold m a (m (Map k b), Maybe (k, b))
#

Deprecated. Use classifyScanIO instead

Same as classify except that it uses mutable IORef cells in the Map providing better performance. Be aware that if this is used as a scan, the values in the intermediate Maps would be mutable.

Definitions:

> classifyIO f fld = Fold.demuxIO f (const fld)
valueclassifyScanIO
  1. :: (MonadIO m, Ord k)
  2. => a -> k
  3. -> Fold m a b
  4. -> Scanl m a (Maybe (k, b))
#

This is a specialized version of classifyScan that uses mutable IO cells as scan accumulators for better performance.

TODO: To drain the final in-progress folds this requires the drain step of Scanl to be streaming.

valuecountDistinct :: (Monad m, Ord a) => Fold m a Int
#

Count non-duplicate elements in the stream.

Definition:

Example2 expressions
countDistinct = fmap Set.size Fold.toSetcountDistinct = Fold.postscanl Scanl.nub $ Fold.catMaybes $ Fold.length

The memory used is proportional to the number of distinct elements in the stream, to guard against using too much memory use it as a scan and terminate if the count reaches more than a threshold.

Space: \mathcal{O}(n)

Pre-release

valuecountDistinctInt :: Monad m => Fold m Int Int
#

Like countDistinct but specialized to a stream of Int, for better performance.

Definition:

Example2 expressions
countDistinctInt = fmap IntSet.size Fold.toIntSetcountDistinctInt = Fold.postscanl Scanl.nubInt $ Fold.catMaybes $ Fold.length

Pre-release

valuedemux
  1. :: (Monad m, Ord k)
  2. => a -> k
  3. -> a -> m (Fold m a b)
  4. -> Fold m a (m (Map k b), Maybe (k, b))
#

Deprecated. Use demuxScan instead

demux getKey getFold: In a key value stream, fold values corresponding to each key using a key specific fold. getFold is invoked to generate a key specific fold when a key is encountered for the first time in the stream.

The first component of the output tuple is a key-value Map of in-progress folds. The fold returns the fold result as the second component of the output tuple whenever a fold terminates.

If a fold terminates, another instance of the fold is started upon receiving an input with that key, getFold is invoked again whenever the key is encountered again.

This can be used to scan a stream and collect the results from the scan output.

Since the fold generator function is monadic we can add folds dynamically. For example, we can maintain a Map of keys to folds in an IORef and lookup the fold from that corresponding to a key. This Map can be changed dynamically, folds for new keys can be added or folds for old keys can be deleted or modified.

Compare with classify, the fold in classify is a static fold.

Pre-release

valuedemuxIO
  1. :: (MonadIO m, Ord k)
  2. => a -> k
  3. -> a -> m (Fold m a b)
  4. -> Fold m a (m (Map k b), Maybe (k, b))
#

Deprecated. Use demuxScanIO instead

This is specialized version of demux that uses mutable IO cells as fold accumulators for better performance.

Keep in mind that the values in the returned Map may be changed by the ongoing fold if you are using those concurrently in another thread.

valuedemuxKvToMap
  1. :: (Monad m, Ord k)
  2. => k -> m (Maybe (Fold m a b))
  3. -> Fold m (k, a) (Map k b)
#

Fold a stream of key value pairs using a function that maps keys to folds.

Definition:

Example1 expression
demuxKvToMap f = Fold.demuxerToContainer fst (Fold.lmap snd . f)

Example:

Example2 expressions
import Data.Map (Map):{ let f "SUM" = return (Just Fold.sum)     f _ = return (Just Fold.product)     input = Stream.fromList [("SUM",1),("PRODUCT",2),("SUM",3),("PRODUCT",4)]  in Stream.fold (Fold.demuxKvToMap f) input :: IO (Map String Int):}fromList [("PRODUCT",8),("SUM",4)]

Pre-release

valuedemuxScanGenericIO
  1. :: (MonadIO m, IsMap f, Traversable f)
  2. => a -> Key f
  3. -> Key f -> m (Maybe (Fold m a b))
  4. -> Scanl m a (m (f b), Maybe (Key f, b))
#

This is a specialized version of demux that uses mutable IO cells as fold accumulators for better performance.

Keep in mind that the values in the returned Map may be changed by the ongoing fold if you are using those concurrently in another thread.

valuedemuxScanIO
  1. :: (MonadIO m, Ord k)
  2. => a -> k
  3. -> k -> m (Maybe (Fold m a b))
  4. -> Scanl m a (Maybe (k, b))
#

This is a specialized version of demuxScan that uses mutable IO cells as scan accumulators for better performance.

TODO: To drain the final in-progress folds this requires the drain step of Scanl to be streaming.

valuedemuxToMap
  1. :: (Monad m, Ord k)
  2. => a -> k
  3. -> a -> m (Fold m a b)
  4. -> Fold m a (Map k b)
#

Deprecated. Use demuxerToMap instead

This collects all the results of demux in a Map.

valuedemuxerToMap
  1. :: (Monad m, Ord k)
  2. => a -> k
  3. -> k -> m (Maybe (Fold m a b))
  4. -> Fold m a (Map k b)
#

demuxerToMap getKey getFold: In a key value stream, fold values corresponding to each key using a key specific fold. getFold is invoked to generate a key specific fold when a key is encountered for the first time in the stream.

If a fold terminates, another instance of the fold is started upon receiving an input with that key, getFold is invoked again whenever the key is encountered again.

This combinator can be used to scan a stream and collect the results from the scan output.

Since the fold generator function is monadic, folds for new keys can be added dynamically or folds for old keys can be deleted or modified. For example, we can maintain a Map of keys to folds in an IORef and lookup the fold from that corresponding to a key. This Map can be changed dynamically.

Note that this fold never terminates. Inputs that do not correspond to a fold in the map are dropped.

Compare with classify, the fold in classify is a static fold.

Pre-release

valuefrequency :: (Monad m, Ord a) => Fold m a (Map a Int)
#

Determine the frequency of each element in the stream.

You can just collect the keys of the resulting map to get the unique elements in the stream.

Definition:

Example1 expression
frequency = Fold.toMap id Fold.length
valuekvToMap :: (Monad m, Ord k) => Fold m a b -> Fold m (k, a) (Map k b)
#

Given an input stream of key value pairs and a fold for values, fold all the values belonging to each key. Useful for map/reduce, bucketizing the input in different bins or for generating histograms.

Definition:

Example1 expression
kvToMap = Fold.toMap fst . Fold.lmap snd

Example:

Example1 expression
:{ let input = Stream.fromList [("ONE",1),("ONE",1.1),("TWO",2), ("TWO",2.2)]  in Stream.fold (Fold.kvToMap Fold.toList) input:}fromList [("ONE",[1.0,1.1]),("TWO",[2.0,2.2])]

Pre-release

valuenub :: (Monad m, Ord a) => Fold m a (Maybe a)
#

Used as a scan. Returns Just for the first occurrence of an element, returns Nothing for any other occurrences.

Example:

Example1 expression
stream = Stream.fromList [1::Int,1,2,3,4,4,5,1,5,7]
> Stream.toList $ Stream.scanMaybe Fold.nub stream
1,2,3,4,5,7

Pre-release

valuetoIntSet :: Monad m => Fold m Int IntSet
#

Fold the input to an int set. For integer inputs this performs better than toSet.

Definition:

Example1 expression
toIntSet = Fold.foldl' (flip IntSet.insert) IntSet.empty
valuetoMap :: (Monad m, Ord k) => (a -> k) -> Fold m a b -> Fold m a (Map k b)
#

Split the input stream based on a key field and fold each split using the given fold. Useful for map/reduce, bucketizing the input in different bins or for generating histograms.

Example:

Example2 expressions
import Data.Map.Strict (Map):{ let input = Stream.fromList [("ONE",1),("ONE",1.1),("TWO",2), ("TWO",2.2)]     classify = Fold.toMap fst (Fold.lmap snd Fold.toList)  in Stream.fold classify input :: IO (Map String [Double]):}fromList [("ONE",[1.0,1.1]),("TWO",[2.0,2.2])]

Once the classifier fold terminates for a particular key any further inputs in that bucket are ignored.

Space used is proportional to the number of keys seen till now and monotonically increases because it stores whether a key has been seen or not.

See demuxToMap for a more powerful version where you can use a different fold for each key. A simpler version of toMap retaining only the last value for a key can be written as:

Example1 expression
toMap = Fold.foldl' (\kv (k, v) -> Map.insert k v kv) Map.empty

Stops: never

Pre-release

valuetoMapIO
  1. :: (MonadIO m, Ord k)
  2. => a -> k
  3. -> Fold m a b
  4. -> Fold m a (Map k b)
#

Same as toMap but maybe faster because it uses mutable cells as fold accumulators in the Map.

valuetoSet :: (Monad m, Ord a) => Fold m a (Set a)
#

Fold the input to a set.

Definition:

Example1 expression
toSet = Fold.foldl' (flip Set.insert) Set.empty
valuecumulative :: Fold m (a, Maybe a) b -> Fold m a b
#

Convert an incremental fold to a cumulative fold using the entire input stream as a single window.

Example1 expression
cumulative f = Fold.lmap (\x -> (x, Nothing)) f
valuewindowLength :: (Monad m, Num b) => Fold m (a, Maybe a) b
#

The number of elements in the rolling window.

This is the 0th power sum.

Example1 expression
length = Fold.windowPowerSum 0
valuewindowLmap :: (c -> a) -> Fold m (a, Maybe a) b -> Fold m (c, Maybe c) b
#

Map a function on the incoming as well as outgoing element of a rolling window fold.

Example2 expressions
:set -fno-warn-deprecationslmap f = Fold.lmap (bimap f (f <$>))
valuewindowMaximum :: (MonadIO m, Unbox a, Ord a) => Int -> Fold m a (Maybe a)
#

The maximum element in a rolling window.

See the performance related comments in minimum.

If you want to compute the maximum of the entire stream Fold.maximum would be much faster.

Time: \mathcal{O}(n*w) where w is the window size.

valuewindowMean :: (Monad m, Fractional a) => Fold m (a, Maybe a) a
#

Arithmetic mean of elements in a sliding window:

\mu = \frac{\sum_{i=1}^n x_{i}}{n}

This is also known as the Simple Moving Average (SMA) when used in the sliding window and Cumulative Moving Avergae (CMA) when used on the entire stream.

Example1 expression
mean = Fold.teeWith (/) Fold.windowSum Fold.windowLength

Space: \mathcal{O}(1)

Time: \mathcal{O}(n)

valuewindowMinimum :: (MonadIO m, Unbox a, Ord a) => Int -> Fold m a (Maybe a)
#

Find the minimum element in a rolling window.

This implementation traverses the entire window buffer to compute the minimum whenever we demand it. It performs better than the dequeue based implementation in streamly-statistics package when the window size is small (< 30).

If you want to compute the minimum of the entire stream Streamly.Data.Fold.minimum is much faster.

Time: \mathcal{O}(n*w) where w is the window size.

valuewindowPowerSum :: (Monad m, Num a) => Int -> Fold m (a, Maybe a) a
#

Sum of the kth power of all the elements in a rolling window:

S_k = \sum_{i=1}^n x_{i}^k

Example1 expression
windowPowerSum k = Fold.windowLmap (^ k) Fold.windowSum

Space: \mathcal{O}(1)

Time: \mathcal{O}(n)

valuewindowPowerSumFrac :: (Monad m, Floating a) => a -> Fold m (a, Maybe a) a
#

Like powerSum but powers can be negative or fractional. This is slower than powerSum for positive intergal powers.

Example1 expression
windowPowerSumFrac p = Fold.windowLmap (** p) Fold.windowSum
valuewindowRange :: (MonadIO m, Unbox a, Ord a) => Int -> Fold m a (Maybe (a, a))
#

Determine the maximum and minimum in a rolling window.

If you want to compute the range of the entire stream Fold.teeWith (,) Fold.maximum Fold.minimum would be much faster.

Space: \mathcal{O}(n) where n is the window size.

Time: \mathcal{O}(n*w) where w is the window size.

valuewindowRollingMap
  1. :: Monad m
  2. => Maybe a -> a -> Maybe b
  3. -> Fold m (a, Maybe a) (Maybe b)
#

Apply a pure function on the latest and the oldest element of the window.

Example1 expression
windowRollingMap f = Fold.windowRollingMapM (\x y -> return $ f x y)
valuewindowSum :: (Monad m, Num a) => Fold m (a, Maybe a) a
#

Sum of all the elements in a rolling window:

S = \sum_{i=1}^n x_{i}

This is the first power sum.

Example1 expression
windowSum = Fold.windowPowerSum 1

Uses Kahan-Babuska-Neumaier style summation for numerical stability of floating precision arithmetic.

Space: \mathcal{O}(1)

Time: \mathcal{O}(n)

valuewindowSumInt :: (Monad m, Integral a) => Fold m (a, Maybe a) a
#

The sum of all the elements in a rolling window. The input elements are required to be intergal numbers.

This was written in the hope that it would be a tiny bit faster than sum for Integral values. But turns out that sum is 2% faster than this even for intergal values!

Internal

valuebefore :: Monad m => m x -> Fold m a b -> Fold m a b
#

Run a side effect before the initialization of the fold.

valuebracketIO
  1. :: (MonadIO m, MonadCatch m)
  2. => IO x
  3. -> x -> IO c
  4. -> x -> Fold m a b
  5. -> Fold m a b
#

bracketIO before after between runs before and invokes between using its output, then runs the fold generated by between. If the fold ends normally, due to an exception or if it is garbage collected prematurely then after is run with the output of before as argument.

If before or after throw an exception that exception is thrown.

valuefinallyIO :: (MonadIO m, MonadCatch m) => IO b -> Fold m a b -> Fold m a b
#

Run a side effect whenever the fold stops normally, aborts due to an exception or is garbage collected.

valueonException :: MonadCatch m => m x -> Fold m a b -> Fold m a b
#

onException action fold runs action whenever the fold throws an exception. The action is executed on any exception whether it is in initial, step or extract action of the fold.

The exception is not caught, simply rethrown. If the action itself throws an exception that exception is thrown instead of the original exception.

Internal