-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | Streaming component combinators
--
-- SCC is a layered library of Streaming Component Combinators. The
-- lowest layer defines a Pipe monad transformer that enables building of
-- producer-consumer coroutine pairs. The next layer adds streaming
-- component types, a number of primitive streaming components and a set
-- of component combinators. Finally, there is an executable that exposes
-- all functionality in a command-line shell.
--
-- The library design is based on paper
-- http://www.idealliance.org/papers/extreme/Proceedings/html/2006/Blazevic01/EML2006Blazevic01.html
--
-- Mario Blažević, Streaming component combinators, Extreme Markup
-- Languages, 2006.
@package scc
@version 0.1
-- | Module Foundation defines the pipe computations and their basic
-- building blocks.
module Control.Concurrent.SCC.Foundation
-- | Pipe represents the type of monadic computations that can be
-- split into co-routining computations using function pipe. The
-- context type parameter delimits the scope of the computation.
data (Monad m) => Pipe context m r
-- | A Source is the read-only end of a Pipe communication
-- channel.
data Source context x
-- | A Sink is the write-only end of a Pipe communication
-- channel.
data Sink context x
-- | A computation that consumes values from a Source is called
-- Consumer.
type Consumer m x r = forall c. Source c x -> Pipe c m r
-- | A computation that produces values and puts them into a Sink is
-- called Producer.
type Producer m x r = forall c. Sink c x -> Pipe c m r
-- | The pipe function splits the computation into two concurrent
-- parts, producer and consumer. The producer is
-- given a Sink to put values into, and consumer a
-- Source to get those values from. Once producer and consumer
-- both complete, pipe returns their paired results.
pipe :: (Monad m) => Producer m x r1 -> Consumer m x r2 -> Pipe context m (r1, r2)
-- | The pipeD function is same as pipe, with an additional
-- description argument.
pipeD :: (Monad m) => String -> Producer m x r1 -> Consumer m x r2 -> Pipe context m (r1, r2)
-- | Function get tries to get a value from the given Source
-- argument. The intervening Pipe computations suspend all the way
-- to the pipe function invocation that created the source. The
-- result of get is Nothing iff the argument source is
-- empty.
get :: (Monad m, Typeable x) => Source context' x -> Pipe context m (Maybe x)
getSuccess :: (Monad m, Typeable x) => Source context' x -> (x -> Pipe context m ()) -> Pipe context m ()
-- | Function canPut checks if the argument sink accepts values,
-- i.e., whether a put operation would succeed on the sink.
canPut :: (Monad m, Typeable x) => Sink context' x -> Pipe context m Bool
-- | Function put tries to put a value into the given sink. The
-- intervening Pipe computations suspend up to the pipe
-- invocation that has created the argument sink. The result of
-- put indicates whether the operation succeded.
put :: (Monad m, Typeable x) => Sink context' x -> x -> Pipe context m Bool
-- | Function liftPipe lifts a value of the underlying monad type
-- into a Pipe computation.
liftPipe :: (Monad m) => m r -> Pipe context m r
-- | Function runPipes runs the given computation involving pipes
-- and returns the final result. The context argument ensures that
-- no suspended computation can escape its scope.
runPipes :: (Monad m) => (forall context. Pipe context m r) -> m r
-- | A utility function wrapping if-then-else, useful for handling monadic
-- truth values
cond :: a -> a -> Bool -> a
-- | A utility function, useful for handling monadic list values where
-- empty list means success
whenNull :: (Monad m) => m [a] -> [a] -> m [a]
-- | pour copies all data from the source argument into the
-- sink argument, as long as there is anything to copy and the
-- sink accepts it.
pour :: (Monad m, Typeable x) => Source c1 x -> Sink c2 x -> Pipe c m ()
-- | tee is similar to pour except it distributes every input
-- value from the source arguments into both sink1 and
-- sink2.
tee :: (Monad m, Typeable x) => Source c1 x -> Sink c2 x -> Sink c3 x -> Pipe c m ()
-- | getList returns the list of all values generated by the source.
getList :: (Monad m, Typeable x) => Source c1 x -> Pipe c m [x]
-- | putList puts entire list into its sink argument, as long
-- as the sink accepts it. The remainder that wasn't accepted by the sink
-- is the result value.
putList :: (Monad m, Typeable x) => [x] -> Sink c1 x -> Pipe c m [x]
-- | consumeAndSuppress consumes the entire source ignoring the
-- values it generates.
consumeAndSuppress :: (Monad m, Typeable x) => Source c1 x -> Pipe c m ()
instance Show (Suspension context m r)
instance (Monad m) => Monad (Pipe context m)
module Control.Concurrent.SCC.ComponentTypes
-- | The Splitter type represents computations that distribute data
-- acording to some criteria. A splitter should distribute only the
-- original input data, and feed it into the sinks in the same order it
-- has been read from the source. If the two sink arguments of a splitter
-- are the same, the splitter must act as an identity transform.
data (Monad m) => Splitter m x
Splitter :: (forall c1 c2 c3 context. Source c1 x -> Sink c2 x -> Sink c3 x -> Pipe context m [x]) -> (forall c1 c2 c3 context. Source c1 x -> Sink c2 (Maybe x) -> Sink c3 (Maybe x) -> Pipe context m [x]) -> Splitter m x
split :: Splitter m x -> forall c1 c2 c3 context. Source c1 x -> Sink c2 x -> Sink c3 x -> Pipe context m [x]
splitSections :: Splitter m x -> forall c1 c2 c3 context. Source c1 x -> Sink c2 (Maybe x) -> Sink c3 (Maybe x) -> Pipe context m [x]
-- | The Transducer type represents computations that transform data
-- and return no result. A transducer must continue consuming the given
-- source and feeding the sink while there is data.
newtype (Monad m) => Transducer m x y
Transducer :: (forall c1 c2 context. Source c1 x -> Sink c2 y -> Pipe context m [x]) -> Transducer m x y
transduce :: Transducer m x y -> forall c1 c2 context. Source c1 x -> Sink c2 y -> Pipe context m [x]
-- | Function lift121Transducer takes a function that maps one input
-- value to one output value each, and lifts it into a Transducer.
lift121Transducer :: (Monad m, Typeable x, Typeable y) => (x -> y) -> Transducer m x y
-- | Function liftStatelessTransducer takes a function that maps one
-- input value into a list of output values, and lifts it into a
-- Transducer.
liftStatelessTransducer :: (Monad m, Typeable x, Typeable y) => (x -> [y]) -> Transducer m x y
-- | Function liftFoldTransducer creates a stateful transducer that
-- produces only one output value after consuming the entire input.
-- Similar to Data.List.foldl
liftFoldTransducer :: (Monad m, Typeable x, Typeable y) => (y -> x -> y) -> y -> Transducer m x y
-- | Function liftStatefulTransducer constructs a Transducer
-- from a state-transition function and the initial state. The transition
-- function may produce arbitrary output at any transition step.
liftStatefulTransducer :: (Monad m, Typeable x, Typeable y) => (state -> x -> (state, [y])) -> state -> Transducer m x y
-- | Function liftSimpleSplitter lifts a simple, non-sectioning
-- splitter function into a full Splitter
liftSimpleSplitter :: (Monad m, Typeable x) => (forall c1 c2 c3 context. Source c1 x -> Sink c2 x -> Sink c3 x -> Pipe context m [x]) -> Splitter m x
-- | Function liftSectionSplitter lifts a sectioning splitter
-- function into a full Splitter
liftSectionSplitter :: (Monad m, Typeable x) => (forall c1 c2 c3 context. Source c1 x -> Sink c2 (Maybe x) -> Sink c3 (Maybe x) -> Pipe context m [x]) -> Splitter m x
-- | Function liftStatelessSplitter takes a function that assigns a
-- Boolean value to each input item and lifts it into a Splitter
liftStatelessSplitter :: (Monad m, Typeable x) => (x -> Bool) -> Splitter m x
-- | Module Components defines primitive components of
-- Producer, Consumer, Transducer and
-- Splitter types, defined in the Foundation and
-- ComponentTypes modules.
module Control.Concurrent.SCC.Components
-- | Producer fromFile opens the named file and feeds the given sink
-- from its contents.
fromFile :: String -> Producer IO Char ()
-- | Producer fromHandle feeds the given sink from the open file
-- handle.
fromHandle :: Handle -> Producer IO Char ()
-- | Producer fromStdIn feeds the given sink from the standard
-- input.
fromStdIn :: Producer IO Char ()
-- | Consumer appendFile opens the name file and appends the given
-- source to it.
appendFile :: String -> Consumer IO Char ()
-- | Consumer toFile opens the named file and copies the given
-- source into it.
toFile :: String -> Consumer IO Char ()
-- | Consumer toHandle copies the given source into the open file
-- handle.
toHandle :: Handle -> Consumer IO Char ()
-- | Consumer toStdOut copies the given source into the standard
-- output.
toStdOut :: Consumer IO Char ()
toPrint :: (Show x, Typeable x) => Consumer IO x ()
-- | Transducer asis passes its input through unmodified.
asis :: (Monad m, Typeable x) => Transducer m x x
-- | The suppress transducer suppresses all input it receives. It is
-- equivalent to substitute []
suppress :: (Monad m, Typeable x, Typeable y) => Transducer m x y
-- | The erroneous transducer reports an error if any input reaches
-- it.
erroneous :: (Monad m, Typeable x) => Transducer m x x
-- | Transducer prepend passes its input unmodified, except for
-- prepending contents of the given list parameter before it.
prepend :: (Monad m, Typeable x) => [x] -> Transducer m x x
-- | Transducer append passes its input unmodified, except for
-- appending contents of the given list parameter to its end.
append :: (Monad m, Typeable x) => [x] -> Transducer m x x
-- | The substitute transducer replaces its whole input by its
-- parameter.
substitute :: (Monad m, Typeable x, Typeable y) => [y] -> Transducer m x y
-- | Splitter allTrue feeds its entire input into its true
-- sink.
allTrue :: (Monad m, Typeable x) => Splitter m x
-- | Splitter allFalse feeds its entire input into its false
-- sink.
allFalse :: (Monad m, Typeable x) => Splitter m x
-- | Splitter one feeds all input values to its true sink,
-- treating every value as a separate section.
one :: (Monad m, Typeable x) => Splitter m x
-- | Splitter substring feeds to its true sink all input
-- parts that match the contents of the given list argument. If two
-- overlapping parts of the input both match the argument, only the first
-- one wins.
substring :: (Monad m, Eq x, Typeable x) => [x] -> Splitter m x
-- | Splitter substringMatch feeds to its true sink all input
-- parts that match the contents of the given list argument. If two
-- overlapping parts of the input match the argument, both are considered
-- true.
substringMatch :: (Monad m, Eq x, Typeable x) => [x] -> Splitter m x
-- | Transducer group collects all its input values into a single
-- list.
group :: (Monad m, Typeable x) => Transducer m x [x]
-- | Transducer concatenate flattens the input stream of lists of
-- values into the output stream of values.
concatenate :: (Monad m, Typeable x) => Transducer m [x] x
concatSeparate :: (Monad m, Typeable x) => [x] -> Transducer m [x] x
-- | The lowercase transforms all uppercase letters in the input to
-- lowercase, leaving the rest unchanged.
lowercase :: (Monad m) => Transducer m Char Char
-- | The uppercase transforms all lowercase letters in the input to
-- uppercase, leaving the rest unchanged.
uppercase :: (Monad m) => Transducer m Char Char
-- | Splitter whitespace feeds all white-space characters into its
-- true sink, all others into false.
whitespace :: (Monad m) => Splitter m Char
-- | Splitter letters feeds all alphabetical characters into its
-- true sink, all other characters into false.
letters :: (Monad m) => Splitter m Char
-- | Splitter digits feeds all digits into its true sink, all
-- other characters into false.
digits :: (Monad m) => Splitter m Char
-- | The sectioning splitter line feeds line-ends into its
-- false sink, and line contents into true. A single
-- line-end can be formed by any of the character sequences "\n", "\r",
-- "\r\n", or "\n\r".
line :: (Monad m) => Splitter m Char
-- | Splitter nonEmptyLine feeds line-ends into its false
-- sink, and all other characters into true.
nonEmptyLine :: (Monad m) => Splitter m Char
-- | The count transducer counts all its input values and outputs
-- the final tally.
count :: (Monad m, Typeable x) => Transducer m x Integer
toString :: (Monad m, Show x, Typeable x) => Transducer m x String
-- | The Combinators module defines combinators applicable to
-- Transducer and Splitter components defined in the
-- ComponentTypes module.
module Control.Concurrent.SCC.Combinators
-- | The result of combinator ->> is a consumer that acts as a
-- composition of the given transducer and consumer arguments.
(->>) :: (Monad m, Typeable x, Typeable y) => Transducer m x y -> Consumer m y r -> Consumer m x r
-- | The result of combinator <<- is a producer that acts as a
-- composition of the given transducer and producer arguments.
(<<-) :: (Monad m, Typeable x, Typeable y) => Transducer m x y -> Producer m x r -> Producer m y r
-- | The >-> combinator composes its argument transducers. The
-- resulting composition t1 >-> t2 passes its input through
-- the first transducer t1, the output of t1 is passed to
-- the other transducer t2, and its output becomes the output of
-- the composition.
(>->) :: (Monad m) => Transducer m x y -> Transducer m y z -> Transducer m x z
-- | The join combinator arranges the two transducer arguments in
-- parallel. The input of the resulting transducer is replicated to both
-- component transducers in parallel, and the output of the resulting
-- transducer is a concatenation of the two component transducers'
-- outputs.
join :: (Monad m, Typeable x) => Transducer m x y -> Transducer m x y -> Transducer m x y
-- | The snot (streaming not) combinator simply reverses the outputs
-- of the argument splitter. In other words, data that the argument
-- splitter sends to its true sink goes to the false sink
-- of the result, and vice versa.
snot :: (Monad m, Typeable x) => Splitter m x -> Splitter m x
-- | The >& combinator sends the true sink output of
-- its left operand to the input of its right operand for further
-- splitting. Both operands' false sinks are connected to the
-- false sink of the combined splitter, but any input value to
-- reach the true sink of the combined component data must be
-- deemed true by both splitters.
(>&) :: (Monad m, Typeable x) => Splitter m x -> Splitter m x -> Splitter m x
-- | A >| combinator's input value can reach its false
-- sink only by going through both argument splitters' false
-- sinks.
(>|) :: (Monad m, Typeable x) => Splitter m x -> Splitter m x -> Splitter m x
-- | Combinator && is a pairwise logical conjunction of two
-- splitters run in parallel on the same input.
(&&) :: (Monad m, Typeable x) => Splitter m x -> Splitter m x -> Splitter m x
-- | Combinator || is a pairwise logical disjunction of two
-- splitters run in parallel on the same input.
(||) :: (Monad m, Typeable x) => Splitter m x -> Splitter m x -> Splitter m x
-- | The result of the combinator ifs is a transducer that applies
-- one argument transducer to one portion of the input and the other
-- transducer to the other portion of input, depending on where the
-- splitter argument routes the data.
ifs :: (Monad m, Typeable x) => Splitter m x -> Transducer m x y -> Transducer m x y -> Transducer m x y
wherever :: (Monad m, Typeable x) => Transducer m x x -> Splitter m x -> Transducer m x x
unless :: (Monad m, Typeable x) => Transducer m x x -> Splitter m x -> Transducer m x x
select :: (Monad m, Typeable x) => Splitter m x -> Transducer m x x
-- | The recursive combinator while feeds the true sink of the
-- argument splitter back to itself, modified by the argument transducer.
-- Data fed to the splitter's false sink is passed on unmodified.
while :: (Monad m, Typeable x) => Transducer m x x -> Splitter m x -> Transducer m x x
-- | The recursive combinator nestedIn combines two splitters into a
-- mutually recursive loop acting as a single splitter. The true sink of
-- one of the argument splitters and false sink of the other become the
-- true and false sinks of the loop. The other two sinks are bound to the
-- other splitter's source. The use of nestedIn makes sense only
-- on hierarchically structured streams. If we gave it some input
-- containing a flat sequence of values, and assuming both component
-- splitters are deterministic and stateless, a value would either not
-- loop at all or it would loop forever.
nestedIn :: (Monad m, Typeable x) => Splitter m x -> Splitter m x -> Splitter m x
-- | The foreach combinator is similar to the combinator ifs
-- in that it combines a splitter and two transducers into another
-- transducer. However, in this case the transducers are re-instantiated
-- for each consecutive portion of the input as the splitter chunks it
-- up. Each contiguous portion of the input that the splitter sends to
-- one of its two sinks gets transducered through the appropriate
-- argument transducer as that transducer's whole input. As soon as the
-- contiguous portion is finished, the transducer gets terminated.
foreach :: (Monad m, Typeable x, Typeable y) => Splitter m x -> Transducer m x y -> Transducer m x y -> Transducer m x y
-- | The having combinator combines two pure splitters into a pure
-- splitter. One splitter is used to chunk the input into contiguous
-- portions. Its false sink is routed directly to the false
-- sink of the combined splitter. The second splitter is instantiated and
-- run on each portion of the input that goes to first splitter's
-- true sink. If the second splitter sends any output at all to
-- its true sink, the whole input portion is passed on to the
-- true sink of the combined splitter, otherwise it goes to its
-- false sink.
having :: (Monad m, Typeable x) => Splitter m x -> Splitter m x -> Splitter m x
-- | The havingOnly combinator is analogous to the having
-- combinator, but it succeeds and passes each chunk of the input to its
-- true sink only if the second splitter sends no part of it to
-- its false sink.
havingOnly :: (Monad m, Typeable x) => Splitter m x -> Splitter m x -> Splitter m x
-- | Combinator followedBy treats its argument Splitters as
-- patterns components and returns a Splitter that matches their
-- concatenation. A section of input is considered true by the
-- result iff its prefix is considered true by argument s1
-- and the rest of the section is considered true by s2.
-- The splitter s2 is started anew after every section split to
-- true sink by s1.
followedBy :: (Monad m, Typeable x) => Splitter m x -> Splitter m x -> Splitter m x
-- | The even combinator takes every input section that its argument
-- splitters deems true, and feeds even ones into its true
-- sink. The odd sections and parts of input that are false
-- according to its argument splitter are fed to even splitter's
-- false sink.
even :: (Monad m, Typeable x) => Splitter m x -> Splitter m x
-- | The result of combinator first behaves the same as the argument
-- splitter up to and including the first portion of the input which goes
-- into the argument's true sink. All input following the first
-- true portion goes into the false sink.
first :: (Monad m, Typeable x) => Splitter m x -> Splitter m x
-- | The result of combinator uptoFirst takes all input up to and
-- including the first portion of the input which goes into the
-- argument's true sink and feeds it to the result splitter's
-- true sink. All the rest of the input goes into the false
-- sink. The only difference between last and lastAndAfter
-- combinators is in where they direct the false portion of the
-- input preceding the first true part.
uptoFirst :: (Monad m, Typeable x) => Splitter m x -> Splitter m x
-- | The prefix combinator feeds its true sink only the
-- prefix of the input that its argument feeds to its true sink.
-- All the rest of the input is dumped into the false sink of the
-- result.
prefix :: (Monad m, Typeable x) => Splitter m x -> Splitter m x
-- | The result of the combinator last is a splitter which directs
-- all input to its false sink, up to the last portion of the
-- input which goes to its argument's true sink. That portion of
-- the input is the only one that goes to the resulting component's
-- true sink. The splitter returned by the combinator last
-- has to buffer the previous two portions of its input, because it
-- cannot know if a true portion of the input is the last one until it
-- sees the end of the input or another portion succeeding the previous
-- one.
last :: (Monad m, Typeable x) => Splitter m x -> Splitter m x
-- | The result of the combinator lastAndAfter is a splitter which
-- directs all input to its false sink, up to the last portion of
-- the input which goes to its argument's true sink. That portion
-- and the remainder of the input is fed to the resulting component's
-- true sink. The difference between last and
-- lastAndAfter combinators is where they feed the false
-- portion of the input, if any, remaining after the last true
-- part.
lastAndAfter :: (Monad m, Typeable x) => Splitter m x -> Splitter m x
-- | The suffix combinator feeds its true sink only the
-- suffix of the input that its argument feeds to its true sink.
-- All the rest of the input is dumped into the false sink of the
-- result.
suffix :: (Monad m, Typeable x) => Splitter m x -> Splitter m x
-- | Combinator between passes to its true sink all input
-- that follows a section considered true by its first argument splitter
-- but not a section considered true by its second argument. The section
-- delimiter pairs can nest to arbitrary depth.
between :: (Monad m, Typeable x) => Splitter m x -> Splitter m x -> Splitter m x
-- | Combinator ... is similar to between, except it passes
-- to true the delimiting sections as well as all input between
-- them.
(...) :: (Monad m, Typeable x) => Splitter m x -> Splitter m x -> Splitter m x