HORIZON HASKELLDocslts/ghc-9.10.x248f8f02026-10-05Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · 248f8f0 · 2026-10-05

Modulefoldl-1.4.18Haskell2010

Control.Scanl

This module provides efficient and streaming left map-with-accumulator that you can combine using Applicative style.

Import this module qualified to avoid clashing with the Prelude:

Example1 expression
import qualified Control.Scanl as SL

Use scan to apply a Scan to a list (or other Traversable structures) from left to right, and scanr to do so from right to left.

Note that the Scan type does not supersede the Fold type nor does the Fold type supersede the Scan type. Each type has a unique advantage.

For example, Scans can be chained end-to-end:

(>>>) :: Scan a b -> Scan b c -> Scan a c

In other words, Scan is an instance of the Category typeclass.

Folds cannot be chained end-to-end

Vice versa, Folds can produce a result even when fed no input:

extract :: Fold a b -> b

In other words, Fold is an instance of the Comonad typeclass.

A Scan cannot produce any output until provided with at least one input.

  • 2 types
  • 15 values
  • Packagefoldl-1.4.18
  • Exports17
  • LanguageHaskell2010
  • LicenceBSD-3-Clause
  • SourceScanl.hs

Scan Types

2 declarations
datadata Scan a b
#

Efficient representation of a left map-with-accumulator that preserves the scan's step function and initial accumulator.

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

A 'Scan a b' processes elements of type a replacing each with a value of type b.

Constructors

  • forall x. Scan (a -> State x b) x

    Scan step initial

Instances10Arrow, Profunctor, Category, Functor, Applicative, Floating, …
datadata ScanM (m :: Type -> Type) a b
#

Like Scan, but monadic.

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

Constructors

  • forall x. ScanM (a -> StateT x m b) (m x)

    ScanM step initial extract

Instances10Category, Arrow, Profunctor, Functor, Applicative, Floating, …

Scanning

5 declarations
valueprescan :: Fold a b -> Scan a b
#

Convert a Fold into a prescan

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

valuepostscan :: Fold a b -> Scan a b
#

Convert a Fold into a postscan

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

Utilities

10 declarations
valuepurely :: (forall x. (a -> State x b) -> x -> r) -> Scan a b -> r
#

Upgrade a scan to accept the Scan type

valuepurely_ :: (forall x. (x -> a -> (x, b)) -> x -> r) -> Scan a b -> r
#

Upgrade a more traditional scan to accept the Scan type

valueimpurely :: (forall x. (a -> StateT x m b) -> m x -> r) -> ScanM m a b -> r
#

Upgrade a monadic scan to accept the ScanM type

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

Upgrade a more traditional monadic scan to accept the ScanM type

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

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

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

(premap f scaner) returns a new Scan where f is applied at each step

scan (premap f scaner) list = scan scaner (map f list)
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) -> ScanM m b r -> ScanM m a r
#

(premapM f scaner) returns a new ScanM 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