foldl-transduce-0.6.0.0: Transducers for foldl folds.

Safe HaskellSafe
LanguageHaskell98

Control.Foldl.Transduce

Contents

Description

This module builds on module Control.Foldl, adding stateful transducers and grouping operations.

>>> L.fold (transduce (surround "[" "]") L.list) "middle"
"[middle]"
>>> L.fold (folds (chunksOf 2) L.length L.list) "aabbccdd"
[2,2,2,2]
>>> L.fold (groups (chunksOf 2) (surround "[" "]") L.list) "aabbccdd"
"[aa][bb][cc][dd]"

Synopsis

Transducer types

type Transduction a b = forall x. Fold b x -> Fold a x Source #

A (possibly stateful) transformation on the inputs of a Fold.

Functions constructed with combinators like premap or handles from Control.Foldl also typecheck as a Transduction.

type Transduction' a b r = forall x. Fold b x -> Fold a (r, x) Source #

A more general from of Transduction that adds new information to the return value of the Fold.

data Transducer i o r Source #

A stateful process that transforms a stream of inputs into a stream of outputs, and may optionally demarcate groups in the stream of outputs.

Composed of a step function, an initial state, and a extraction function.

The step function returns a triplet of:

  • The new internal state.
  • List of outputs belonging to the last segment detected in the previous step.
  • A list of lists of outputs belonging to segments detected in the current step. If the list is empty, that means no splitting has taken place in the current step. Transducers that do not perform grouping never return anything other than [] here. In effect, they treat the whole stream as a single group.

The extraction function returns the Transducers own result value, along with any pending output.

Constructors

Transducer (x -> i -> (x, [o], [[o]])) x (x -> (r, [o], [[o]])) 

Instances

ToTransductions' Transducer Source # 

Methods

toTransductions' :: Transducer a b u -> Moore a b u Source #

ToTransducer Transducer Source # 

Methods

toTransducer :: Transducer i o r -> Transducer i o r Source #

Monad m => ToTransductionsM' m Transducer Source # 

Methods

toTransductionsM' :: Transducer a b u -> MooreM m a b u Source #

Monad m => ToTransducerM m Transducer Source # 

Methods

toTransducerM :: Transducer i o r -> TransducerM m i o r Source #

Bifunctor (Transducer i) Source # 

Methods

bimap :: (a -> b) -> (c -> d) -> Transducer i a c -> Transducer i b d #

first :: (a -> b) -> Transducer i a c -> Transducer i b c #

second :: (b -> c) -> Transducer i a b -> Transducer i a c #

Functor (Transducer i o) Source # 

Methods

fmap :: (a -> b) -> Transducer i o a -> Transducer i o b #

(<$) :: a -> Transducer i o b -> Transducer i o a #

Comonad (Transducer i o) Source # 

Methods

extract :: Transducer i o a -> a #

duplicate :: Transducer i o a -> Transducer i o (Transducer i o a) #

extend :: (Transducer i o a -> b) -> Transducer i o a -> Transducer i o b #

Extend (Transducer i o) Source # 

Methods

duplicated :: Transducer i o a -> Transducer i o (Transducer i o a) #

extended :: (Transducer i o a -> b) -> Transducer i o a -> Transducer i o b #

class ToTransducer t where Source #

Helps converting monadic transducers (over Identity) into pure ones.

Minimal complete definition

toTransducer

Methods

toTransducer :: t i o r -> Transducer i o r Source #

Monadic transducer types

type TransductionM m a b = forall x. Monad m => FoldM m b x -> FoldM m a x Source #

Like Transduction, but works on monadic Folds.

type TransductionM' m a b r = forall x. FoldM m b x -> FoldM m a (r, x) Source #

Like Transduction', but works on monadic Folds.

data TransducerM m i o r Source #

Like Transducer, but monadic.

Constructors

TransducerM (x -> i -> m (x, [o], [[o]])) (m x) (x -> m (r, [o], [[o]])) 

Instances

((~) (* -> *) m m', Monad m') => ToTransductionsM' m (TransducerM m') Source # 

Methods

toTransductionsM' :: TransducerM m' a b u -> MooreM m a b u Source #

(~) (* -> *) m m' => ToTransducerM m (TransducerM m') Source # 

Methods

toTransducerM :: TransducerM m' i o r -> TransducerM m i o r Source #

ToTransducer (TransducerM Identity) Source # 
(Functor m, Monad m) => Bifunctor (TransducerM m i) Source # 

