HORIZON HASKELLDocslts/ghc-9.10.xc74966e2026-09-27Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · c74966e · 2026-09-27

Modulefoldl-1.4.18Haskell2010

Control.Foldl

This module provides efficient and streaming left folds that you can combine using Applicative style.

Import this module qualified to avoid clashing with the Prelude:

Example1 expression
import qualified Control.Foldl as Foldl

Use fold to apply a Fold to a list:

Example1 expression
Foldl.fold Foldl.sum [1..100]5050

Folds are Applicatives, so you can combine them using Applicative combinators:

Example2 expressions
import Control.Applicativelet average = (/) <$> Foldl.sum <*> Foldl.genericLength

… or you can use do notation if you enable the ApplicativeDo language extension:

Example2 expressions
:set -XApplicativeDolet average = do total <- Foldl.sum; count <- Foldl.genericLength; return (total / count)

… or you can use the fact that the Fold type implements Num to do this:

Example1 expression
let average = Foldl.sum / Foldl.genericLength

These combined folds will still traverse the list only once, streaming efficiently over the list in constant space without space leaks:

Example2 expressions
Foldl.fold average [1..10000000]5000000.5Foldl.fold ((,) <$> Foldl.minimum <*> Foldl.maximum) [1..10000000](Just 1,Just 10000000)

You might want to try enabling the -flate-dmd-anal flag when compiling executables that use this library to further improve performance.

  • 6 types
  • 3 classes
  • 79 values
  • Packagefoldl-1.4.18
  • Exports89
  • LanguageHaskell2010
  • LicenceBSD-3-Clause
  • SourceFoldl.hs

Fold Types

2 declarations
datadata Fold a b
#

Efficient representation of a left fold that preserves the fold's step function, initial accumulator, and extraction function

This allows the Applicative instance to assemble derived folds that traverse the container only once

A 'Fold a b' processes elements of type a and results in a value of type b.

Constructors

  • forall x. Fold (x -> a -> x) x (x -> b)

    Fold step initial extract

Instances15Choice, Closed, Costrong, Profunctor, Semigroupoid, Cosieve, …
datadata FoldM (m :: Type -> Type) a b
#

Like Fold, but monadic.

A 'FoldM m a b' processes elements of type a and results in a monadic value of type m b.

Constructors

  • forall x. FoldM (x -> a -> m x) (m x) (x -> m b)

    FoldM step initial extract

Instances9Profunctor, Functor, Applicative, Extend, Floating, Fractional, …

Folding

5 declarations
valuescan :: Fold a b -> [a] -> [b]
#

Convert a strict left Fold into a scan

Example1 expression
Foldl.scan Foldl.length [1..5][0,1,2,3,4,5]
valueprescan :: Traversable t => Fold a b -> t a -> t b
#

Convert a Fold into a prescan for any Traversable type

"Prescan" means that the last element of the scan is not included

Example1 expression
Foldl.prescan Foldl.length [1..5][0,1,2,3,4]
valuepostscan :: Traversable t => Fold a b -> t a -> t b
#

Convert a Fold into a postscan for any Traversable type

"Postscan" means that the first element of the scan is not included

Example1 expression
Foldl.postscan Foldl.length [1..5][1,2,3,4,5]

Folds

32 declarations
valuehead :: Fold a (Maybe a)
#

Get the first element of a container or return Nothing if the container is empty

valuelast :: Fold a (Maybe a)
#

Get the last element of a container or return Nothing if the container is empty

valuelastDef :: a -> Fold a a
#

Get the last element of a container or return a default value if the container is empty

valueall :: (a -> Bool) -> Fold a Bool
#

(all predicate) returns True if all elements satisfy the predicate, False otherwise

valueany :: (a -> Bool) -> Fold a Bool
#

(any predicate) returns True if any element satisfies the predicate, False otherwise

valuesum :: Num a => Fold a a
#

Computes the sum of all elements

valueproduct :: Num a => Fold a a
#

Computes the product of all elements

valuemean :: Fractional a => Fold a a
#

Compute a numerically stable arithmetic mean of all elements

valuevariance :: Fractional a => Fold a a
#

Compute a numerically stable (population) variance over all elements

valuestd :: Floating a => Fold a a
#

Compute a numerically stable (population) standard deviation over all elements

valuemaximumBy :: (a -> a -> Ordering) -> Fold a (Maybe a)
#

Computes the maximum element with respect to the given comparison function

valueminimumBy :: (a -> a -> Ordering) -> Fold a (Maybe a)
#

Computes the minimum element with respect to the given comparison function

valueelem :: Eq a => a -> Fold a Bool
#

(elem a) returns True if the container has an element equal to a, False otherwise

