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

GHC 9.14.1 · lts/ghc-9.14.x · d82dee8 · 2026-10-12

Modulemachines-0.7.4Haskell2010

Data.Machine.Process

  • 2 types
  • 2 classes
  • 33 values
  • Packagemachines-0.7.4
  • Exports37
  • LanguageHaskell2010
  • LicenceBSD-3-Clause
  • SourceProcess.hs

Processes

5 declarations
typetype Process a b = Machine (Is a) b
#

A Process a b is a stream transducer that can consume values of type a from its input, and produce values of type b for its output.

typetype ProcessT (m :: Type -> Type) a b = MachineT m (Is a) b
#

A ProcessT m a b is a stream transducer that can consume values of type a from its input, and produce values of type b and has side-effects in the Monad m.

Common Processes

valueecho :: Monad m => MachineT m (Is a) a
#

The trivial Process that simply repeats each input it receives.

This can be constructed from a plan with

echo :: Process a a
echo = repeatedly $ do
  i <- await
  yield i

Examples:

Example1 expression
run $ echo <~ source [1..5][1,2,3,4,5]
valuefiltered :: (a -> Bool) -> Process a a
#

A Process that only passes through inputs that match a predicate.

This can be constructed from a plan with

filtered :: (a -> Bool) -> Process a a
filtered p = repeatedly $ do
  i <- await
  when (p i) $ yield i

Examples:

Example1 expression
run $ filtered even <~ source [1..5][2,4]
valuedropping :: Int -> Process a a
#

A Process that drops the first n, then repeats the rest.

This can be constructed from a plan with

dropping n = before echo $ replicateM_ n await

Examples:

Example1 expression
run $ dropping 3 <~ source [1..5][4,5]
valuetaking :: Int -> Process a a
#

A Process that passes through the first n elements from its input then stops

This can be constructed from a plan with

taking n = construct . replicateM_ n $ await >>= yield

Examples:

Example1 expression
run $ taking 3 <~ source [1..5][1,2,3]
valuedroppingWhile :: (a -> Bool) -> Process a a
#

A Process that drops elements while a predicate holds

This can be constructed from a plan with

droppingWhile :: (a -> Bool) -> Process a a
droppingWhile p = before echo loop where
  loop = await >>= v -> if p v then loop else yield v

Examples:

Example1 expression
run $ droppingWhile (< 3) <~ source [1..5][3,4,5]
valuetakingWhile :: (a -> Bool) -> Process a a
#

A Process that passes through elements until a predicate ceases to hold, then stops

This can be constructed from a plan with

takingWhile :: (a -> Bool) -> Process a a
takingWhile p = repeatedly $ await >>= v -> if p v then yield v else stop

Examples:

Example1 expression
run $ takingWhile (< 3) <~ source [1..5][1,2]
valuetakingJusts :: Monad m => MachineT m (Is (Maybe a)) a
#

A Process that passes through elements unwrapped from Just until a Nothing is found, then stops.

This can be constructed from a plan with

takingJusts :: Process (Maybe a) a
takingJusts = repeatedly $ await >>= maybe stop yield

Examples:

Example1 expression
run $ takingJusts <~ source [Just 1, Just 2, Nothing, Just 3, Just 4][1,2]
valuebuffered :: Int -> Process a [a]
#

Chunk up the input into n element lists.

Avoids returning empty lists and deals with the truncation of the final group.

An approximation of this can be constructed from a plan with

buffered :: Int -> Process a [a]
buffered = repeatedly . go [] where
  go acc 0 = yield (reverse acc)
  go acc n = do
    i await <| yield (reverse acc) *> stop
    go (i:acc) $! n-1

Examples:

Example1 expression
run $ buffered 3 <~ source [1..6][[1,2,3],[4,5,6]]
Example1 expression
run $ buffered 3 <~ source [1..5][[1,2,3],[4,5]]
Example1 expression
run $ buffered 3 <~ source [][]
valueflattened :: Foldable f => Process (f a) a
#

Break each input into pieces that are fed downstream individually.

Alias for asParts

valuefold :: Category k => (a -> b -> a) -> a -> Machine (k b) a
#

Construct a Process from a left-folding operation.

Like scan, but only yielding the final value.

It may be useful to consider this alternative signature

fold :: (a -> b -> a) -> a -> Process b a

This can be constructed from a plan with

fold :: Category k => (a -> b -> a) -> a -> Machine (k b) a
fold func seed = construct $ go seed where
  go cur = do
    next await <| yield cur *> stop
    go $! func cur next

Examples:

Example1 expression
run $ fold (+) 0 <~ source [1..5][15]
Example1 expression
run $ fold (\a _ -> a + 1) 0 <~ source [1..5][5]
valuefold1 :: Category k => (a -> a -> a) -> Machine (k a) a
#

fold1 is a variant of fold that has no starting value argument

This can be constructed from a plan with