Methods

bimap :: (a -> b) -> (c -> d) -> TransducerM m i a c -> TransducerM m i b d #

first :: (a -> b) -> TransducerM m i a c -> TransducerM m i b c #

second :: (b -> c) -> TransducerM m i a b -> TransducerM m i a c #

Monad m => Functor (TransducerM m i o) Source # 

Methods

fmap :: (a -> b) -> TransducerM m i o a -> TransducerM m i o b #

(<$) :: a -> TransducerM m i o b -> TransducerM m i o a #

Monad m => Extend (TransducerM m i o) Source # 

Methods

duplicated :: TransducerM m i o a -> TransducerM m i o (TransducerM m i o a) #

extended :: (TransducerM m i o a -> b) -> TransducerM m i o a -> TransducerM m i o b #

class ToTransducerM m t where Source #

Helps converting pure transducers into monadic ones.

Minimal complete definition

toTransducerM

Methods

toTransducerM :: t i o r -> TransducerM m i o r Source #

Instances

Monad m => ToTransducerM m Transducer Source # 

Methods

toTransducerM :: Transducer i o r -> TransducerM m i o r Source #

(~) (* -> *) m m' => ToTransducerM m (TransducerM m') Source # 

Methods

toTransducerM :: TransducerM m' i o r -> TransducerM m i o r Source #

Applying transducers

transduce :: ToTransducer t => t i o () -> Transduction i o Source #

Apply a Transducer to a Fold, discarding the return value of the Transducer.

>>> L.fold (transduce (Transducer (\_ i -> ((),[i],[])) () (\_ -> ((),[],[]))) L.list) [1..7]
[1,2,3,4,5,6,7]

transduce' :: ToTransducer t => t i o s -> Transduction' i o s Source #

Generalized version of transduce that preserves the return value of the Transducer.