valuefind :: (a -> Bool) -> Fold a (Maybe a)
#

(find predicate) returns the first element that satisfies the predicate or Nothing if no element satisfies the predicate

valueindex :: Int -> Fold a (Maybe a)
#

(index n) returns the nth element of the container, or Nothing if the container has an insufficient number of elements

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

(lookup a) returns the element paired with the first matching item, or Nothing if none matches

valueelemIndex :: Eq a => a -> Fold a (Maybe Int)
#

(elemIndex a) returns the index of the first element that equals a, or Nothing if no element matches

valuefindIndex :: (a -> Bool) -> Fold a (Maybe Int)
#

(findIndex predicate) returns the index of the first element that satisfies the predicate, or Nothing if no element satisfies the predicate

valuemapM_ :: Monad m => (a -> m ()) -> FoldM m a ()
#

Converts an effectful function to a fold. Specialized version of sink.

valuesink :: (Monoid w, Monad m) => (a -> m w) -> FoldM m a w
#

Converts an effectful function to a fold

sink (f <> g) = sink f <> sink g -- if `(<>)` is commutative
sink mempty = mempty

Generic Folds

Container Folds

valuelist :: Fold a [a]
#

Fold all values into a list

valuerevList :: Fold a [a]
#

Fold all values into a list, in reverse order

valuenub :: Ord a => Fold a [a]
#

O(n log n). Fold values into a list with duplicates removed, while preserving their first occurrences

valueeqNub :: Eq a => Fold a [a]
#

O(n^2). Fold values into a list with duplicates removed, while preserving their first occurrences

valuemap :: Ord a => Fold (a, b) (Map a b)
#

Fold pairs into a map.

valuefoldByKeyMap :: Ord k => Fold a b -> Fold (k, a) (Map k b)
#

Given a Fold, produces a Map which applies that fold to each a separated by key k.

Example1 expression
fold (foldByKeyMap Control.Foldl.sum) [("a",1), ("b",2), ("b",20), ("a",10)]fromList [("a",11),("b",22)]
valuefoldByKeyHashMap
  1. :: (Hashable k, Eq k)
  2. => Fold a b
  3. -> Fold (k, a) (HashMap k b)
#

Given a Fold, produces a HashMap which applies that fold to each a separated by key k.

Example1 expression
List.sort (HashMap.toList (fold (foldByKeyHashMap Control.Foldl.sum) [("a",1), ("b",2), ("b",20), ("a",10)]))[("a",11),("b",22)]

Utilities

31 declarations

purely and impurely allow you to write folds compatible with the foldl library without incurring a foldl dependency. Write your fold to accept three parameters corresponding to the step function, initial accumulator, and extraction function and then users can upgrade your function to accept a Fold or FoldM using the purely or impurely combinators.

For example, the pipes library implements fold and foldM functions in Pipes.Prelude with the following type:

Pipes.Prelude.fold
    :: Monad m
    -> (x -> a -> x) -> x -> (x -> b) -> Producer a m () -> m b

Pipes.Prelude.foldM
    :: Monad m
    => (x -> a -> m x) -> m x -> (x -> m b) -> Producer a m () -> m b

Both fold and foldM is set up so that you can wrap them with either purely or impurely to accept a Fold or FoldM, respectively:

purely Pipes.Prelude.fold
    :: Monad m => Fold a b -> Producer a m () -> m b

impurely Pipes.Prelude.foldM
    :: Monad m => FoldM m a b -> Producer a m () -> m b

Other streaming libraries supporting purely and impurely include io-streams and streaming. So for example we have:

purely System.IO.Streams.fold_
    :: Fold a b -> Streams.InputStream a -> IO b

impurely System.IO.Streams.foldM_
    :: FoldM IO a b -> Streams.InputStream a -> IO b

The monotraversable package makes it convenient to apply a Fold or FoldM to pure containers that do not allow a general Foldable instance, like unboxed vectors:

purely ofoldlUnwrap
    :: MonoFoldable mono
    => Fold (Element mono) b -> mono -> b

impurely ofoldMUnwrap
    :: MonoFoldable mono
    => FoldM m (Element mono) b -> mono -> m b
valuepurely :: (forall x. (x -> a -> x) -> x -> (x -> b) -> r) -> Fold a b -> r
#

Upgrade a fold to accept the Fold type

valuepurely_ :: (forall x. (x -> a -> x) -> x -> x) -> Fold a b -> b
#

Upgrade a more traditional fold to accept the Fold type

valueimpurely
  1. :: forall x. (x -> a -> m x) -> m x -> (x -> m b) -> r
  2. -> FoldM m a b
  3. -> r