fold1 :: Category k => (a -> a -> a) -> Machine (k a) a
fold1 func = construct $ await >>= go where
  go cur = do
    next await <| yield cur *> stop
    go $! func cur next

Examples:

Example1 expression
run $ fold1 (+) <~ source [1..5][15]
valuescan :: Category k => (a -> b -> a) -> a -> Machine (k b) a
#

Construct a Process from a left-scanning operation.

Like fold, but yielding intermediate values.

It may be useful to consider this alternative signature

scan :: (a -> b -> a) -> a -> Process b a

For stateful scan use auto with Data.Machine.Mealy machine. This can be constructed from a plan with

scan :: Category k => (a -> b -> a) -> a -> Machine (k b) a
scan func seed = construct $ go seed where
  go cur = do
    yield cur
    next <- await
    go $! func cur next

Examples:

Example1 expression
run $ scan (+) 0 <~ source [1..5][0,1,3,6,10,15]
Example1 expression
run $ scan (\a _ -> a + 1) 0 <~ source [1..5][0,1,2,3,4,5]
valuescan1 :: Category k => (a -> a -> a) -> Machine (k a) a
#

scan1 is a variant of scan that has no starting value argument

This can be constructed from a plan with

scan1 :: Category k => (a -> a -> a) -> Machine (k a) a
scan1 func = construct $ await >>= go where
  go cur = do
    yield cur
    next <- await
    go $! func cur next

Examples:

Example1 expression
run $ scan1 (+) <~ source [1..5][1,3,6,10,15]
valuescanMap :: (Category k, Monoid b) => (a -> b) -> Machine (k a) b
#

Like scan only uses supplied function to map and uses Monoid for associative operation

Examples:

Example1 expression
run $ mapping getSum <~ scanMap Sum <~ source [1..5][0,1,3,6,10,15]
valueasParts :: Foldable f => Process (f a) a
#

Break each input into pieces that are fed downstream individually.

This can be constructed from a plan with

asParts :: Foldable f => Process (f a) a
asParts = repeatedly $ await >>= traverse_ yield

Examples:

Example1 expression
run $ asParts <~ source [[1..3],[4..6]][1,2,3,4,5,6]
valuesinkPart_ :: Monad m => (a -> (b, c)) -> ProcessT m c Void -> ProcessT m a b
#

sinkPart_ toParts sink creates a process that uses the toParts function to break input into a tuple of (passAlong, sinkPart) for which the second projection is given to the supplied sink ProcessT (that produces no output) while the first projection is passed down the pipeline.

valueautoM :: (Category k, Monad m) => (a -> m b) -> MachineT m (k a) b
#

Apply a monadic function to each element of a ProcessT.

This can be constructed from a plan with

autoM :: Monad m => (a -> m b) -> ProcessT m a b
autoM :: (Category k, Monad m) => (a -> m b) -> MachineT m (k a) b
autoM f = repeatedly $ await >>= lift . f >>= yield

Examples:

Example1 expression
runT $ autoM Left <~ source [3, 4]Left 3
Example1 expression
runT $ autoM Right <~ source [3, 4]Right [3,4]
valuefinal :: Category k => Machine (k a) a
#

Skip all but the final element of the input

This can be constructed from a plan with

final :: Process a a
final :: Category k => Machine (k a) a
final = construct $ await >>= go where
  go prev = do
    next await <| yield prev *> stop
    go next

Examples:

Example2 expressions
runT $ final <~ source [1..10][10]runT $ final <~ source [][]
valuefinalOr :: Category k => a -> Machine (k a) a
#

Skip all but the final element of the input. If the input is empty, the default value is emitted

This can be constructed from a plan with

finalOr :: a -> Process a a
finalOr :: Category k => a -> Machine (k a) a
finalOr = construct . go where
  go prev = do
    next await <| yield prev *> stop
    go next

Examples:

Example2 expressions
runT $ finalOr (-1) <~ source [1..10][10]runT $ finalOr (-1) <~ source [][-1]
valuesequencing :: (Category k, Monad m) => MachineT m (k (m a)) a
#

Convert a stream of actions to a stream of values

This can be constructed from a plan with

sequencing :: Monad m => (a -> m b) -> ProcessT m a b
sequencing :: (Category k, Monad m) => MachineT m (k (m a)) a
sequencing = repeatedly $ do
  ma <- await
  a  <- lift ma
  yield a

Examples:

Example1 expression
runT $ sequencing <~ source [Just 3, Nothing]Nothing
Example1 expression
runT $ sequencing <~ source [Just 3, Just 4]Just [3,4]
valuemapping :: Category k => (a -> b) -> Machine (k a) b
#

Apply a function to all values coming from the input

This can be constructed from a plan with

mapping :: Category k => (a -> b) -> Machine (k a) b
mapping f = repeatedly $ await >>= yield . f

Examples:

Example1 expression
runT $ mapping (*2) <~ source [1..3][2,4,6]