>>> L.fold (transduce' (Transducer (\_ i -> ((),[i],[])) () (\_ -> ('r',[],[]))) L.list) [1..7]
('r',[1,2,3,4,5,6,7])

transduceM :: (Monad m, ToTransducerM m t) => t i o () -> TransductionM m i o Source #

Like transduce, but works on monadic Folds.

transduceM' :: (Monad m, ToTransducerM m t) => t i o s -> TransductionM' m i o s Source #

Like transduce', but works on monadic Folds.

transduceK :: Monad m => (i -> m [o]) -> TransductionM m i o Source #

Transduce with a Kleisli arrow that returns a list.

Folding over groups

folds Source #

Arguments

:: (ToTransducer t, ToFold f) 
=> t a b ()

Transducer working as a splitter.

-> f b c 
-> Transduction a c 

Summarizes each of the groups demarcated by the Transducer using a Fold.

The result value of the Transducer is discarded.

>>> L.fold (folds (chunksOf 3) L.sum L.list) [1..7]
[6,15,7]

folds' Source #

Arguments

:: (ToTransducer t, ToFold f) 
=> t a b s

Transducer working as a splitter.

-> f b c 
-> Transduction' a c s 

Like folds, but preserves the return value of the Transducer.

>>> L.fold (folds' (chunksOf 3) L.sum L.list) [1..7]
((),[6,15,7])

foldsM Source #

Arguments

:: (Applicative m, Monad m, ToTransducerM m t, ToFoldM m f) 
=> t a b () 
-> f b c 
-> TransductionM m a c 

Monadic version of folds.

foldsM' Source #

Arguments

:: (Applicative m, Monad m, ToTransducerM m t, ToFoldM m f) 
=> t a b s 
-> f b c 
-> TransductionM' m a c s 

Monadic version of folds'.

Group operations

newtype ReifiedTransduction' a b r Source #

Helper for storing a Transduction' safely on a container.

reify :: Transduction a b -> ReifiedTransduction' a b () Source #

Convenience constructor, often useful with pure functions like id.

newtype Moore a b u Source #

An unending machine that eats u values and returns ReifiedTransduction's whose result type is also u.

Constructors

Moore 

Fields

Instances

class ToTransductions' t where Source #

Helper for obtaining infinite sequences of Transduction's from suitable types (in order to avoid explicit conversions).

Minimal complete definition

toTransductions'

Methods

toTransductions' :: t a b u -> Moore a b u Source #

moveHead :: (ToTransductions' h, ToTransductions' t) => h a b u -> t a b u -> Moore a b u Source #

Prepend the head of the first argument to the second argument.

groups Source #

Arguments

:: (ToTransducer s, ToTransductions' t) 
=> s a b ()

Transducer working as a splitter.

-> t b c ()

infinite list of transductions

-> Transduction a c 

Processes each of the groups demarcated by a Transducer using a Transduction taken from an unending supply, returning a Transduction what works over the undivided stream of inputs.

The return value of the Transducer is discarded.

>>> L.fold (groups (chunksOf 2) (surround "<" ">") L.list) "aabbccdd"
"<aa><bb><cc><dd>"
>>> :{
    let transductions = Moore (C.unfold (\i ->
          (reify (transduce (surround (show i) [])), \_ -> succ i)) 0)
    in L.fold (groups (chunksOf 2) transductions L.list) "aabbccdd"
    :}
"0aa1bb2cc3dd"

bisect Source #

Arguments

:: (ToTransducer s, ToTransductions' h, ToTransductions' t) 
=> s a b ()

Transducer working as a splitter.

-> h b c ()

Machine to process the first group

-> t b c ()

Machine to process the second and subsequent groups

-> Transduction a c 

Use a different Transduction for the first detected group.

>>> :{
    let drop n = bisect (splitAt n) ignore (reify id)
    in L.fold (drop 2 L.list) "aabbccdd"
    :}
"bbccdd"

groups' Source #

Arguments

:: (ToTransducer s, ToTransductions' t, ToFold f) 
=> s a b r

Transducer working as a splitter.

-> t b c u

machine that eats u values and spits transductions

-> f u v

auxiliary Fold that aggregates the u values produced for each group

-> Transduction' a c (r, v) 

Generalized version of groups that preserves the return value of the Transducer.

A summary value for each group is also calculated. These values are aggregated for the whole stream, with the help of an auxiliary Fold.

>>> :{
    let transductions = 
          reify' (\f -> transduce (surround "<" ">") ((,) <$> L.list <*> f))
    in L.fold (groups' (chunksOf 2) transductions L.list L.list) "aabbccdd"
    :}
(((),["<aa>","<bb>","<cc>","<dd>"]),"<aa><bb><cc><dd>")

Monadic group operations

newtype ReifiedTransductionM' m a b r Source #

Helper for storing a TransductionM' safely on a container.

Instances

((~) (* -> *) m m', Monad m') => ToTransductionsM' m (ReifiedTransductionM' m') Source # 

Methods

toTransductionsM' :: ReifiedTransductionM' m' a b u -> MooreM m a b u Source #

reifyM :: Monad m => TransductionM m a b -> ReifiedTransductionM' m a b () Source #

Monadic version of reify.

reifyM' :: TransductionM' m a b r -> ReifiedTransductionM' m a b r Source #

Monadic version of reifyM.

newtype MooreM m a b u Source #

Monadic version of Moore.

Constructors

MooreM 

Fields

Instances

((~) (* -> *) m m', Monad m') => ToTransductionsM' m (MooreM m') Source # 

Methods

toTransductionsM' :: MooreM m' a b u -> MooreM m a b u Source #

class Monad m => ToTransductionsM' m t where Source #

Monadic version of ToTransductions'.

Minimal complete definition

toTransductionsM'

Methods

toTransductionsM' :: t a b u -> MooreM m a b u Source #

Instances

Monad m => ToTransductionsM' m Transducer Source # 

Methods

toTransductionsM' :: Transducer a b u -> MooreM m a b u Source #

((~) (* -> *) m m', Monad m') => ToTransductionsM' m (ReifiedTransductionM' m') Source # 

Methods

toTransductionsM' :: ReifiedTransductionM' m' a b u -> MooreM m a b u Source #

((~) (* -> *) m m', Monad m') => ToTransductionsM' m (TransducerM m') Source # 

Methods

toTransductionsM' :: TransducerM m' a b u -> MooreM m a b u Source #

((~) (* -> *) m m', Monad m') => ToTransductionsM' m (MooreM m') Source # 

Methods

toTransductionsM' :: MooreM m' a b u -> MooreM m a b u Source #

moveHeadM :: (Monad m, ToTransductionsM' m h, ToTransductionsM' m t) => h a b u -> t a b u -> MooreM m a b u Source #

Monadic version of moveHead.

groupsM Source #

Arguments

:: (Monad m, ToTransducerM m s, ToTransductionsM' m t) 
=> s a b () 
-> t b c () 
-> TransductionM m a c 

Monadic version of groups.

bisectM Source #

Arguments

:: (Monad m, ToTransducerM m s, ToTransductionsM' m h, ToTransductionsM' m t) 
=> s a b () 
-> h b c () 
-> t b c () 
-> TransductionM m a c 

Monadic version of bisect.

groupsM' Source #

Arguments

:: (Monad m, ToTransducerM m s, ToTransductionsM' m t, ToFoldM m f) 
=> s a b r 
-> t b c u 
-> f u v 
-> TransductionM' m a c (r, v) 

Monadic version of groups'.

Transducers

ignore :: Transducer a b () Source #

Ignore all the inputs coming into the fold.

Polymorphic in both inputs and outputs.

surround :: (Traversable p, Traversable s) => p a -> s a -> Transducer a a () Source #

Adds a prefix and a suffix to the stream arriving into a Fold.

>>> L.fold (transduce (surround "prefix" "suffix") L.list) "middle"
"prefixmiddlesuffix"

Used as a splitter, it puts the prefix, the original stream and the suffix in separate groups:

>>> L.fold (groups (surround "prefix" "suffix") (surround "[" "]") L.list) "middle"
"[prefix][middle][suffix]"

surroundIO :: (Traversable p, Traversable s, Functor m, MonadIO m) => m (p a) -> m (s a) -> TransducerM m a a () Source #

Like surround, but the prefix and suffix are obtained using a IO action.

>>> L.foldM (transduceM (surroundIO (return "prefix") (return "suffix")) (L.generalize L.list)) "middle"
"prefixmiddlesuffix"

Splitters

chunksOf :: Int -> Transducer a a () Source #

Splits a stream into chunks of fixed size.

>>> L.fold (folds (chunksOf 2) L.list L.list) [1..7]
[[1,2],[3,4],[5,6],[7]]
>>> L.fold (groups (chunksOf 2) (surround [] [0]) L.list) [1..7]
[1,2,0,3,4,0,5,6,0,7,0]

split :: (a -> Bool) -> Transducer a a () Source #

>>> L.fold (folds (split (==2)) L.list L.list) [1,2,2,1,1,2,1]
[[1],[],[1,1],[1]]
>>> L.fold (folds (split (==2)) L.list L.list) [2,1,1,2]
[[],[1,1],[]]

splitAt :: Int -> Transducer a a () Source #

Splits the stream at a given position.

>>> L.fold (bisect (splitAt 2) ignore (reify id) L.list) [1..5]
[3,4,5]

chunkedSplitAt :: StableFactorialMonoid m => Int -> Transducer m m () Source #

Similar to splitAt, but works with streams of "chunked" data like bytestrings, texts, vectors, lists of lists...

>>> L.fold (bisect (chunkedSplitAt 7) ignore (reify id) L.list) [[1..5],[6..9]]
[[8,9]]

splitLast :: Transducer a a (Maybe a) Source #

Puts the last element of the input stream (if it exists) in a separate group.

>>> L.fold (bisect (void splitLast) (reify id) ignore L.list) [1..5]
[1,2,3,4]

break :: (a -> Bool) -> Transducer a a () Source #

>>> L.fold (bisect (break (>3)) (reify id) ignore L.list) [1..5]
[1,2,3]

chunkedStripPrefix Source #

Arguments

:: (LeftGCDMonoid i, StableFactorialMonoid i, Traversable t, Monad m) 
=> t i 
-> TransducerM (ExceptT ([i], Maybe i) m) i i () 

Strip a prefix from a stream of "chunked" data, like packed text.

If the prefix doesn't match, fail with the unmatched part of the prefix and the input that caused the error.

>>> runExceptT $ L.foldM (transduceM (chunkedStripPrefix [[1..2],[3..4]]) (L.generalize L.list)) [[1..5],[6..9]]
Right [[5],[6,7,8,9]]
>>> runExceptT $ L.foldM (transduceM (chunkedStripPrefix [[1..2],[3,77,99]]) (L.generalize L.list)) [[1..5],[6..9]]
Left ([[77,99]],Just [4,5])

Transducer utilities

foldify :: Transducer i o s -> Fold i s Source #

Transforms a Transducer into a Fold by forgetting about the data sent downstream.

foldifyM :: Functor m => TransducerM m i o s -> FoldM m i s Source #

Monadic version of foldify.

condense :: Fold a r -> Transducer a r r Source #

Transforms a Fold into a Transducer that sends the return value of the Fold downstream when upstream closes.

condenseM :: Applicative m => FoldM m a r -> TransducerM m a r r Source #

Monadic version of condense.

hoistTransducer :: Monad m => (forall a. m a -> n a) -> TransducerM m i o s -> TransducerM n i o s Source #

Changes the base monad used by a TransducerM.

Fold utilities

hoistFold :: Monad m => (forall a. m a -> n a) -> FoldM m i r -> FoldM n i r Source #

Changes the base monad used by a FoldM.

Another name for hoists.

unit :: Fold a () Source #

The "do-nothing" fold.

trip :: Monad m => FoldM (ExceptT a m) a () Source #

A fold that fails if it receives any input at all. The received input is used as the error.

quiesce :: Monad m => FoldM (ExceptT e m) a r -> FoldM m a (Either e r) Source #

Turn a FoldM that fails abruptly into one that encodes the error into its return value.

Can be useful when combining fallible FoldMs with non-fallible ones.

>>> L.foldM (quiesce (FoldM (\_ _-> throwE ()) (return ()) (\_ -> throwE ()))) [1..7]
Left ()

newtype Fallible m r i e Source #

Constructors

Fallible 

Fields

Instances

(Functor m, Monad m, Monoid r) => Choice (Fallible m r) Source #

Fail immediately when an input comes in the wrong branch.

Methods

left' :: Fallible m r a b -> Fallible m r (Either a c) (Either b c) #

right' :: Fallible m r a b -> Fallible m r (Either c a) (Either c b) #

(Functor m, Monad m) => Profunctor (Fallible m r) Source # 

Methods

dimap :: (a -> b) -> (c -> d) -> Fallible m r b c -> Fallible m r a d #

lmap :: (a -> b) -> Fallible m r b c -> Fallible m r a c #

rmap :: (b -> c) -> Fallible m r a b -> Fallible m r a c #

(#.) :: Coercible * c b => (b -> c) -> Fallible m r a b -> Fallible m r a c #

(.#) :: Coercible * b a => Fallible m r b c -> (a -> b) -> Fallible m r a c #

(Functor m, Monad m) => Monad (Fallible m r i) Source #

>>= continues folding after an error using a Fallible constructed from the error.

Methods

(>>=) :: Fallible m r i a -> (a -> Fallible m r i b) -> Fallible m r i b #

(>>) :: Fallible m r i a -> Fallible m r i b -> Fallible m r i b #

return :: a -> Fallible m r i a #

fail :: String -> Fallible m r i a #

(Functor m, Monad m) => Functor (Fallible m r i) Source # 

Methods

fmap :: (a -> b) -> Fallible m r i a -> Fallible m r i b #

(<$) :: a -> Fallible m r i b -> Fallible m r i a #

(Functor m, Monad m) => Applicative (Fallible m r i) Source #

pure creates a Fallible that starts in a failed state.

Methods

pure :: a -> Fallible m r i a #

(<*>) :: Fallible m r i (a -> b) -> Fallible m r i a -> Fallible m r i b #

liftA2 :: (a -> b -> c) -> Fallible m r i a -> Fallible m r i b -> Fallible m r i c #

(*>) :: Fallible m r i a -> Fallible m r i b -> Fallible m r i b #

(<*) :: Fallible m r i a -> Fallible m r i b -> Fallible m r i a #

class ToFold t where Source #

Minimal complete definition

toFold

Methods

toFold :: t i r -> Fold i r Source #

Instances

ToFold Fold Source # 

Methods

toFold :: Fold i r -> Fold i r Source #

ToFold (FoldM Identity) Source # 

Methods

toFold :: FoldM Identity i r -> Fold i r Source #

class ToFoldM m t where Source #

Minimal complete definition

toFoldM

Methods

toFoldM :: t i r -> FoldM m i r Source #

Instances

Monad m => ToFoldM m Fold Source # 

Methods

toFoldM :: Fold i r -> FoldM m i r Source #

(~) (* -> *) m m' => ToFoldM m (FoldM m') Source # 

Methods

toFoldM :: FoldM m' i r -> FoldM m i r Source #

Deprecated

Re-exports

 

Orphan instances

Extend (Fold a) Source # 

Methods

duplicated :: Fold a a -> Fold a (Fold a a) #

extended :: (Fold a a -> b) -> Fold a a -> Fold a b #

Monad m => Extend (FoldM m a) Source # 

Methods

duplicated :: FoldM m a a -> FoldM m a (FoldM m a a) #

extended :: (FoldM m a a -> b) -> FoldM m a a -> FoldM m a b #