| Safe Haskell | Safe-Inferred |
|---|---|
| Language | Haskell98 |
Control.Foldl.Transduce
Contents
Description
This module builds on module Control.Foldl, adding stateful transducers and grouping operations.
- type Transduction a b = forall x. Fold b x -> Fold a x
- type Transduction' a b r = forall x. Fold b x -> Fold a (r, x)
- data Transducer i o r = forall x . Transducer (x -> i -> (x, [o], [[o]])) x (x -> (r, [o], [[o]]))
- class ToTransducer t where
- toTransducer :: t i o r -> Transducer i o r
- type TransductionM m a b = forall x. Monad m => FoldM m b x -> FoldM m a x
- type TransductionM' m a b r = forall x. FoldM m b x -> FoldM m a (r, x)
- data TransducerM m i o r = forall x . TransducerM (x -> i -> m (x, [o], [[o]])) (m x) (x -> m (r, [o], [[o]]))
- class ToTransducerM m t where
- toTransducerM :: t i o r -> TransducerM m i o r
- transduce :: ToTransducer t => t i o s -> Transduction i o
- transduce' :: ToTransducer t => t i o s -> Transduction' i o s
- transduceM :: (Monad m, ToTransducerM m t) => t i o s -> TransductionM m i o
- transduceM' :: (Monad m, ToTransducerM m t) => t i o s -> TransductionM' m i o s
- transduceK :: Monad m => (i -> m [o]) -> TransductionM m i o
- folds :: ToTransducer t => t a b s -> Fold b c -> Transduction a c
- folds' :: ToTransducer t => t a b s -> Fold b c -> Transduction' a c s
- foldsM :: (Applicative m, Monad m, ToTransducerM m t) => t a b s -> FoldM m b c -> TransductionM m a c
- foldsM' :: (Applicative m, Monad m, ToTransducerM m t) => t a b s -> FoldM m b c -> TransductionM' m a c s
- type Infinite e = Cofree Identity e
- newtype ReifiedTransduction a b = ReifiedTransduction {
- getTransduction :: Transduction a b
- groups :: ToTransducer t => t a b s -> Infinite (ReifiedTransduction b c) -> Transduction a c
- evenly :: Transduction b c -> Infinite (ReifiedTransduction b c)
- bisect :: ToTransducer t => t a b s -> Transduction b c -> Transduction b c -> Transduction a c
- type Moore a b = Cofree ((->) a) b
- newtype ReifiedTransduction' a b r = ReifiedTransduction' {
- getTransduction' :: Transduction' a b r
- groups' :: ToTransducer t => t a b s -> Fold u v -> Moore u (ReifiedTransduction' b c u) -> Transduction' a c (s, v)
- evenly' :: Transduction' b c u -> Moore u (ReifiedTransduction' b c u)
- newtype ReifiedTransductionM m a b = ReifiedTransductionM {
- getTransductionM :: TransductionM m a b
- groupsM :: (Monad m, ToTransducerM m t) => t a b s -> Infinite (ReifiedTransductionM m b c) -> TransductionM m a c
- evenlyM :: TransductionM m b c -> Infinite (ReifiedTransductionM m b c)
- bisectM :: ToTransducerM m t => t a b s -> TransductionM m b c -> TransductionM m b c -> TransductionM m a c
- newtype ReifiedTransductionM' m a b r = ReifiedTransductionM' {
- getTransductionM' :: TransductionM' m a b r
- groupsM' :: (Monad m, ToTransducerM m t) => t a b s -> FoldM m u v -> Moore u (ReifiedTransductionM' m b c u) -> TransductionM' m a c (s, v)
- evenlyM' :: TransductionM' m b c u -> Moore u (ReifiedTransductionM' m b c u)
- ignore :: Transducer a b ()
- surround :: (Traversable p, Traversable s) => p a -> s a -> Transducer a a ()
- surroundIO :: (Traversable p, Traversable s, Functor m, MonadIO m) => m (p a) -> m (s a) -> TransducerM m a a ()
- chunksOf :: Int -> Transducer a a ()
- splitAt :: Int -> Transducer a a ()
- chunkedSplitAt :: StableFactorialMonoid m => Int -> Transducer m m ()
- splitWhen :: (a -> Bool) -> Transducer a a ()
- splitLast :: Transducer a a (Maybe a)
- chunkedStripPrefix :: (LeftGCDMonoid i, StableFactorialMonoid i, Traversable t, Monad m) => t i -> TransducerM (ExceptT ([i], Maybe i) m) i i ()
- foldify :: Transducer i o s -> Fold i s
- foldifyM :: Functor m => TransducerM m i o s -> FoldM m i s
- condense :: Fold a r -> Transducer a r r
- condenseM :: Applicative m => FoldM m a r -> TransducerM m a r r
- hoistTransducer :: Monad m => (forall a. m a -> n a) -> TransducerM m i o s -> TransducerM n i o s
- quiesce :: Monad m => FoldM (ExceptT e m) a r -> FoldM m a (Either e r)
- quiesceWith :: (Functor m, Monad m) => FoldM m a v -> FoldM (ExceptT e m) a r -> FoldM m a (Either (e, v) r)
- hoistFold :: Monad m => (forall a. m a -> n a) -> FoldM m i r -> FoldM n i r
- module Data.Functor.Extend
- module Control.Foldl
- module Control.Comonad.Cofree
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, as well as any pending output.
Constructors
| forall x . Transducer (x -> i -> (x, [o], [[o]])) x (x -> (r, [o], [[o]])) |
Instances
| ToTransducer Transducer | |
| Monad m => ToTransducerM m Transducer | |
| Bifunctor (Transducer i) | |
| Functor (Transducer i o) | |
| Comonad (Transducer i o) | |
| Extend (Transducer i o) |
class ToTransducer t where Source
Helps converting monadic transducers (over Identity) into pure ones.
Methods
toTransducer :: t i o r -> Transducer i o r Source
Instances
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
| forall x . TransducerM (x -> i -> m (x, [o], [[o]])) (m x) (x -> m (r, [o], [[o]])) |
Instances
| (~) (* -> *) m m' => ToTransducerM m (TransducerM m') | |
| ToTransducer (TransducerM Identity) | |
| (Functor m, Monad m) => Bifunctor (TransducerM m i) | |
| Monad m => Functor (TransducerM m i o) | |
| Monad m => Extend (TransducerM m i o) |
class ToTransducerM m t where Source
Helps converting pure transducers into monadic ones.
Methods
toTransducerM :: t i o r -> TransducerM m i o r Source
Instances
| Monad m => ToTransducerM m Transducer | |
| (~) (* -> *) m m' => ToTransducerM m (TransducerM m') |
Applying transducers
transduce :: ToTransducer t => t i o s -> Transduction i o Source
Apply a Transducer to a Fold, discarding the return value of the
Transducer.
>>>L.fold (transduce (Transducer (\_ i -> ((),[i],[])) () (\_ -> ('r',[],[]))) 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 s -> TransductionM m i o Source
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 :: ToTransducer t => t a b s -> Fold b c -> Transduction a c Source
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' :: ToTransducer t => t a b s -> Fold b c -> Transduction' a c s Source
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 :: (Applicative m, Monad m, ToTransducerM m t) => t a b s -> FoldM m b c -> TransductionM m a c Source
Monadic version of folds.
foldsM' :: (Applicative m, Monad m, ToTransducerM m t) => t a b s -> FoldM m b c -> TransductionM' m a c s Source
Monadic version of folds'.
Group operations
newtype ReifiedTransduction a b Source
Helper for storing a Transduction safely on a container.
Constructors
| ReifiedTransduction | |
Fields
| |
Arguments
| :: ToTransducer t | |
| => t a b s | |
| -> Infinite (ReifiedTransduction 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) (evenly (transduce (surround "<" ">"))) L.list) "aabbccdd""<aa><bb><cc><dd>"
>>>:{let transducers = flip C.unfold 0 $ \i -> (,) (ReifiedTransduction (transduce (surround (show i) []))) (Identity (succ i)) in L.fold (groups (chunksOf 2) transducers L.list) "aabbccdd" :} "0aa1bb2cc3dd"
evenly :: Transduction b c -> Infinite (ReifiedTransduction b c) Source
Use the same Transduction for each group.
Arguments
| :: ToTransducer t | |
| => t a b s | |
| -> Transduction b c | head |
| -> Transduction b c | |
| -> Transduction a c |
Use one transduction to process the first group, and another for the second and all subsequent groups.
type Moore a b = Cofree ((->) a) b Source
Unending machine that gives you a b whenever you give it an a.
newtype ReifiedTransduction' a b r Source
Helper for storing a ReifiedTransduction safely on a container.
Constructors
| ReifiedTransduction' | |
Fields
| |
Arguments
| :: ToTransducer t | |
| => t a b s | |
| -> Fold u v | auxiliary |
| -> Moore u (ReifiedTransduction' b c u) | a machine that eats |
| -> Transduction' a c (s, 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 = evenly' $ \f -> transduce (surround "<" ">") (liftA2 (,) L.list f) in L.fold (groups' (chunksOf 2) L.list transductions L.list) "aabbccdd" :} (((),["<aa>","<bb>","<cc>","<dd>"]),"<aa><bb><cc><dd>")
evenly' :: Transduction' b c u -> Moore u (ReifiedTransduction' b c u) Source
Use the same Transduction' for each group.
Ignores the inputs to the Moore machine.
Monadic group operations
newtype ReifiedTransductionM m a b Source
Helper for storing a TransductionM safely on a container.
Constructors
| ReifiedTransductionM | |
Fields
| |
Arguments
| :: (Monad m, ToTransducerM m t) | |
| => t a b s | |
| -> Infinite (ReifiedTransductionM m b c) | |
| -> TransductionM m a c |
Monadic version of groups.
evenlyM :: TransductionM m b c -> Infinite (ReifiedTransductionM m b c) Source
Monadic version of evenly.
Arguments
| :: ToTransducerM m t | |
| => t a b s | |
| -> TransductionM m b c | head |
| -> TransductionM m b c | |
| -> TransductionM m a c |
Monadic version of bisect.
newtype ReifiedTransductionM' m a b r Source
Helper for storing a TransductionM' safely on a container.
Constructors
| ReifiedTransductionM' | |
Fields
| |
Arguments
| :: (Monad m, ToTransducerM m t) | |
| => t a b s | |
| -> FoldM m u v | |
| -> Moore u (ReifiedTransductionM' m b c u) | a machine that eats |
| -> TransductionM' m a c (s, v) |
Monadic version of groups'.
evenlyM' :: TransductionM' m b c u -> Moore u (ReifiedTransductionM' m b c u) Source
Monadic version of evenly'.
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") (evenly (transduce (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
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) (evenly (transduce (surround [] [0]))) L.list) [1..7][1,2,0,3,4,0,5,6,0,7,0]
splitAt :: Int -> Transducer a a () Source
Splits the stream at a given position.
>>>L.fold (bisect (splitAt 2) (transduce ignore) 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) (transduce ignore) id L.list) [[1..5],[6..9]][[8,9]]
splitWhen :: (a -> Bool) -> Transducer a a () Source
>>>L.fold (bisect (splitWhen (>3)) id (transduce ignore) L.list) [1..5][1,2,3]
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 splitLast id (transduce ignore) L.list) [1..5][1,2,3,4]
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.
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
quiesceWith :: (Functor m, Monad m) => FoldM m a v -> FoldM (ExceptT e m) a r -> FoldM m a (Either (e, v) r) Source
Generalized version of quiesce to turn a fallible FoldM into another
that starts a "fallback fold" when it encounters an error.
"Start folding this way, if you encounter an error, start folding this other way".
>>>L.foldM (quiesceWith (L.generalize L.length) (FoldM (\_ _-> throwE ()) (return ()) (\_ -> throwE ()))) [1..7]Left ((),7)
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.
Re-exports
module Data.Functor.Extend
module Control.Foldl
module Control.Comonad.Cofree