#

Upgrade a monadic fold to accept the FoldM type

valueimpurely_
  1. :: Monad m
  2. => forall x. (x -> a -> m x) -> m x -> m x
  3. -> FoldM m a b
  4. -> m b
#

Upgrade a more traditional monadic fold to accept the FoldM type

valuehoists :: (forall x. m x -> n x) -> FoldM m a b -> FoldM n a b
#

Shift a FoldM from one monad to another with a morphism such as lift or liftIO; the effect is the same as hoist.

value_Fold1 :: (a -> a -> a) -> Fold a (Maybe a)
#

_Fold1 step returns a new Fold using just a step function that has the same type for the accumulator and the element. The result type is the accumulator type wrapped in Maybe. The initial accumulator is retrieved from the Foldable, the result is None for empty containers.

valuepremap :: (a -> b) -> Fold b r -> Fold a r
#

(premap f folder) returns a new Fold where f is applied at each step

fold (premap f folder) list = fold folder (List.map f list)
Example1 expression
fold (premap Sum Foldl.mconcat) [1..10]Sum {getSum = 55}
Example1 expression
fold Foldl.mconcat (List.map Sum [1..10])Sum {getSum = 55}
premap id = id

premap (f . g) = premap g . premap f
premap k (pure r) = pure r

premap k (f <*> x) = premap k f <*> premap k x
valuepremapM :: Monad m => (a -> m b) -> FoldM m b r -> FoldM m a r
#

(premapM f folder) returns a new FoldM where f is applied to each input element

premapM return = id

premapM (f <=< g) = premap g . premap f
premapM k (pure r) = pure r

premapM k (f <*> x) = premapM k f <*> premapM k x
valuepostmapM :: Monad m => (a -> m r) -> FoldM m x a -> FoldM m x r
#

(postmapM f folder) returns a new FoldM where f is applied to the final value.

postmapM pure = id

postmapM (f >=> g) = postmapM g . postmapM f
postmapM k (pure r) = lifts (k r)
valueprefilter :: (a -> Bool) -> Fold a r -> Fold a r
#

(prefilter f folder) returns a new Fold where the folder's input is used only when the input satisfies a predicate f

This can also be done with handles (handles (filtered f)) but prefilter does not need you to depend on a lens library.

fold (prefilter p folder) list = fold folder (filter p list)
Example1 expression
fold (prefilter (>5) Control.Foldl.sum) [1..10]40
Example1 expression
fold Control.Foldl.sum (filter (>5) [1..10])40
valueprefilterM :: Monad m => (a -> m Bool) -> FoldM m a r -> FoldM m a r
#

(prefilterM f folder) returns a new FoldM where the folder's input is used only when the input satisfies a monadic predicate f.

valuepredropWhile :: (a -> Bool) -> Fold a r -> Fold a r
#

Transforms a Fold into one which ignores elements until they stop satisfying a predicate

fold (predropWhile p folder) list = fold folder (dropWhile p list)
Example1 expression
fold (predropWhile (>5) Control.Foldl.sum) [10,9,5,9]14
valuedrop :: Natural -> Fold a b -> Fold a b
#

(drop n folder) returns a new Fold that ignores the first n inputs but otherwise behaves the same as the original fold.

fold (drop n folder) list = fold folder (Data.List.genericDrop n list)
Example1 expression
Foldl.fold (Foldl.drop 3 Foldl.sum) [10, 20, 30, 1, 2, 3]6
Example1 expression
Foldl.fold (Foldl.drop 10 Foldl.sum) [10, 20, 30, 1, 2, 3]0
valuedropM :: Monad m => Natural -> FoldM m a b -> FoldM m a b
#

(dropM n folder) returns a new FoldM that ignores the first n inputs but otherwise behaves the same as the original fold.

foldM (dropM n folder) list = foldM folder (Data.List.genericDrop n list)
Example1 expression
Foldl.foldM (Foldl.dropM 3 (Foldl.generalize Foldl.sum)) [10, 20, 30, 1, 2, 3]6
Example1 expression
Foldl.foldM (Foldl.dropM 10 (Foldl.generalize Foldl.sum)) [10, 20, 30, 1, 2, 3]0
valuehandles :: Handler a b -> Fold b r -> Fold a r
#

(handles t folder) transforms the input of a Fold using a lens, traversal, or prism:

handles _1       :: Fold a r -> Fold (a, b) r
handles _Left    :: Fold a r -> Fold (Either a b) r
handles traverse :: Traversable t => Fold a r -> Fold (t a) r
handles folded   :: Foldable    t => Fold a r -> Fold (t a) r
Example1 expression
fold (handles traverse sum) [[1..5],[6..10]]55
Example1 expression
fold (handles (traverse . traverse) sum) [[Nothing, Just 2, Just 7],[Just 13, Nothing, Just 20]]42
Example1 expression
fold (handles (filtered even) sum) [1..10]30
Example1 expression
fold (handles _2 Foldl.mconcat) [(1,"Hello "),(2,"World"),(3,"!")]"Hello World!"
handles id = id

handles (f . g) = handles f . handles g
handles t (pure r) = pure r

handles t (f <*> x) = handles t f <*> handles t x
valuefoldOver :: Handler s a -> Fold a b -> s -> b
#

(foldOver f folder xs) folds all values from a Lens, Traversal, Prism or Fold with the given folder

Example1 expression
foldOver (_Just . both) Foldl.sum (Just (2, 3))5
Example1 expression
foldOver (_Just . both) Foldl.sum Nothing0
Foldl.foldOver f folder xs == Foldl.fold folder (xs^..f)
Foldl.foldOver (folded . f) folder == Foldl.fold (handles f folder)
Foldl.foldOver folded == Foldl.fold
newtypenewtype EndoM (m :: Type -> Type) a
#
instance Monad m => Monoid (EndoM m a) where
    mempty = EndoM return
    mappend (EndoM f) (EndoM g) = EndoM (f <=< g)

Constructors

Instances2Semigroup, Monoid
valuehandlesM :: HandlerM m a b -> FoldM m b r -> FoldM m a r
#

(handlesM t folder) transforms the input of a FoldM using a lens, traversal, or prism:

handlesM _1       :: FoldM m a r -> FoldM (a, b) r
handlesM _Left    :: FoldM m a r -> FoldM (Either a b) r
handlesM traverse :: Traversable t => FoldM m a r -> FoldM m (t a) r
handlesM folded   :: Foldable    t => FoldM m a r -> FoldM m (t a) r

handlesM obeys these laws:

handlesM id = id

handlesM (f . g) = handlesM f . handlesM g
handlesM t (pure r) = pure r

handlesM t (f <*> x) = handlesM t f <*> handlesM t x
valuefoldOverM :: Monad m => HandlerM m s a -> FoldM m a b -> s -> m b
#

(foldOverM f folder xs) folds all values from a Lens, Traversal, Prism or Fold monadically with the given folder

Foldl.foldOverM (folded . f) folder == Foldl.foldM (handlesM f folder)
Foldl.foldOverM folded == Foldl.foldM
valuefiltered :: Monoid m => (a -> Bool) -> (a -> m) -> a -> m
#
Example1 expression
fold (handles (filtered even) sum) [1..10]30
Example1 expression
foldM (handlesM (filtered even) (Foldl.mapM_ print)) [1..10]246810
valuegroupBy :: Ord k => (a -> k) -> Fold a b -> Fold a (Map k b)
#

Perform a Fold while grouping the data according to a specified group projection function. Returns the folded result grouped as a map keyed by the group.

valueeither :: Fold a1 b1 -> Fold a2 b2 -> Fold (Either a1 a2) (b1, b2)
#

Combine two folds into a fold over inputs for either of them.

Re-exports

5 declarations

Control.Monad.Primitive re-exports the PrimMonad type class

Data.Foldable re-exports the Foldable type class

Data.Vector.Generic re-exports the Vector type class

classclass Monad m => PrimMonad (m :: Type -> Type) where
#

Class of monads which can perform primitive state-transformer actions.

Instances18PrimMonad, …
datadata RealWorld
#

RealWorld is deeply magical. It is primitive, but it is not unlifted (hence ptrArg). We never manipulate values of type RealWorld; it's only used in the type system, to parameterise State#.

classclass Foldable (t :: Type -> Type) where
#

The Foldable class represents data structures that can be reduced to a summary value one element at a time. Strict left-associative folds are a good fit for space-efficient reduction, while lazy right-associative folds are a good fit for corecursive iteration, or for folds that short-circuit after processing an initial subsequence of the structure's elements.

Instances can be derived automatically by enabling the DeriveFoldable extension. For example, a derived instance for a binary tree might be:

{-# LANGUAGE DeriveFoldable #-}
data Tree a = Empty
            | Leaf a
            | Node (Tree a) a (Tree a)
    deriving Foldable

A more detailed description can be found in the Overview section of Data.Foldable#overview.

For the class laws see the Laws section of Data.Foldable#laws.

Instances89Foldable, …
classclass MVector (Mutable v) a => Vector (v :: Type -> Type) a where
#
Instances46Vector, …
familytype family Mutable (v :: Type -> Type) :: Type -> Type -> Type
#
Instances8Mutable, …