-- 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 original library design is based on paper
-- http://conferences.idealliance.org/extreme/html/2006/Blazevic01/EML2006Blazevic01.html
--
-- Mario Blažević, Streaming component combinators, Extreme Markup
-- Languages, 2006.
@package scc
@version 0.3
-- | Module Foundation defines the pipe computations and their basic
-- building blocks.
module Control.Concurrent.SCC.Foundation
class (Monad m) => ParallelizableMonad m
parallelize :: (ParallelizableMonad m) => m a -> m b -> m (a, b)
-- | 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 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
-- | 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 context m x r1 -> Consumer context 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 c m x r1 -> Consumer c m x r2 -> Pipe c m (r1, r2)
-- | The pipeP function is equivalent to pipe, except the
-- producer and consumer are run in parallel if resources
-- allow.
pipeP :: (ParallelizableMonad m) => Producer c m x r1 -> Consumer c m x r2 -> Pipe c 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 get' assumes that the argument source is not empty and
-- returns the value the source yields. If the source is empty, the
-- function throws an error.
get' :: (Monad m, Typeable x) => Source context x -> Pipe context m x
-- | 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 c x -> Sink c x -> Pipe c m ()
-- | pourMap is like pour that applies the function f
-- to each argument before passing it into the sink.
pourMap :: (Monad m, Typeable x, Typeable y) => (x -> y) -> Source c x -> Sink c y -> Pipe c m ()
-- | pourMapMaybe is to pourMap like
-- Data.Maybe.mapMaybe is to Data.List.Map.
pourMapMaybe :: (Monad m, Typeable x, Typeable y) => (x -> Maybe y) -> Source c x -> Sink c y -> 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 c x -> Sink c x -> Sink c x -> Pipe c m ()
-- | getList returns the list of all values generated by the source.
getList :: (Monad m, Typeable x) => Source c 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 c x -> Pipe c m [x]
-- | Like putList, except it puts the contents of the given
-- Seq into the sink.
putQueue :: (Monad m, Typeable x) => Seq x -> Sink c x -> Pipe c m [x]
-- | consumeAndSuppress consumes the entire source ignoring the
-- values it generates.
consumeAndSuppress :: (Monad m, Typeable x) => Source c x -> Pipe c m ()
instance Show (Suspension context m r)
instance (ParallelizableMonad m) => ParallelizableMonad (Pipe context m)
instance (Monad m) => Monad (Pipe context m)
instance ParallelizableMonad IO
instance ParallelizableMonad Maybe
instance ParallelizableMonad Identity
module Control.Concurrent.SCC.ComponentTypes
-- | The types of Component class carry metadata and can be
-- configured to use a specific number of threads.
class Component c
name :: (Component c) => c -> String
subComponents :: (Component c) => c -> [AnyComponent]
maxUsableThreads :: (Component c) => c -> Int
usingThreads :: (Component c) => Int -> c -> c
usedThreads :: (Component c) => c -> Int
cost :: (Component c) => c -> Int
-- | BranchComponent is a type class representing all components
-- that can act as consumers, namely Consumer, Transducer,
-- and Splitter.
class BranchComponent cc m x r | cc -> m x
combineBranches :: (BranchComponent cc m x r) => String -> Int -> (forall c. Bool -> (Source c x -> Pipe c m r) -> (Source c x -> Pipe c m r) -> (Source c x -> Pipe c m r)) -> cc -> cc -> cc
class LiftableComponent cx cy x y | cx -> x, cy -> y, cx y -> cy, cy x -> cx
liftComponent :: (LiftableComponent cx cy x y) => cy -> cx
-- | The Container class applies to two types where a first type
-- value may contain values of the second type.
class Container x y
unwrap :: (Container x y, ParallelizableMonad m) => (Splitter m x (), Transducer m x y)
rewrap :: (Container x y, ParallelizableMonad m) => Transducer m y x
-- | AnyComponent is an existential type wrapper around a
-- Component.
data AnyComponent
AnyComponent :: a -> AnyComponent
-- | A component that performs a computation with no inputs nor outputs is
-- a Performer.
data Performer m r
Performer :: String -> Int -> ComponentConfiguration -> (Int -> (ComponentConfiguration, forall c. Pipe c m r)) -> (forall c. Pipe c m r) -> Performer m r
performerName :: Performer m r -> String
performerMaxThreads :: Performer m r -> Int
performerConfiguration :: Performer m r -> ComponentConfiguration
performerUsingThreads :: Performer m r -> Int -> (ComponentConfiguration, forall c. Pipe c m r)
perform :: Performer m r -> forall c. Pipe c m r
-- | A component that consumes values from a Source is called
-- Consumer. data Consumer m x r = Consumer {consumerData ::
-- ComponentData (forall c. Source c x -> Pipe c m r), consume ::
-- forall c. Source c x -> Pipe c m r}
data Consumer m x r
Consumer :: String -> Int -> ComponentConfiguration -> (Int -> (ComponentConfiguration, forall c. Source c x -> Pipe c m r)) -> (forall c. Source c x -> Pipe c m r) -> Consumer m x r
consumerName :: Consumer m x r -> String
consumerMaxThreads :: Consumer m x r -> Int
consumerConfiguration :: Consumer m x r -> ComponentConfiguration
consumerUsingThreads :: Consumer m x r -> Int -> (ComponentConfiguration, forall c. Source c x -> Pipe c m r)
consume :: Consumer m x r -> forall c. Source c x -> Pipe c m r
-- | A component that produces values and puts them into a Sink is
-- called Producer.
data Producer m x r
Producer :: String -> Int -> ComponentConfiguration -> (Int -> (ComponentConfiguration, forall c. Sink c x -> Pipe c m r)) -> (forall c. Sink c x -> Pipe c m r) -> Producer m x r
producerName :: Producer m x r -> String
producerMaxThreads :: Producer m x r -> Int
producerConfiguration :: Producer m x r -> ComponentConfiguration
producerUsingThreads :: Producer m x r -> Int -> (ComponentConfiguration, forall c. Sink c x -> Pipe c m r)
produce :: Producer m x r -> forall c. Sink c x -> Pipe c m r
-- | 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 c x' arguments of a
-- splitter are the same, the splitter must act as an identity transform.
data Splitter m x b
Splitter :: String -> Int -> ComponentConfiguration -> (Int -> (ComponentConfiguration, forall c. Source c x -> Sink c x -> Sink c x -> Sink c b -> Pipe c m [x])) -> (forall c. Source c x -> Sink c x -> Sink c x -> Sink c b -> Pipe c m [x]) -> Splitter m x b
splitterName :: Splitter m x b -> String
splitterMaxThreads :: Splitter m x b -> Int
splitterConfiguration :: Splitter m x b -> ComponentConfiguration
splitterUsingThreads :: Splitter m x b -> Int -> (ComponentConfiguration, forall c. Source c x -> Sink c x -> Sink c x -> Sink c b -> Pipe c m [x])
split :: Splitter m x b -> forall c. Source c x -> Sink c x -> Sink c x -> Sink c b -> Pipe c 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.
data Transducer m x y
Transducer :: String -> Int -> ComponentConfiguration -> (Int -> (ComponentConfiguration, forall c. Source c x -> Sink c y -> Pipe c m [x])) -> (forall c. Source c x -> Sink c y -> Pipe c m [x]) -> Transducer m x y
transducerName :: Transducer m x y -> String
transducerMaxThreads :: Transducer m x y -> Int
transducerConfiguration :: Transducer m x y -> ComponentConfiguration
transducerUsingThreads :: Transducer m x y -> Int -> (ComponentConfiguration, forall c. Source c x -> Sink c y -> Pipe c m [x])
transduce :: Transducer m x y -> forall c. Source c x -> Sink c y -> Pipe c m [x]
data ComponentConfiguration
ComponentConfiguration :: [AnyComponent] -> Int -> Int -> ComponentConfiguration
componentChildren :: ComponentConfiguration -> [AnyComponent]
componentThreads :: ComponentConfiguration -> Int
componentCost :: ComponentConfiguration -> Int
-- | A Markup value is produced to mark either a Start and
-- End of a region of data, or an arbitrary Point in data.
-- A Point is semantically equivalent to a Start
-- immediately followed by End. The Content constructor
-- wraps the actual data.
data Boundary y
Start :: y -> Boundary y
End :: y -> Boundary y
Point :: y -> Boundary y
data Markup x y
Content :: x -> Markup x y
Markup :: (Boundary y) -> Markup x y
type Parser m x b = Transducer m x (Markup x b)
-- | Function liftPerformer takes a component name, maximum number
-- of threads it can use, and its usingThreads method, and returns
-- a Performer component.
liftPerformer :: String -> Int -> (Int -> (ComponentConfiguration, forall c. Pipe c m r)) -> Performer m r
-- | Function liftConsumer takes a component name, maximum number of
-- threads it can use, and its usingThreads method, and returns a
-- Consumer component.
liftConsumer :: String -> Int -> (Int -> (ComponentConfiguration, forall c. Source c x -> Pipe c m r)) -> Consumer m x r
-- | Function liftAtomicConsumer lifts a single-threaded
-- consume function into a Consumer component.
liftAtomicConsumer :: String -> Int -> (forall c. Source c x -> Pipe c m r) -> Consumer m x r
-- | Function liftProducer takes a component name, maximum number of
-- threads it can use, and its usingThreads method, and returns a
-- Producer component.
liftProducer :: String -> Int -> (Int -> (ComponentConfiguration, forall c. Sink c x -> Pipe c m r)) -> Producer m x r
-- | Function liftAtomicProducer lifts a single-threaded
-- produce function into a Producer component.
liftAtomicProducer :: String -> Int -> (forall c. Sink c x -> Pipe c m r) -> Producer m x r
-- | Function liftTransducer takes a component name, maximum number
-- of threads it can use, and its usingThreads method, and returns
-- a Transducer component.
liftTransducer :: String -> Int -> (Int -> (ComponentConfiguration, forall c. Source c x -> Sink c y -> Pipe c m [x])) -> Transducer m x y
-- | Function liftAtomicTransducer lifts a single-threaded
-- transduce function into a Transducer component.
liftAtomicTransducer :: String -> Int -> (forall c. Source c x -> Sink c y -> Pipe c m [x]) -> Transducer m x y
-- | 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) => String -> (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) => String -> (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) => String -> (s -> x -> s) -> s -> (s -> 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) => String -> (state -> x -> (state, [y])) -> state -> Transducer m x y
-- | Function liftSplitter lifts a splitter function into a full
-- Splitter.
liftSplitter :: (Monad m, Typeable x) => String -> Int -> (Int -> (ComponentConfiguration, forall c. Source c x -> Sink c x -> Sink c x -> Sink c b -> Pipe c m [x])) -> Splitter m x b
-- | Function liftAtomicSplitter lifts a single-threaded
-- split function into a Splitter component.
liftAtomicSplitter :: (Monad m, Typeable x) => String -> Int -> (forall c. Source c x -> Sink c x -> Sink c x -> Sink c b -> Pipe c m [x]) -> Splitter m x b
-- | Function liftStatelessSplitter takes a function that assigns a
-- Boolean value to each input item and lifts it into a Splitter.
liftStatelessSplitter :: (ParallelizableMonad m, Typeable x) => String -> (x -> Bool) -> Splitter m x b
-- | Function liftStatefulSplitter takes a state-converting function
-- that also assigns a Boolean value to each input item and lifts it into
-- a Splitter.
liftStatefulSplitter :: (ParallelizableMonad m, Typeable x) => String -> (state -> x -> (state, Bool)) -> state -> Splitter m x ()
-- | Show details of the given component's configuration.
showComponentTree :: (Component c) => c -> String
-- | Function optimalTwoParallelConfigurations configures two
-- components assuming they can be run in parallel, splitting the given
-- thread count between them, and returns the configured components, a
-- ComponentConfiguration that can be used to build a new
-- component from them, and a flag that indicates if they should be run
-- in parallel or sequentially for optimal resource usage.
optimalTwoParallelConfigurations :: (Component c1, Component c2) => Int -> c1 -> c2 -> (ComponentConfiguration, c1, c2, Bool)
-- | Function optimalTwoParallelConfigurations configures two
-- components, both of them with the full thread count, and returns the
-- components and a ComponentConfiguration that can be used to
-- build a new component from them.
optimalTwoSequentialConfigurations :: (Component c1, Component c2) => Int -> c1 -> c2 -> (ComponentConfiguration, c1, c2)
-- | Function optimalThreeParallelConfigurations configures three
-- components assuming they can be run in parallel, splitting the given
-- thread count between them, and returns the components, a
-- ComponentConfiguration that can be used to build a new
-- component from them, and a flag per component that indicates if it
-- should be run in parallel or sequentially for optimal resource usage.
optimalThreeParallelConfigurations :: (Component c1, Component c2, Component c3) => Int -> c1 -> c2 -> c3 -> (ComponentConfiguration, (c1, Bool), (c2, Bool), (c3, Bool))
-- | Given a Splitter, a Source, and three consumer
-- functions, splitToConsumers runs the splitter on the source and
-- feeds the splitter's outputs to its true, false, and
-- edge sinks, respectively, to the three consumers.
splitToConsumers :: (ParallelizableMonad m, Typeable x, Typeable b) => Splitter m x b -> Source c x -> (Source c x -> Pipe c m r1) -> (Source c x -> Pipe c m r2) -> (Source c b -> Pipe c m r3) -> Pipe c m ([x], r1, r2, r3)
-- | Given a Splitter, a Source, and two consumer functions,
-- splitInputToConsumers runs the splitter on the source and feeds
-- the splitter's true and false outputs, respectively, to
-- the two consumers.
splitInputToConsumers :: (ParallelizableMonad m, Typeable x, Typeable b) => Bool -> Splitter m x b -> Source c x -> (Source c x -> Pipe c m [x]) -> (Source c x -> Pipe c m [x]) -> Pipe c m [x]
instance Typeable2 Markup
instance Typeable1 Boundary
instance (Eq x, Eq y) => Eq (Markup x y)
instance (Eq y) => Eq (Boundary y)
instance (Show y) => Show (Boundary y)
instance (ParallelizableMonad m, Typeable x) => BranchComponent (Splitter m x b) m x [x]
instance BranchComponent (Transducer m x y) m x [x]
instance (Monad m) => BranchComponent (Consumer m x ()) m x [x]
instance (Monad m) => BranchComponent (Consumer m x r) m x r
instance Component (Splitter m x b)
instance Component (Transducer m x y)
instance Component (Producer m x r)
instance Component (Consumer m x r)
instance Component (Performer m r)
instance (Container x y, ParallelizableMonad m, Typeable x, Typeable y) => LiftableComponent (Splitter m x ()) (Splitter m y ()) x y
instance (Container x y, ParallelizableMonad m, Typeable x, Typeable y) => LiftableComponent (Transducer m x x) (Transducer m y y) x y
instance (Typeable x, Typeable y) => Container (Markup x y) x
instance (Show y) => Show (Markup Char y)
instance Functor Boundary
instance Component AnyComponent
-- | The Combinators module defines combinators applicable to
-- Transducer and Splitter components defined in the
-- Control.Concurrent.SCC.ComponentTypes module.
module Control.Concurrent.SCC.Combinators
-- | Converts a Splitter into a Transducer. Every input value
-- x that the argument splitter sends to its true sink is
-- converted to Left (x, True), every y sent to the
-- splitter's false sink becomes Left (y, False), and any
-- value e the splitter puts in its edge sink becomes
-- Right e.
splitterToMarker :: (ParallelizableMonad m, Typeable x, Typeable b) => Splitter m x b -> Transducer m x (Either (x, Bool) b)
-- | Converts a Consumer into a Transducer with no output.
consumeBy :: (Monad m, Typeable x) => Consumer m x r -> Transducer m x y
-- | Combinator prepend converts the given producer to transducer
-- that passes all its input through unmodified, except | for prepending
-- the output of the argument producer to it. | prepend
-- prefix = join (substitute prefix)
-- asis
prepend :: (Monad m, Typeable x) => Producer m x r -> Transducer m x x
-- | Combinator append converts the given producer to transducer
-- that passes all its input through unmodified, finally | appending to
-- it the output of the argument producer. | append suffix
-- = join asis (substitute suffix)
append :: (Monad m, Typeable x) => Producer m x r -> Transducer m x x
-- | The substitute combinator converts its argument producer to a
-- transducer that produces the same output, while | consuming its entire
-- input and ignoring it.
substitute :: (Monad m, Typeable x, Typeable y) => Producer m y r -> Transducer m x y
-- | Class PipeableComponentPair applies to any two components that
-- can be combined into a third component with the following properties:
--
--
-- - The input of the result, if any, becomes the input of the first
-- component.
-- - The output produced by the first child component is consumed by
-- the second child component.
-- - The result output, if any, is the output of the second
-- component.
--
class PipeableComponentPair m :: (* -> *) w c1 c2 c3 | c1 c2 -> c3, c1 c3 -> c2, c2 c3 -> c2, c1 -> m w, c2 -> m w, c3 -> m
(>->) :: (PipeableComponentPair m w c1 c2 c3) => c1 -> c2 -> c3
-- | Class JoinableComponentPair applies to any two components that
-- can be combined into a third component with the following properties:
--
--
-- - if both argument components consume input, the input of the
-- combined component gets distributed to both components in
-- parallel,
-- - if both argument components produce output, the output of the
-- combined component is a concatenation of the complete output from the
-- first component followed by the complete output of the second
-- component, and
-- - the join method may apply the components in any order, the
-- sequence method makes sure its first argument has completed
-- before using the second one.
--
class (Monad m, CompatibleSignature c1 t1 m x y, CompatibleSignature c2 t2 m x y, CompatibleSignature c3 t3 m x y) => JoinableComponentPair t1 t2 t3 m x y c1 c2 c3 | c1 c2 -> c3, c1 -> t1 m, c2 -> t2 m, c3 -> t3 m x y, t1 m x y -> c1, t2 m x y -> c2, t3 m x y -> c3
join :: (JoinableComponentPair t1 t2 t3 m x y c1 c2 c3) => c1 -> c2 -> c3
sequence :: (JoinableComponentPair t1 t2 t3 m x y c1 c2 c3) => c1 -> c2 -> c3
-- | 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 :: (ParallelizableMonad m, Typeable x, Typeable b) => Splitter m x b -> Splitter m x b
-- | 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.
(>&) :: (ParallelizableMonad m, Typeable x, Typeable b1, Typeable b2) => Splitter m x b1 -> Splitter m x b2 -> Splitter m x (b1, b2)
-- | A >| combinator's input value can reach its false
-- sink only by going through both argument splitters' false
-- sinks.
(>|) :: (ParallelizableMonad m, Typeable x, Typeable b1, Typeable b2) => Splitter m x b1 -> Splitter m x b2 -> Splitter m x (Either b1 b2)
-- | Combinator && is a pairwise logical conjunction of two
-- splitters run in parallel on the same input.
(&&) :: (ParallelizableMonad m, Typeable x, Typeable b1, Typeable b2) => Splitter m x b1 -> Splitter m x b2 -> Splitter m x (b1, b2)
-- | Combinator || is a pairwise logical disjunction of two
-- splitters run in parallel on the same input.
(||) :: (ParallelizableMonad m, Typeable x, Typeable b1, Typeable b2) => Splitter m x b1 -> Splitter m x b2 -> Splitter m x (Either b1 b2)
ifs :: (ParallelizableMonad m, Typeable x, Typeable b, BranchComponent cc m x [x]) => Splitter m x b -> cc -> cc -> cc
wherever :: (ParallelizableMonad m, Typeable x, Typeable b) => Transducer m x x -> Splitter m x b -> Transducer m x x
unless :: (ParallelizableMonad m, Typeable x, Typeable b) => Transducer m x x -> Splitter m x b -> Transducer m x x
select :: (ParallelizableMonad m, Typeable x, Typeable b) => Splitter m x b -> 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 :: (ParallelizableMonad m, Typeable x, Typeable b) => Transducer m x x -> Splitter m x b -> 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, an input value would either
-- not loop at all or it would loop forever.
nestedIn :: (ParallelizableMonad m, Typeable x, Typeable b) => Splitter m x b -> Splitter m x b -> Splitter m x b
-- | 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 :: (ParallelizableMonad m, Typeable x, Typeable b, BranchComponent cc m x [x]) => Splitter m x b -> cc -> cc -> cc
-- | 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 :: (ParallelizableMonad m, Typeable x, Typeable b1, Typeable b2) => Splitter m x b1 -> Splitter m x b2 -> Splitter m x b1
-- | 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 :: (ParallelizableMonad m, Typeable x, Typeable b1, Typeable b2) => Splitter m x b1 -> Splitter m x b2 -> Splitter m x b1
-- | 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 :: (ParallelizableMonad m, Typeable x, Typeable b1, Typeable b2) => Splitter m x b1 -> Splitter m x b2 -> Splitter m x (b1, b2)
-- | The even combinator takes every input section that its argument
-- splitter 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 :: (ParallelizableMonad m, Typeable x, Typeable b) => Splitter m x b -> Splitter m x b
-- | 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 :: (ParallelizableMonad m, Typeable x, Typeable b) => Splitter m x b -> Splitter m x b
-- | 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 first and uptoFirst
-- combinators is in where they direct the false portion of the
-- input preceding the first true part.
uptoFirst :: (ParallelizableMonad m, Typeable x, Typeable b) => Splitter m x b -> Splitter m x b
-- | 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 :: (ParallelizableMonad m, Typeable x, Typeable b) => Splitter m x b -> Splitter m x b
-- | 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 :: (ParallelizableMonad m, Typeable x, Typeable b) => Splitter m x b -> Splitter m x b
-- | 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 :: (ParallelizableMonad m, Typeable x, Typeable b) => Splitter m x b -> Splitter m x b
-- | 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 :: (ParallelizableMonad m, Typeable x, Typeable b) => Splitter m x b -> Splitter m x b
-- | Splitter startOf issues an empty true section at the
-- beginning of every section considered true by its | argument
-- splitter, otherwise the entire input goes into its false sink.
startOf :: (ParallelizableMonad m, Typeable x, Typeable b) => Splitter m x b -> Splitter m x (Maybe b)
-- | Splitter endOf issues an empty true section at the end
-- of every section considered true by its argument | splitter,
-- otherwise the entire input goes into its false sink.
endOf :: (ParallelizableMonad m, Typeable x, Typeable b) => Splitter m x b -> Splitter m x (Maybe b)
-- | Combinator ... tracks the running balance of difference between
-- the number of preceding starts of sections considered true
-- according to its first argument and the ones according to its second
-- argument. The combinator passes to true all input values for
-- which the difference balance is positive. This combinator is typically
-- used with startOf and endOf in order to count entire
-- input sections and ignore their lengths.
(...) :: (ParallelizableMonad m, Typeable x, Typeable b1, Typeable b2) => Splitter m x b1 -> Splitter m x b2 -> Splitter m x b1
-- | Converts a splitter into a parser.
parseRegions :: (ParallelizableMonad m, Typeable x, Typeable b) => Splitter m x b -> Parser m x b
-- | Converts a boundary-marking splitter into a parser.
parseNestedRegions :: (ParallelizableMonad m, Typeable x, Typeable b) => Splitter m x (Boundary b) -> Parser m x b
-- | Runs the second argument on every contiguous region of input source
-- (typically produced by splitterToMarker) whose all values
-- either match Left (_, True) or Left (_, False).
groupMarks :: (ParallelizableMonad m, Typeable x, Typeable b) => Source c (Either (x, Bool) b) -> (Maybe (Maybe b) -> Source c x -> Pipe c m r) -> Pipe c m ()
instance (ParallelizableMonad m, Typeable x, Typeable y) => JoinableComponentPair (ConsumerType ()) (ProducerType ()) TransducerType m [x] [y] (Consumer m x ()) (Producer m y ()) (Transducer m x y)
instance (ParallelizableMonad m, Typeable x, Typeable y) => JoinableComponentPair (ProducerType ()) (ConsumerType ()) TransducerType m [x] [y] (Producer m y ()) (Consumer m x ()) (Transducer m x y)
instance (ParallelizableMonad m, Typeable x, Typeable y) => JoinableComponentPair TransducerType (ConsumerType ()) TransducerType m [x] [y] (Transducer m x y) (Consumer m x ()) (Transducer m x y)
instance (ParallelizableMonad m, Typeable x, Typeable y) => JoinableComponentPair (ConsumerType ()) TransducerType TransducerType m [x] [y] (Consumer m x ()) (Transducer m x y) (Transducer m x y)
instance (ParallelizableMonad m, Typeable x, Typeable y) => JoinableComponentPair TransducerType (ProducerType ()) TransducerType m [x] [y] (Transducer m x y) (Producer m y ()) (Transducer m x y)
instance (ParallelizableMonad m, Typeable x, Typeable y) => JoinableComponentPair (ProducerType ()) TransducerType TransducerType m [x] [y] (Producer m y ()) (Transducer m x y) (Transducer m x y)
instance (ParallelizableMonad m, Typeable x, Typeable y) => JoinableComponentPair TransducerType (PerformerType r) TransducerType m [x] [y] (Transducer m x y) (Performer m r) (Transducer m x y)
instance (ParallelizableMonad m, Typeable x, Typeable y) => JoinableComponentPair (PerformerType r) TransducerType TransducerType m [x] [y] (Performer m r) (Transducer m x y) (Transducer m x y)
instance (ParallelizableMonad m, Typeable x) => JoinableComponentPair (ConsumerType r1) (PerformerType r2) (ConsumerType r2) m [x] () (Consumer m x r1) (Performer m r2) (Consumer m x r2)
instance (ParallelizableMonad m, Typeable x) => JoinableComponentPair (PerformerType r1) (ConsumerType r2) (ConsumerType r2) m [x] () (Performer m r1) (Consumer m x r2) (Consumer m x r2)
instance (ParallelizableMonad m, Typeable x) => JoinableComponentPair (ProducerType r1) (PerformerType r2) (ProducerType r2) m () [x] (Producer m x r1) (Performer m r2) (Producer m x r2)
instance (ParallelizableMonad m, Typeable x) => JoinableComponentPair (PerformerType r1) (ProducerType r2) (ProducerType r2) m () [x] (Performer m r1) (Producer m x r2) (Producer m x r2)
instance (ParallelizableMonad m) => JoinableComponentPair (PerformerType r1) (PerformerType r2) (PerformerType r2) m () () (Performer m r1) (Performer m r2) (Performer m r2)
instance (ParallelizableMonad m, Typeable x, Typeable y) => JoinableComponentPair TransducerType TransducerType TransducerType m [x] [y] (Transducer m x y) (Transducer m x y) (Transducer m x y)
instance (ParallelizableMonad m, Typeable x) => JoinableComponentPair (ConsumerType ()) (ConsumerType ()) (ConsumerType ()) m [x] () (Consumer m x ()) (Consumer m x ()) (Consumer m x ())
instance (Monad m, Typeable x) => JoinableComponentPair (ProducerType r1) (ProducerType r2) (ProducerType r2) m () [x] (Producer m x r1) (Producer m x r2) (Producer m x r2)
instance CompatibleSignature (Transducer m x y) TransducerType m [x] [y]
instance (AnyListOrUnit y) => CompatibleSignature (Producer m x r) (ProducerType r) m y [x]
instance (AnyListOrUnit y) => CompatibleSignature (Consumer m x r) (ConsumerType r) m [x] y
instance (AnyListOrUnit x, AnyListOrUnit y) => CompatibleSignature (Performer m r) (PerformerType r) m x y
instance AnyListOrUnit ()
instance AnyListOrUnit [x]
instance (ParallelizableMonad m) => PipeableComponentPair m y (Transducer m x y) (Transducer m y z) (Transducer m x z)
instance (ParallelizableMonad m, Typeable x, Typeable y) => PipeableComponentPair m x (Producer m x r) (Transducer m x y) (Producer m y r)
instance (ParallelizableMonad m, Typeable x, Typeable y) => PipeableComponentPair m y (Transducer m x y) (Consumer m y r) (Consumer m x r)
instance (ParallelizableMonad m, Typeable x) => PipeableComponentPair m x (Producer m x ()) (Consumer m x ()) (Performer m ())
-- | Module Components defines primitive components of
-- Producer, Consumer, Transducer and
-- Splitter types, defined in the Foundation and
-- ComponentTypes modules.
module Control.Concurrent.SCC.Components
-- | Used by parseSubstring to distinguish between overlapping
-- substrings.
data OccurenceTag
-- | fromList produces the contents of the given list argument.
fromList :: (Monad m, Typeable x) => [x] -> Producer m x [x]
-- | Consumer toList copies the given source into a list.
toList :: (Monad m, Typeable x) => Consumer m x [x]
-- | 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. The argument doClose determines if |
-- handle should be closed when the handle is consumed or the sink
-- closed.
fromHandle :: Handle -> Bool -> 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. The argument doClose determines if |
-- handle should be closed once the entire source is consumed and
-- copied.
toHandle :: Handle -> Bool -> Consumer IO Char ()
-- | Consumer toStdOut copies the given source into the standard
-- output.
toStdOut :: Consumer IO Char ()
-- | The suppress consumer suppresses all input it receives. It is
-- equivalent to substitute []
suppress :: (Monad m, Typeable x) => Consumer m x ()
-- | The erroneous consumer reports an error if any input reaches
-- it.
erroneous :: (Monad m, Typeable x) => String -> Consumer m x ()
-- | Transducer asis passes its input through unmodified.
asis :: (Monad m, Typeable x) => Transducer m x x
-- | Transducer parse prepares input content for subsequent parsing.
parse :: (Monad m, Typeable x, Typeable y) => Transducer m x (Markup x y)
-- | Transducer unparse removes all markup from its input and passes
-- the content through.
unparse :: (Monad m, Typeable x, Typeable y) => Transducer m (Markup x y) x
-- | Performs the same task as the substring splitter, but instead
-- of splitting it outputs the input as Markup x
-- OccurenceTag in order to distinguish overlapping strings.
parseSubstring :: (ParallelizableMonad m, Eq x, Typeable x) => [x] -> Parser m x OccurenceTag
-- | Splitter everything feeds its entire input into its true
-- sink.
everything :: (ParallelizableMonad m, Typeable x) => Splitter m x ()
-- | Splitter nothing feeds its entire input into its false
-- sink.
nothing :: (ParallelizableMonad m, Typeable x) => Splitter m x ()
-- | Splitter marked passes all marked-up input sections to its
-- true sink, and all unmarked input to its false sink.
marked :: (ParallelizableMonad m, Typeable x, Typeable y, Eq y) => Splitter m (Markup x y) ()
-- | Splitter markedContent passes the content of all marked-up
-- input sections to its true sink, while the outermost tags and
-- all unmarked input go to its false sink.
markedContent :: (ParallelizableMonad m, Typeable x, Typeable y, Eq y) => Splitter m (Markup x y) ()
-- | Splitter markedWith passes input sections marked-up with the
-- appropriate tag to its true sink, and the rest of the input to
-- its false sink. The argument select determines if the
-- tag is appropriate.
markedWith :: (ParallelizableMonad m, Typeable x, Typeable y, Eq y) => (y -> Bool) -> Splitter m (Markup x y) ()
-- | Splitter contentMarkedWith passes the content of input sections
-- marked-up with the appropriate tag to its true sink, and the
-- rest of the input to its false sink. The argument select
-- determines if the tag is appropriate.
contentMarkedWith :: (ParallelizableMonad m, Typeable x, Typeable y, Eq y) => (y -> Bool) -> Splitter m (Markup x y) ()
-- | Splitter one feeds all input values to its true sink,
-- treating every value as a separate section.
one :: (ParallelizableMonad 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, both are sent
-- to true and each is preceded by an edge.
substring :: (ParallelizableMonad 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
-- | Same as concatenate except it inserts the given separator list
-- between every two input lists.
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 :: (ParallelizableMonad m) => Splitter m Char ()
-- | Splitter letters feeds all alphabetical characters into its
-- true sink, all other characters into false.
letters :: (ParallelizableMonad m) => Splitter m Char ()
-- | Splitter digits feeds all digits into its true sink, all
-- other characters into false.
digits :: (ParallelizableMonad 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 :: (ParallelizableMonad m) => Splitter m Char ()
-- | Splitter nonEmptyLine feeds line-ends into its false
-- sink, and all other characters into true.
nonEmptyLine :: (ParallelizableMonad 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
-- | Converts each input value x to show x.
toString :: (Monad m, Show x, Typeable x) => Transducer m x String
-- | The constant cost of each I/O-performing component.
ioCost :: Int
instance Typeable OccurenceTag
instance Eq OccurenceTag
instance Show OccurenceTag
instance Enum OccurenceTag
-- | Module XMLComponents defines primitive components for parsing
-- and manipulating XML.
module Control.Concurrent.SCC.XMLComponents
data Token
StartTag :: Token
EndTag :: Token
EmptyTag :: Token
ElementName :: Token
AttributeName :: Token
AttributeValue :: Token
EntityReferenceToken :: Token
EntityName :: Token
ProcessingInstruction :: Token
ProcessingInstructionText :: Token
Comment :: Token
CommentText :: Token
StartMarkedSectionCDATA :: Token
EndMarkedSection :: Token
ErrorToken :: String -> Token
-- | The tokens splitter distinguishes XML markup from data content.
-- It is used by parseTokens.
tokens :: (ParallelizableMonad m) => Splitter m Char (Boundary Token)
-- | The XML token parser. This parser converts plain text to parsed text,
-- which is a precondition for using the remaining XML components.
parseTokens :: (ParallelizableMonad m) => Parser m Char Token
-- | Converts an XML entity name into the text value it represents:
-- expandEntity "lt" = "<".
expandEntity :: String -> String
-- | Escapes a character for inclusion into an XML attribute value.
escapeAttributeCharacter :: Char -> String
-- | Escapes a character for inclusion into the XML data content.
escapeContentCharacter :: Char -> String
-- | Splits all top-level elements with all their content to true,
-- all other input to false.
element :: (Monad m) => Splitter m (Markup Char Token) ()
-- | Splits the content of all top-level elements to true, their
-- tags and intervening input to false.
elementContent :: (Monad m) => Splitter m (Markup Char Token) ()
-- | Splits every element name, including the names of nested elements and
-- names in end tags, to true, all the rest of input to
-- false.
elementName :: (ParallelizableMonad m) => Splitter m (Markup Char Token) ()
-- | Splits every attribute specification to true, everything else
-- to false.
attribute :: (ParallelizableMonad m) => Splitter m (Markup Char Token) ()
-- | Splits every attribute name to true, all the rest of input to
-- false.
attributeName :: (ParallelizableMonad m) => Splitter m (Markup Char Token) ()
-- | Splits every attribute value, excluding the quote delimiters, to
-- true, all the rest of input to false.
attributeValue :: (ParallelizableMonad m) => Splitter m (Markup Char Token) ()
-- | Similiar to (having element), except it runs
-- the argument splitter only on each element's start tag, not on the
-- entire element with its content.
elementHavingTag :: (ParallelizableMonad m, Typeable b) => Splitter m (Markup Char Token) b -> Splitter m (Markup Char Token) b
-- | Behaves like having, but the right-hand splitter works on plain
-- instead of marked-up text. This allows regular Char splitters
-- to be applied to parsed XML.
havingText :: (ParallelizableMonad m, Typeable b1, Typeable b2) => Splitter m (Markup Char Token) b1 -> Splitter m Char b2 -> Splitter m (Markup Char Token) b1
-- | Behaves like havingOnly, but the right-hand splitter works on
-- plain instead of marked-up text. This allows regular Char
-- splitters to be applied to parsed XML.
havingOnlyText :: (ParallelizableMonad m, Typeable b1, Typeable b2) => Splitter m (Markup Char Token) b1 -> Splitter m Char b2 -> Splitter m (Markup Char Token) b1
instance Typeable Token
instance Eq Token
instance Show Token