{-
    Copyright 2008-2016 Mario Blazevic

    This file is part of the Streaming Component Combinators (SCC) project.

    The SCC project is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
    License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
    version.

    SCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along with SCC.  If not, see
    <http://www.gnu.org/licenses/>.
-}

{-# LANGUAGE ScopedTypeVariables, RankNTypes, KindSignatures, EmptyDataDecls,
             MultiParamTypeClasses, FlexibleContexts, FlexibleInstances,
             FunctionalDependencies, TypeFamilies #-}
{-# OPTIONS_HADDOCK hide #-}

-- | The "Combinators" module defines combinators applicable to values of the 'Transducer' and 'Splitter' types defined
-- in the "Control.Concurrent.SCC.Types" module.

module Control.Concurrent.SCC.Combinators (
   -- * Consumer, producer, and transducer combinators
   consumeBy, prepend, append, substitute,
   JoinableComponentPair (join, sequence),
   -- * Splitter combinators
   sNot,
   -- ** Pseudo-logic flow combinators
   -- | Combinators 'sAnd' and 'sOr' are only /pseudo/-logic. While the laws of double negation and De Morgan's laws
   -- hold, 'sAnd' and 'sOr' are in general not commutative, associative, nor idempotent. In the special case when all
   -- argument splitters are stateless, such as those produced by 'Control.Concurrent.SCC.Types.statelessSplitter',
   -- these combinators do satisfy all laws of Boolean algebra.
   sAnd, sOr,
   -- ** Zipping logic combinators
   -- | The 'pAnd' and 'pOr' combinators run the argument splitters in parallel and combine their logical outputs using
   -- the corresponding logical operation on each output pair, in a manner similar to 'Data.List.zipWith'. They fully
   -- satisfy the laws of Boolean algebra.
   pAnd, pOr,
   -- * Flow-control combinators
   -- | The following combinators resemble the common flow-control programming language constructs. Combinators 
   -- 'wherever', 'unless', and 'select' are just the special cases of the combinator 'ifs'.
   --
   --    * /transducer/ ``wherever`` /splitter/ = 'ifs' /splitter/ /transducer/ 'Control.Category.id'
   --
   --    * /transducer/ ``unless`` /splitter/ = 'ifs' /splitter/ 'Control.Category.id' /transducer/
   --
   --    * 'select' /splitter/ = 'ifs' /splitter/ 'Control.Category.id'
   --    'Control.Concurrent.SCC.Primitives.suppress'
   --
   ifs, wherever, unless, select,
   -- ** Recursive
   while, nestedIn,
   -- * Section-based combinators
   -- | All combinators in this section use their 'Control.Concurrent.SCC.Splitter' argument to determine the structure
   -- of the input. Every contiguous portion of the input that gets passed to one or the other sink of the splitter is
   -- treated as one section in the logical structure of the input stream. What is done with the section depends on the
   -- combinator, but the sections, and therefore the logical structure of the input stream, are determined by the
   -- argument splitter alone.
   foreach, having, havingOnly, followedBy, even,
   -- ** first and its variants
   first, uptoFirst, prefix,
   -- ** last and its variants
   last, lastAndAfter, suffix,
   -- ** positional splitters
   startOf, endOf, between,
   -- * Parser support
   splitterToMarker, splittersToPairMarker, parserToSplitter, parseRegions,
   -- * Helper functions
   groupMarks, findsTrueIn, findsFalseIn, teeConsumers
   )
where
   
import Prelude hiding (drop, even, join, last, length, map, null, sequence)
import Control.Monad (liftM, void, when)
import Control.Monad.Trans.Class (lift)
import Data.Maybe (isJust, mapMaybe)
import Data.Monoid (Monoid, mempty, mconcat)
import qualified Data.Foldable as Foldable
import qualified Data.List as List (map)
import qualified Data.Sequence as Seq
import Data.Sequence (Seq, (<|), (|>), (><), ViewL (EmptyL, (:<)))

import Control.Monad.Coroutine
import Data.Monoid.Null (MonoidNull(null))
import Data.Monoid.Factorial (FactorialMonoid, length, drop)

import Control.Concurrent.SCC.Streams
import Control.Concurrent.SCC.Types
import Control.Concurrent.SCC.Coercions

-- | Converts a 'Consumer' into a 'Transducer' with no output.
consumeBy :: forall m x y r. (Monad m) => Consumer m x r -> Transducer m x y
consumeBy :: Consumer m x r -> Transducer m x y
consumeBy Consumer m x r
c = (forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
 OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
forall (m :: * -> *) x y.
(forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
 OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
Transducer ((forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
  OpenTransducer m a1 a2 d x y ())
 -> Transducer m x y)
-> (forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
    OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
forall a b. (a -> b) -> a -> b
$ \ Source m a1 x
source Sink m a2 y
_sink -> Consumer m x r -> Source m a1 x -> Coroutine d m r
forall (m :: * -> *) x r.
Consumer m x r
-> forall (a :: * -> *) (d :: * -> *).
   (AncestorFunctor a d, Monoid x) =>
   Source m a x -> Coroutine d m r
consume Consumer m x r
c Source m a1 x
source Coroutine d m r -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

class CompatibleSignature c cons (m :: * -> *) input output | c -> cons m

instance CompatibleSignature (Performer m r)    (PerformerType r)  m x y
instance CompatibleSignature (Consumer m x r)   (ConsumerType r)   m x y
instance CompatibleSignature (Producer m x r)   (ProducerType r)   m y x
instance CompatibleSignature (Transducer m x y)  TransducerType    m x y

data PerformerType r
data ConsumerType r
data ProducerType r
data TransducerType

-- | 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, and
--
--    * 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.
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
   where 
      -- | The 'join' combinator may apply the components in any order.
      join :: PairBinder m -> c1 -> c2 -> c3
      join = (c1 -> c2 -> c3)
-> ((Any -> Any -> m Any) -> m Any -> m Any -> m Any)
-> c1
-> c2
-> c3
forall a b. a -> b -> a
const c1 -> c2 -> c3
forall t1 t2 t3 (m :: * -> *) x y c1 c2 c3.
JoinableComponentPair t1 t2 t3 m x y c1 c2 c3 =>
c1 -> c2 -> c3
sequence
      -- | The 'sequence' combinator makes sure its first argument has completed before using the second one.
      sequence :: c1 -> c2 -> c3

instance forall m x r1 r2. Monad m =>
   JoinableComponentPair (ProducerType r1) (ProducerType r2) (ProducerType r2) m () x
                         (Producer m x r1) (Producer m x r2) (Producer m x r2)
   where sequence :: Producer m x r1 -> Producer m x r2 -> Producer m x r2
sequence Producer m x r1
p1 Producer m x r2
p2 = (forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r2)
-> Producer m x r2
forall (m :: * -> *) x r.
(forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r)
-> Producer m x r
Producer ((forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r2)
 -> Producer m x r2)
-> (forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r2)
-> Producer m x r2
forall a b. (a -> b) -> a -> b
$ \Sink m a x
sink-> Producer m x r1 -> Sink m a x -> Coroutine d m r1
forall (m :: * -> *) x r.
Producer m x r
-> forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r
produce Producer m x r1
p1 Sink m a x
sink Coroutine d m r1 -> Coroutine d m r2 -> Coroutine d m r2
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Producer m x r2 -> Sink m a x -> Coroutine d m r2
forall (m :: * -> *) x r.
Producer m x r
-> forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r
produce Producer m x r2
p2 Sink m a x
sink

instance forall m x. Monad m =>
   JoinableComponentPair (ConsumerType ()) (ConsumerType ()) (ConsumerType ()) m x ()
                         (Consumer m x ()) (Consumer m x ()) (Consumer m x ())
   where join :: PairBinder m
-> Consumer m x () -> Consumer m x () -> Consumer m x ()
join PairBinder m
binder Consumer m x ()
c1 Consumer m x ()
c2 = (forall (a :: * -> *) (d :: * -> *). OpenConsumer m a d x ())
-> Consumer m x ()
forall (m :: * -> *) x r.
(forall (a :: * -> *) (d :: * -> *).
 (AncestorFunctor a d, Monoid x) =>
 Source m a x -> Coroutine d m r)
-> Consumer m x r
Consumer ((((), ()) -> ()) -> Coroutine d m ((), ()) -> Coroutine d m ()
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (() -> ((), ()) -> ()
forall a b. a -> b -> a
const ()) (Coroutine d m ((), ()) -> Coroutine d m ())
-> (Source m a x -> Coroutine d m ((), ()))
-> Source m a x
-> Coroutine d m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PairBinder m
-> (forall (a' :: * -> *).
    OpenConsumer m a' (SourceFunctor (SinkFunctor d x) x) x ())
-> (forall (a' :: * -> *).
    OpenConsumer m a' (SourceFunctor d x) x ())
-> OpenConsumer m a d x ((), ())
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x r1 r2.
Monad m =>
PairBinder m
-> (forall (a' :: * -> *).
    OpenConsumer m a' (SourceFunctor (SinkFunctor d x) x) x r1)
-> (forall (a' :: * -> *).
    OpenConsumer m a' (SourceFunctor d x) x r2)
-> OpenConsumer m a d x (r1, r2)
teeConsumers PairBinder m
binder (Consumer m x ()
-> forall (a :: * -> *) (d :: * -> *). OpenConsumer m a d x ()
forall (m :: * -> *) x r.
Consumer m x r
-> forall (a :: * -> *) (d :: * -> *).
   (AncestorFunctor a d, Monoid x) =>
   Source m a x -> Coroutine d m r
consume Consumer m x ()
c1) (Consumer m x ()
-> forall (a :: * -> *) (d :: * -> *). OpenConsumer m a d x ()
forall (m :: * -> *) x r.
Consumer m x r
-> forall (a :: * -> *) (d :: * -> *).
   (AncestorFunctor a d, Monoid x) =>
   Source m a x -> Coroutine d m r
consume Consumer m x ()
c2))
         sequence :: Consumer m x () -> Consumer m x () -> Consumer m x ()
sequence Consumer m x ()
c1 Consumer m x ()
c2 = (forall (a :: * -> *) (d :: * -> *). OpenConsumer m a d x ())
-> Consumer m x ()
forall (m :: * -> *) x r.
(forall (a :: * -> *) (d :: * -> *).
 (AncestorFunctor a d, Monoid x) =>
 Source m a x -> Coroutine d m r)
-> Consumer m x r
Consumer ((forall (a :: * -> *) (d :: * -> *). OpenConsumer m a d x ())
 -> Consumer m x ())
-> (forall (a :: * -> *) (d :: * -> *). OpenConsumer m a d x ())
-> Consumer m x ()
forall a b. (a -> b) -> a -> b
$ \Source m a x
source->
                          PairBinder m
-> (forall (a' :: * -> *).
    OpenConsumer m a' (SourceFunctor (SinkFunctor d x) x) x ())
-> (forall (a' :: * -> *).
    OpenConsumer m a' (SourceFunctor d x) x x)
-> Source m a x
-> Coroutine d m ((), x)
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x r1 r2.
Monad m =>
PairBinder m
-> (forall (a' :: * -> *).
    OpenConsumer m a' (SourceFunctor (SinkFunctor d x) x) x r1)
-> (forall (a' :: * -> *).
    OpenConsumer m a' (SourceFunctor d x) x r2)
-> OpenConsumer m a d x (r1, r2)
teeConsumers PairBinder m
forall (m :: * -> *). Monad m => PairBinder m
sequentialBinder (Consumer m x ()
-> forall (a :: * -> *) (d :: * -> *). OpenConsumer m a d x ()
forall (m :: * -> *) x r.
Consumer m x r
-> forall (a :: * -> *) (d :: * -> *).
   (AncestorFunctor a d, Monoid x) =>
   Source m a x -> Coroutine d m r
consume Consumer m x ()
c1) forall (a' :: * -> *). OpenConsumer m a' (SourceFunctor d x) x x
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, Monoid x, AncestorFunctor a d) =>
Source m a x -> Coroutine d m x
getAll Source m a x
source
                          Coroutine d m ((), x)
-> (((), x) -> Coroutine d m ()) -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \((), x
list)-> (Sink m (SinkFunctor d x) x -> Coroutine (SinkFunctor d x) m x)
-> (Source m (SourceFunctor d x) x
    -> Coroutine (SourceFunctor d x) m ())
-> Coroutine d m (x, ())
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
(Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2) -> Coroutine a m (r1, r2)
pipe ((Sink m (SinkFunctor d x) x
 -> x -> Coroutine (SinkFunctor d x) m x)
-> x
-> Sink m (SinkFunctor d x) x
-> Coroutine (SinkFunctor d x) m x
forall a b c. (a -> b -> c) -> b -> a -> c
flip Sink m (SinkFunctor d x) x -> x -> Coroutine (SinkFunctor d x) m x
forall (m :: * -> *) (a :: * -> *) x.
Sink m a x
-> forall (d :: * -> *).
   AncestorFunctor a d =>
   x -> Coroutine d m x
putChunk x
list) (Consumer m x ()
-> forall (a :: * -> *) (d :: * -> *). OpenConsumer m a d x ()
forall (m :: * -> *) x r.
Consumer m x r
-> forall (a :: * -> *) (d :: * -> *).
   (AncestorFunctor a d, Monoid x) =>
   Source m a x -> Coroutine d m r
consume Consumer m x ()
c2)
                          Coroutine d m (x, ()) -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

instance forall m x y. (Monad m, Monoid x, Monoid y) =>
   JoinableComponentPair TransducerType TransducerType TransducerType m x y
                         (Transducer m x y) (Transducer m x y) (Transducer m x y)
   where join :: PairBinder m
-> Transducer m x y -> Transducer m x y -> Transducer m x y
join PairBinder m
binder Transducer m x y
t1 Transducer m x y
t2 = (forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d y -> Coroutine d m ())
-> Transducer m x y
forall (m :: * -> *) x y.
(Monad m, Monoid x) =>
(forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d y -> Coroutine d m ())
-> Transducer m x y
isolateTransducer ((forall (d :: * -> *).
  Functor d =>
  Source m d x -> Sink m d y -> Coroutine d m ())
 -> Transducer m x y)
-> (forall (d :: * -> *).
    Functor d =>
    Source m d x -> Sink m d y -> Coroutine d m ())
-> Transducer m x y
forall a b. (a -> b) -> a -> b
$ \Source m d x
source Sink m d y
sink->
                             (Sink m (SinkFunctor d y) y
 -> Coroutine (SinkFunctor d y) m ((), ()))
-> (Source m (SourceFunctor d y) y
    -> Coroutine (SourceFunctor d y) m y)
-> Coroutine d m (((), ()), y)
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
(Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2) -> Coroutine a m (r1, r2)
pipe
                                (\Sink m (SinkFunctor d y) y
buffer-> PairBinder m
-> (forall (a' :: * -> *).
    OpenConsumer
      m a' (SourceFunctor (SinkFunctor (SinkFunctor d y) x) x) x ())
-> (forall (a' :: * -> *).
    OpenConsumer m a' (SourceFunctor (SinkFunctor d y) x) x ())
-> Source m d x
-> Coroutine (SinkFunctor d y) m ((), ())
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x r1 r2.
Monad m =>
PairBinder m
-> (forall (a' :: * -> *).
    OpenConsumer m a' (SourceFunctor (SinkFunctor d x) x) x r1)
-> (forall (a' :: * -> *).
    OpenConsumer m a' (SourceFunctor d x) x r2)
-> OpenConsumer m a d x (r1, r2)
teeConsumers PairBinder m
binder
                                              (\Source m a' x
source'-> Transducer m x y
-> Source m a' x
-> Sink m d y
-> Coroutine
     (SourceFunctor (SinkFunctor (SinkFunctor d y) x) x) m ()
forall (m :: * -> *) x y.
Transducer m x y
-> forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
   OpenTransducer m a1 a2 d x y ()
transduce Transducer m x y
t1 Source m a' x
source' Sink m d y
sink)
                                              (\Source m a' x
source'-> Transducer m x y
-> Source m a' x
-> Sink m (SinkFunctor d y) y
-> Coroutine (SourceFunctor (SinkFunctor d y) x) m ()
forall (m :: * -> *) x y.
Transducer m x y
-> forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
   OpenTransducer m a1 a2 d x y ()
transduce Transducer m x y
t2 Source m a' x
source' Sink m (SinkFunctor d y) y
buffer)
                                              Source m d x
source)
                                Source m (SourceFunctor d y) y -> Coroutine (SourceFunctor d y) m y
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, Monoid x, AncestorFunctor a d) =>
Source m a x -> Coroutine d m x
getAll
                             Coroutine d m (((), ()), y)
-> ((((), ()), y) -> Coroutine d m ()) -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \(((), ())
_, y
list)-> Sink m d y -> y -> Coroutine d m y
forall (m :: * -> *) (a :: * -> *) x.
Sink m a x
-> forall (d :: * -> *).
   AncestorFunctor a d =>
   x -> Coroutine d m x
putChunk Sink m d y
sink y
list
                             Coroutine d m y -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
         sequence :: Transducer m x y -> Transducer m x y -> Transducer m x y
sequence Transducer m x y
t1 Transducer m x y
t2 = (forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d y -> Coroutine d m ())
-> Transducer m x y
forall (m :: * -> *) x y.
(Monad m, Monoid x) =>
(forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d y -> Coroutine d m ())
-> Transducer m x y
isolateTransducer ((forall (d :: * -> *).
  Functor d =>
  Source m d x -> Sink m d y -> Coroutine d m ())
 -> Transducer m x y)
-> (forall (d :: * -> *).
    Functor d =>
    Source m d x -> Sink m d y -> Coroutine d m ())
-> Transducer m x y
forall a b. (a -> b) -> a -> b
$ \Source m d x
source Sink m d y
sink->
                          PairBinder m
-> (forall (a' :: * -> *).
    OpenConsumer m a' (SourceFunctor (SinkFunctor d x) x) x ())
-> (forall (a' :: * -> *).
    OpenConsumer m a' (SourceFunctor d x) x x)
-> Source m d x
-> Coroutine d m ((), x)
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x r1 r2.
Monad m =>
PairBinder m
-> (forall (a' :: * -> *).
    OpenConsumer m a' (SourceFunctor (SinkFunctor d x) x) x r1)
-> (forall (a' :: * -> *).
    OpenConsumer m a' (SourceFunctor d x) x r2)
-> OpenConsumer m a d x (r1, r2)
teeConsumers PairBinder m
forall (m :: * -> *). Monad m => PairBinder m
sequentialBinder ((Source m a' x
 -> Sink m d y
 -> Coroutine (SourceFunctor (SinkFunctor d x) x) m ())
-> Sink m d y
-> Source m a' x
-> Coroutine (SourceFunctor (SinkFunctor d x) x) m ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip (Transducer m x y
-> forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
   (AncestorFunctor a1 d, AncestorFunctor a2 d, Monoid x, Monoid y) =>
   Source m a1 x -> Sink m a2 y -> Coroutine d m ()
forall (m :: * -> *) x y.
Transducer m x y
-> forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
   OpenTransducer m a1 a2 d x y ()
transduce Transducer m x y
t1) Sink m d y
sink) forall (a' :: * -> *). OpenConsumer m a' (SourceFunctor d x) x x
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, Monoid x, AncestorFunctor a d) =>
Source m a x -> Coroutine d m x
getAll Source m d x
source
                          Coroutine d m ((), x)
-> (((), x) -> Coroutine d m ()) -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \(()
_, x
list)-> (Sink m (SinkFunctor d x) x -> Coroutine (SinkFunctor d x) m x)
-> (Source m (SourceFunctor d x) x
    -> Coroutine (SourceFunctor d x) m ())
-> Coroutine d m (x, ())
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
(Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2) -> Coroutine a m (r1, r2)
pipe ((Sink m (SinkFunctor d x) x
 -> x -> Coroutine (SinkFunctor d x) m x)
-> x
-> Sink m (SinkFunctor d x) x
-> Coroutine (SinkFunctor d x) m x
forall a b c. (a -> b -> c) -> b -> a -> c
flip Sink m (SinkFunctor d x) x -> x -> Coroutine (SinkFunctor d x) m x
forall (m :: * -> *) (a :: * -> *) x.
Sink m a x
-> forall (d :: * -> *).
   AncestorFunctor a d =>
   x -> Coroutine d m x
putChunk x
list) (\Source m (SourceFunctor d x) x
source'-> Transducer m x y
-> Source m (SourceFunctor d x) x
-> Sink m d y
-> Coroutine (SourceFunctor d x) m ()
forall (m :: * -> *) x y.
Transducer m x y
-> forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
   OpenTransducer m a1 a2 d x y ()
transduce Transducer m x y
t2 Source m (SourceFunctor d x) x
source' Sink m d y
sink)
                          Coroutine d m (x, ()) -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

instance forall m r1 r2. Monad m =>
   JoinableComponentPair (PerformerType r1) (PerformerType r2) (PerformerType r2) m () ()
                         (Performer m r1) (Performer m r2) (Performer m r2)
   where join :: PairBinder m -> Performer m r1 -> Performer m r2 -> Performer m r2
join PairBinder m
binder Performer m r1
p1 Performer m r2
p2 = m r2 -> Performer m r2
forall (m :: * -> *) r. m r -> Performer m r
Performer (m r2 -> Performer m r2) -> m r2 -> Performer m r2
forall a b. (a -> b) -> a -> b
$ (r1 -> r2 -> m r2) -> m r1 -> m r2 -> m r2
PairBinder m
binder ((r2 -> m r2) -> r1 -> r2 -> m r2
forall a b. a -> b -> a
const r2 -> m r2
forall (m :: * -> *) a. Monad m => a -> m a
return) (Performer m r1 -> m r1
forall (m :: * -> *) r. Performer m r -> m r
perform Performer m r1
p1) (Performer m r2 -> m r2
forall (m :: * -> *) r. Performer m r -> m r
perform Performer m r2
p2)
         sequence :: Performer m r1 -> Performer m r2 -> Performer m r2
sequence Performer m r1
p1 Performer m r2
p2 = m r2 -> Performer m r2
forall (m :: * -> *) r. m r -> Performer m r
Performer (m r2 -> Performer m r2) -> m r2 -> Performer m r2
forall a b. (a -> b) -> a -> b
$ Performer m r1 -> m r1
forall (m :: * -> *) r. Performer m r -> m r
perform Performer m r1
p1 m r1 -> m r2 -> m r2
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Performer m r2 -> m r2
forall (m :: * -> *) r. Performer m r -> m r
perform Performer m r2
p2

instance forall m x r1 r2. Monad m =>
   JoinableComponentPair (PerformerType r1) (ProducerType r2) (ProducerType r2) m () x
                         (Performer m r1) (Producer m x r2) (Producer m x r2)
   where join :: PairBinder m
-> Performer m r1 -> Producer m x r2 -> Producer m x r2
join PairBinder m
binder Performer m r1
pe Producer m x r2
pr = (forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r2)
-> Producer m x r2
forall (m :: * -> *) x r.
(forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r)
-> Producer m x r
Producer ((forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r2)
 -> Producer m x r2)
-> (forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r2)
-> Producer m x r2
forall a b. (a -> b) -> a -> b
$ \Sink m a x
sink-> PairBinder m
-> (r1 -> r2 -> Coroutine d m r2)
-> Coroutine d m r1
-> Coroutine d m r2
-> Coroutine d m r2
forall (s :: * -> *) (m :: * -> *).
(Functor s, Monad m) =>
PairBinder m -> PairBinder (Coroutine s m)
liftBinder PairBinder m
binder ((r2 -> Coroutine d m r2) -> r1 -> r2 -> Coroutine d m r2
forall a b. a -> b -> a
const r2 -> Coroutine d m r2
forall (m :: * -> *) a. Monad m => a -> m a
return) (m r1 -> Coroutine d m r1
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Performer m r1 -> m r1
forall (m :: * -> *) r. Performer m r -> m r
perform Performer m r1
pe)) (Producer m x r2 -> Sink m a x -> Coroutine d m r2
forall (m :: * -> *) x r.
Producer m x r
-> forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r
produce Producer m x r2
pr Sink m a x
sink)
         sequence :: Performer m r1 -> Producer m x r2 -> Producer m x r2
sequence Performer m r1
pe Producer m x r2
pr = (forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r2)
-> Producer m x r2
forall (m :: * -> *) x r.
(forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r)
-> Producer m x r
Producer ((forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r2)
 -> Producer m x r2)
-> (forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r2)
-> Producer m x r2
forall a b. (a -> b) -> a -> b
$ \Sink m a x
sink-> m r1 -> Coroutine d m r1
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Performer m r1 -> m r1
forall (m :: * -> *) r. Performer m r -> m r
perform Performer m r1
pe) Coroutine d m r1 -> Coroutine d m r2 -> Coroutine d m r2
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Producer m x r2 -> Sink m a x -> Coroutine d m r2
forall (m :: * -> *) x r.
Producer m x r
-> forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r
produce Producer m x r2
pr Sink m a x
sink

instance forall m x r1 r2. Monad m =>
   JoinableComponentPair (ProducerType r1) (PerformerType r2) (ProducerType r2) m () x
                         (Producer m x r1) (Performer m r2) (Producer m x r2)
   where join :: PairBinder m
-> Producer m x r1 -> Performer m r2 -> Producer m x r2
join PairBinder m
binder Producer m x r1
pr Performer m r2
pe = (forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r2)
-> Producer m x r2
forall (m :: * -> *) x r.
(forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r)
-> Producer m x r
Producer ((forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r2)
 -> Producer m x r2)
-> (forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r2)
-> Producer m x r2
forall a b. (a -> b) -> a -> b
$ \Sink m a x
sink-> PairBinder m
-> (r1 -> r2 -> Coroutine d m r2)
-> Coroutine d m r1
-> Coroutine d m r2
-> Coroutine d m r2
forall (s :: * -> *) (m :: * -> *).
(Functor s, Monad m) =>
PairBinder m -> PairBinder (Coroutine s m)
liftBinder PairBinder m
binder ((r2 -> Coroutine d m r2) -> r1 -> r2 -> Coroutine d m r2
forall a b. a -> b -> a
const r2 -> Coroutine d m r2
forall (m :: * -> *) a. Monad m => a -> m a
return) (Producer m x r1 -> Sink m a x -> Coroutine d m r1
forall (m :: * -> *) x r.
Producer m x r
-> forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r
produce Producer m x r1
pr Sink m a x
sink) (m r2 -> Coroutine d m r2
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Performer m r2 -> m r2
forall (m :: * -> *) r. Performer m r -> m r
perform Performer m r2
pe))
         sequence :: Producer m x r1 -> Performer m r2 -> Producer m x r2
sequence Producer m x r1
pr Performer m r2
pe = (forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r2)
-> Producer m x r2
forall (m :: * -> *) x r.
(forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r)
-> Producer m x r
Producer ((forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r2)
 -> Producer m x r2)
-> (forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r2)
-> Producer m x r2
forall a b. (a -> b) -> a -> b
$ \Sink m a x
sink-> Producer m x r1 -> Sink m a x -> Coroutine d m r1
forall (m :: * -> *) x r.
Producer m x r
-> forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r
produce Producer m x r1
pr Sink m a x
sink Coroutine d m r1 -> Coroutine d m r2 -> Coroutine d m r2
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> m r2 -> Coroutine d m r2
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Performer m r2 -> m r2
forall (m :: * -> *) r. Performer m r -> m r
perform Performer m r2
pe)

instance forall m x r1 r2. Monad m =>
   JoinableComponentPair (PerformerType r1) (ConsumerType r2) (ConsumerType r2) m x ()
                         (Performer m r1) (Consumer m x r2) (Consumer m x r2)
   where join :: PairBinder m
-> Performer m r1 -> Consumer m x r2 -> Consumer m x r2
join PairBinder m
binder Performer m r1
p Consumer m x r2
c = (forall (a :: * -> *) (d :: * -> *). OpenConsumer m a d x r2)
-> Consumer m x r2
forall (m :: * -> *) x r.
(forall (a :: * -> *) (d :: * -> *).
 (AncestorFunctor a d, Monoid x) =>
 Source m a x -> Coroutine d m r)
-> Consumer m x r
Consumer ((forall (a :: * -> *) (d :: * -> *). OpenConsumer m a d x r2)
 -> Consumer m x r2)
-> (forall (a :: * -> *) (d :: * -> *). OpenConsumer m a d x r2)
-> Consumer m x r2
forall a b. (a -> b) -> a -> b
$ \Source m a x
source-> PairBinder m
-> (r1 -> r2 -> Coroutine d m r2)
-> Coroutine d m r1
-> Coroutine d m r2
-> Coroutine d m r2
forall (s :: * -> *) (m :: * -> *).
(Functor s, Monad m) =>
PairBinder m -> PairBinder (Coroutine s m)
liftBinder PairBinder m
binder ((r2 -> Coroutine d m r2) -> r1 -> r2 -> Coroutine d m r2
forall a b. a -> b -> a
const r2 -> Coroutine d m r2
forall (m :: * -> *) a. Monad m => a -> m a
return) (m r1 -> Coroutine d m r1
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Performer m r1 -> m r1
forall (m :: * -> *) r. Performer m r -> m r
perform Performer m r1
p)) (Consumer m x r2 -> Source m a x -> Coroutine d m r2
forall (m :: * -> *) x r.
Consumer m x r
-> forall (a :: * -> *) (d :: * -> *).
   (AncestorFunctor a d, Monoid x) =>
   Source m a x -> Coroutine d m r
consume Consumer m x r2
c Source m a x
source)
         sequence :: Performer m r1 -> Consumer m x r2 -> Consumer m x r2
sequence Performer m r1
p Consumer m x r2
c = (forall (a :: * -> *) (d :: * -> *). OpenConsumer m a d x r2)
-> Consumer m x r2
forall (m :: * -> *) x r.
(forall (a :: * -> *) (d :: * -> *).
 (AncestorFunctor a d, Monoid x) =>
 Source m a x -> Coroutine d m r)
-> Consumer m x r
Consumer ((forall (a :: * -> *) (d :: * -> *). OpenConsumer m a d x r2)
 -> Consumer m x r2)
-> (forall (a :: * -> *) (d :: * -> *). OpenConsumer m a d x r2)
-> Consumer m x r2
forall a b. (a -> b) -> a -> b
$ \Source m a x
source-> m r1 -> Coroutine d m r1
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Performer m r1 -> m r1
forall (m :: * -> *) r. Performer m r -> m r
perform Performer m r1
p) Coroutine d m r1 -> Coroutine d m r2 -> Coroutine d m r2
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Consumer m x r2 -> Source m a x -> Coroutine d m r2
forall (m :: * -> *) x r.
Consumer m x r
-> forall (a :: * -> *) (d :: * -> *).
   (AncestorFunctor a d, Monoid x) =>
   Source m a x -> Coroutine d m r
consume Consumer m x r2
c Source m a x
source

instance forall m x r1 r2. Monad m =>
   JoinableComponentPair (ConsumerType r1) (PerformerType r2) (ConsumerType r2) m x ()
                         (Consumer m x r1) (Performer m r2) (Consumer m x r2)
   where join :: PairBinder m
-> Consumer m x r1 -> Performer m r2 -> Consumer m x r2
join PairBinder m
binder Consumer m x r1
c Performer m r2
p = (forall (a :: * -> *) (d :: * -> *). OpenConsumer m a d x r2)
-> Consumer m x r2
forall (m :: * -> *) x r.
(forall (a :: * -> *) (d :: * -> *).
 (AncestorFunctor a d, Monoid x) =>
 Source m a x -> Coroutine d m r)
-> Consumer m x r
Consumer ((forall (a :: * -> *) (d :: * -> *). OpenConsumer m a d x r2)
 -> Consumer m x r2)
-> (forall (a :: * -> *) (d :: * -> *). OpenConsumer m a d x r2)
-> Consumer m x r2
forall a b. (a -> b) -> a -> b
$ \Source m a x
source-> PairBinder m
-> (r1 -> r2 -> Coroutine d m r2)
-> Coroutine d m r1
-> Coroutine d m r2
-> Coroutine d m r2
forall (s :: * -> *) (m :: * -> *).
(Functor s, Monad m) =>
PairBinder m -> PairBinder (Coroutine s m)
liftBinder PairBinder m
binder ((r2 -> Coroutine d m r2) -> r1 -> r2 -> Coroutine d m r2
forall a b. a -> b -> a
const r2 -> Coroutine d m r2
forall (m :: * -> *) a. Monad m => a -> m a
return) (Consumer m x r1 -> Source m a x -> Coroutine d m r1
forall (m :: * -> *) x r.
Consumer m x r
-> forall (a :: * -> *) (d :: * -> *).
   (AncestorFunctor a d, Monoid x) =>
   Source m a x -> Coroutine d m r
consume Consumer m x r1
c Source m a x
source) (m r2 -> Coroutine d m r2
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Performer m r2 -> m r2
forall (m :: * -> *) r. Performer m r -> m r
perform Performer m r2
p))
         sequence :: Consumer m x r1 -> Performer m r2 -> Consumer m x r2
sequence Consumer m x r1
c Performer m r2
p = (forall (a :: * -> *) (d :: * -> *). OpenConsumer m a d x r2)
-> Consumer m x r2
forall (m :: * -> *) x r.
(forall (a :: * -> *) (d :: * -> *).
 (AncestorFunctor a d, Monoid x) =>
 Source m a x -> Coroutine d m r)
-> Consumer m x r
Consumer ((forall (a :: * -> *) (d :: * -> *). OpenConsumer m a d x r2)
 -> Consumer m x r2)
-> (forall (a :: * -> *) (d :: * -> *). OpenConsumer m a d x r2)
-> Consumer m x r2
forall a b. (a -> b) -> a -> b
$ \Source m a x
source-> Consumer m x r1 -> Source m a x -> Coroutine d m r1
forall (m :: * -> *) x r.
Consumer m x r
-> forall (a :: * -> *) (d :: * -> *).
   (AncestorFunctor a d, Monoid x) =>
   Source m a x -> Coroutine d m r
consume Consumer m x r1
c Source m a x
source Coroutine d m r1 -> Coroutine d m r2 -> Coroutine d m r2
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> m r2 -> Coroutine d m r2
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Performer m r2 -> m r2
forall (m :: * -> *) r. Performer m r -> m r
perform Performer m r2
p)

instance forall m x y r. Monad m =>
   JoinableComponentPair (PerformerType r) TransducerType TransducerType m x y
                         (Performer m r) (Transducer m x y) (Transducer m x y)
   where join :: PairBinder m
-> Performer m r -> Transducer m x y -> Transducer m x y
join PairBinder m
binder Performer m r
p Transducer m x y
t = 
            (forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
 OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
forall (m :: * -> *) x y.
(forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
 OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
Transducer ((forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
  OpenTransducer m a1 a2 d x y ())
 -> Transducer m x y)
-> (forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
    OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
forall a b. (a -> b) -> a -> b
$ \ Source m a1 x
source Sink m a2 y
sink -> 
            PairBinder m
-> (r -> () -> Coroutine d m ())
-> Coroutine d m r
-> Coroutine d m ()
-> Coroutine d m ()
forall (s :: * -> *) (m :: * -> *).
(Functor s, Monad m) =>
PairBinder m -> PairBinder (Coroutine s m)
liftBinder PairBinder m
binder ((() -> Coroutine d m ()) -> r -> () -> Coroutine d m ()
forall a b. a -> b -> a
const () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return) (m r -> Coroutine d m r
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Performer m r -> m r
forall (m :: * -> *) r. Performer m r -> m r
perform Performer m r
p)) (Transducer m x y
-> Source m a1 x -> Sink m a2 y -> Coroutine d m ()
forall (m :: * -> *) x y.
Transducer m x y
-> forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
   OpenTransducer m a1 a2 d x y ()
transduce Transducer m x y
t Source m a1 x
source Sink m a2 y
sink)
         sequence :: Performer m r -> Transducer m x y -> Transducer m x y
sequence Performer m r
p Transducer m x y
t = (forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
 OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
forall (m :: * -> *) x y.
(forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
 OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
Transducer ((forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
  OpenTransducer m a1 a2 d x y ())
 -> Transducer m x y)
-> (forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
    OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
forall a b. (a -> b) -> a -> b
$ \ Source m a1 x
source Sink m a2 y
sink -> m r -> Coroutine d m r
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Performer m r -> m r
forall (m :: * -> *) r. Performer m r -> m r
perform Performer m r
p) Coroutine d m r -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Transducer m x y
-> Source m a1 x -> Sink m a2 y -> Coroutine d m ()
forall (m :: * -> *) x y.
Transducer m x y
-> forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
   OpenTransducer m a1 a2 d x y ()
transduce Transducer m x y
t Source m a1 x
source Sink m a2 y
sink

instance forall m x y r. Monad m
   => JoinableComponentPair TransducerType (PerformerType r) TransducerType m x y
                            (Transducer m x y) (Performer m r) (Transducer m x y)
   where join :: PairBinder m
-> Transducer m x y -> Performer m r -> Transducer m x y
join PairBinder m
binder Transducer m x y
t Performer m r
p = 
            (forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
 OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
forall (m :: * -> *) x y.
(forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
 OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
Transducer ((forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
  OpenTransducer m a1 a2 d x y ())
 -> Transducer m x y)
-> (forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
    OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
forall a b. (a -> b) -> a -> b
$ \ Source m a1 x
source Sink m a2 y
sink -> 
            PairBinder m
-> (() -> r -> Coroutine d m ())
-> Coroutine d m ()
-> Coroutine d m r
-> Coroutine d m ()
forall (s :: * -> *) (m :: * -> *).
(Functor s, Monad m) =>
PairBinder m -> PairBinder (Coroutine s m)
liftBinder PairBinder m
binder (Coroutine d m () -> r -> Coroutine d m ()
forall a b. a -> b -> a
const (Coroutine d m () -> r -> Coroutine d m ())
-> (() -> Coroutine d m ()) -> () -> r -> Coroutine d m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return) (Transducer m x y
-> Source m a1 x -> Sink m a2 y -> Coroutine d m ()
forall (m :: * -> *) x y.
Transducer m x y
-> forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
   OpenTransducer m a1 a2 d x y ()
transduce Transducer m x y
t Source m a1 x
source Sink m a2 y
sink) (m r -> Coroutine d m r
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Performer m r -> m r
forall (m :: * -> *) r. Performer m r -> m r
perform Performer m r
p))
         sequence :: Transducer m x y -> Performer m r -> Transducer m x y
sequence Transducer m x y
t Performer m r
p = (forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
 OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
forall (m :: * -> *) x y.
(forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
 OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
Transducer ((forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
  OpenTransducer m a1 a2 d x y ())
 -> Transducer m x y)
-> (forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
    OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
forall a b. (a -> b) -> a -> b
$ \ Source m a1 x
source Sink m a2 y
sink -> do ()
result <- Transducer m x y
-> Source m a1 x -> Sink m a2 y -> Coroutine d m ()
forall (m :: * -> *) x y.
Transducer m x y
-> forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
   OpenTransducer m a1 a2 d x y ()
transduce Transducer m x y
t Source m a1 x
source Sink m a2 y
sink
                                                         r
_ <- m r -> Coroutine d m r
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Performer m r -> m r
forall (m :: * -> *) r. Performer m r -> m r
perform Performer m r
p)
                                                         () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
result

instance forall m x y. (Monad m, Monoid x, Monoid y) =>
   JoinableComponentPair (ProducerType ()) TransducerType TransducerType m x y
                         (Producer m y ()) (Transducer m x y) (Transducer m x y)
   where join :: PairBinder m
-> Producer m y () -> Transducer m x y -> Transducer m x y
join PairBinder m
binder Producer m y ()
p Transducer m x y
t = 
            (forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d y -> Coroutine d m ())
-> Transducer m x y
forall (m :: * -> *) x y.
(Monad m, Monoid x) =>
(forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d y -> Coroutine d m ())
-> Transducer m x y
isolateTransducer ((forall (d :: * -> *).
  Functor d =>
  Source m d x -> Sink m d y -> Coroutine d m ())
 -> Transducer m x y)
-> (forall (d :: * -> *).
    Functor d =>
    Source m d x -> Sink m d y -> Coroutine d m ())
-> Transducer m x y
forall a b. (a -> b) -> a -> b
$ \Source m d x
source Sink m d y
sink->
            (Sink m (SinkFunctor d y) y -> Coroutine (SinkFunctor d y) m ())
-> (Source m (SourceFunctor d y) y
    -> Coroutine (SourceFunctor d y) m y)
-> Coroutine d m ((), y)
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
(Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2) -> Coroutine a m (r1, r2)
pipe (\Sink m (SinkFunctor d y) y
buffer-> PairBinder m
-> (() -> () -> Coroutine (SinkFunctor d y) m ())
-> Coroutine (SinkFunctor d y) m ()
-> Coroutine (SinkFunctor d y) m ()
-> Coroutine (SinkFunctor d y) m ()
forall (s :: * -> *) (m :: * -> *).
(Functor s, Monad m) =>
PairBinder m -> PairBinder (Coroutine s m)
liftBinder PairBinder m
binder ((() -> Coroutine (SinkFunctor d y) m ())
-> () -> () -> Coroutine (SinkFunctor d y) m ()
forall a b. a -> b -> a
const () -> Coroutine (SinkFunctor d y) m ()
forall (m :: * -> *) a. Monad m => a -> m a
return) (Producer m y () -> Sink m d y -> Coroutine (SinkFunctor d y) m ()
forall (m :: * -> *) x r.
Producer m x r
-> forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r
produce Producer m y ()
p Sink m d y
sink) (Transducer m x y
-> Source m d x
-> Sink m (SinkFunctor d y) y
-> Coroutine (SinkFunctor d y) m ()
forall (m :: * -> *) x y.
Transducer m x y
-> forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
   OpenTransducer m a1 a2 d x y ()
transduce Transducer m x y
t Source m d x
source Sink m (SinkFunctor d y) y
buffer)) Source m (SourceFunctor d y) y -> Coroutine (SourceFunctor d y) m y
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, Monoid x, AncestorFunctor a d) =>
Source m a x -> Coroutine d m x
getAll
            Coroutine d m ((), y)
-> (((), y) -> Coroutine d m ()) -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \(()
_, y
out)-> Sink m d y -> y -> Coroutine d m y
forall (m :: * -> *) (a :: * -> *) x.
Sink m a x
-> forall (d :: * -> *).
   AncestorFunctor a d =>
   x -> Coroutine d m x
putChunk Sink m d y
sink y
out Coroutine d m y -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
         sequence :: Producer m y () -> Transducer m x y -> Transducer m x y
sequence Producer m y ()
p Transducer m x y
t = (forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
 OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
forall (m :: * -> *) x y.
(forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
 OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
Transducer ((forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
  OpenTransducer m a1 a2 d x y ())
 -> Transducer m x y)
-> (forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
    OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
forall a b. (a -> b) -> a -> b
$ \ Source m a1 x
source Sink m a2 y
sink -> Producer m y () -> Sink m a2 y -> Coroutine d m ()
forall (m :: * -> *) x r.
Producer m x r
-> forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r
produce Producer m y ()
p Sink m a2 y
sink Coroutine d m () -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Transducer m x y
-> Source m a1 x -> Sink m a2 y -> Coroutine d m ()
forall (m :: * -> *) x y.
Transducer m x y
-> forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
   OpenTransducer m a1 a2 d x y ()
transduce Transducer m x y
t Source m a1 x
source Sink m a2 y
sink

instance forall m x y. (Monad m, Monoid x, Monoid y) =>
   JoinableComponentPair TransducerType (ProducerType ()) TransducerType m x y
                         (Transducer m x y) (Producer m y ()) (Transducer m x y)
   where join :: PairBinder m
-> Transducer m x y -> Producer m y () -> Transducer m x y
join PairBinder m
binder Transducer m x y
t Producer m y ()
p =
            (forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d y -> Coroutine d m ())
-> Transducer m x y
forall (m :: * -> *) x y.
(Monad m, Monoid x) =>
(forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d y -> Coroutine d m ())
-> Transducer m x y
isolateTransducer ((forall (d :: * -> *).
  Functor d =>
  Source m d x -> Sink m d y -> Coroutine d m ())
 -> Transducer m x y)
-> (forall (d :: * -> *).
    Functor d =>
    Source m d x -> Sink m d y -> Coroutine d m ())
-> Transducer m x y
forall a b. (a -> b) -> a -> b
$ \Source m d x
source Sink m d y
sink->
            (Sink m (SinkFunctor d y) y -> Coroutine (SinkFunctor d y) m ())
-> (Source m (SourceFunctor d y) y
    -> Coroutine (SourceFunctor d y) m y)
-> Coroutine d m ((), y)
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
(Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2) -> Coroutine a m (r1, r2)
pipe (\Sink m (SinkFunctor d y) y
buffer-> PairBinder m
-> (() -> () -> Coroutine (SinkFunctor d y) m ())
-> Coroutine (SinkFunctor d y) m ()
-> Coroutine (SinkFunctor d y) m ()
-> Coroutine (SinkFunctor d y) m ()
forall (s :: * -> *) (m :: * -> *).
(Functor s, Monad m) =>
PairBinder m -> PairBinder (Coroutine s m)
liftBinder PairBinder m
binder (Coroutine (SinkFunctor d y) m ()
-> () -> Coroutine (SinkFunctor d y) m ()
forall a b. a -> b -> a
const (Coroutine (SinkFunctor d y) m ()
 -> () -> Coroutine (SinkFunctor d y) m ())
-> (() -> Coroutine (SinkFunctor d y) m ())
-> ()
-> ()
-> Coroutine (SinkFunctor d y) m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. () -> Coroutine (SinkFunctor d y) m ()
forall (m :: * -> *) a. Monad m => a -> m a
return) (Transducer m x y
-> Source m d x -> Sink m d y -> Coroutine (SinkFunctor d y) m ()
forall (m :: * -> *) x y.
Transducer m x y
-> forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
   OpenTransducer m a1 a2 d x y ()
transduce Transducer m x y
t Source m d x
source Sink m d y
sink) (Producer m y ()
-> Sink m (SinkFunctor d y) y -> Coroutine (SinkFunctor d y) m ()
forall (m :: * -> *) x r.
Producer m x r
-> forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r
produce Producer m y ()
p Sink m (SinkFunctor d y) y
buffer)) Source m (SourceFunctor d y) y -> Coroutine (SourceFunctor d y) m y
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, Monoid x, AncestorFunctor a d) =>
Source m a x -> Coroutine d m x
getAll
            Coroutine d m ((), y)
-> (((), y) -> Coroutine d m ()) -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \(()
_, y
out)-> Sink m d y -> y -> Coroutine d m y
forall (m :: * -> *) (a :: * -> *) x.
Sink m a x
-> forall (d :: * -> *).
   AncestorFunctor a d =>
   x -> Coroutine d m x
putChunk Sink m d y
sink y
out Coroutine d m y -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
         sequence :: Transducer m x y -> Producer m y () -> Transducer m x y
sequence Transducer m x y
t Producer m y ()
p = (forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
 OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
forall (m :: * -> *) x y.
(forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
 OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
Transducer ((forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
  OpenTransducer m a1 a2 d x y ())
 -> Transducer m x y)
-> (forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
    OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
forall a b. (a -> b) -> a -> b
$ \ Source m a1 x
source Sink m a2 y
sink -> do ()
result <- Transducer m x y
-> Source m a1 x -> Sink m a2 y -> Coroutine d m ()
forall (m :: * -> *) x y.
Transducer m x y
-> forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
   OpenTransducer m a1 a2 d x y ()
transduce Transducer m x y
t Source m a1 x
source Sink m a2 y
sink
                                                         Producer m y () -> Sink m a2 y -> Coroutine d m ()
forall (m :: * -> *) x r.
Producer m x r
-> forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r
produce Producer m y ()
p Sink m a2 y
sink
                                                         () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
result

instance forall m x y. (Monad m, Monoid x, Monoid y) =>
   JoinableComponentPair (ConsumerType ()) TransducerType TransducerType m x y
                         (Consumer m x ()) (Transducer m x y) (Transducer m x y)
   where join :: PairBinder m
-> Consumer m x () -> Transducer m x y -> Transducer m x y
join PairBinder m
binder Consumer m x ()
c Transducer m x y
t = 
            (forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d y -> Coroutine d m ())
-> Transducer m x y
forall (m :: * -> *) x y.
(Monad m, Monoid x) =>
(forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d y -> Coroutine d m ())
-> Transducer m x y
isolateTransducer ((forall (d :: * -> *).
  Functor d =>
  Source m d x -> Sink m d y -> Coroutine d m ())
 -> Transducer m x y)
-> (forall (d :: * -> *).
    Functor d =>
    Source m d x -> Sink m d y -> Coroutine d m ())
-> Transducer m x y
forall a b. (a -> b) -> a -> b
$ \Source m d x
source Sink m d y
sink->
            PairBinder m
-> (forall (a' :: * -> *).
    OpenConsumer m a' (SourceFunctor (SinkFunctor d x) x) x ())
-> (forall (a' :: * -> *).
    OpenConsumer m a' (SourceFunctor d x) x ())
-> Source m d x
-> Coroutine d m ((), ())
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x r1 r2.
Monad m =>
PairBinder m
-> (forall (a' :: * -> *).
    OpenConsumer m a' (SourceFunctor (SinkFunctor d x) x) x r1)
-> (forall (a' :: * -> *).
    OpenConsumer m a' (SourceFunctor d x) x r2)
-> OpenConsumer m a d x (r1, r2)
teeConsumers PairBinder m
binder (Consumer m x ()
-> forall (a :: * -> *) (d :: * -> *).
   (AncestorFunctor a d, Monoid x) =>
   Source m a x -> Coroutine d m ()
forall (m :: * -> *) x r.
Consumer m x r
-> forall (a :: * -> *) (d :: * -> *).
   (AncestorFunctor a d, Monoid x) =>
   Source m a x -> Coroutine d m r
consume Consumer m x ()
c) (\Source m a' x
source'-> Transducer m x y
-> Source m a' x
-> Sink m d y
-> Coroutine (SourceFunctor d x) m ()
forall (m :: * -> *) x y.
Transducer m x y
-> forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
   OpenTransducer m a1 a2 d x y ()
transduce Transducer m x y
t Source m a' x
source' Sink m d y
sink) Source m d x
source
            Coroutine d m ((), ()) -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
         sequence :: Consumer m x () -> Transducer m x y -> Transducer m x y
sequence Consumer m x ()
c Transducer m x y
t = (forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d y -> Coroutine d m ())
-> Transducer m x y
forall (m :: * -> *) x y.
(Monad m, Monoid x) =>
(forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d y -> Coroutine d m ())
-> Transducer m x y
isolateTransducer ((forall (d :: * -> *).
  Functor d =>
  Source m d x -> Sink m d y -> Coroutine d m ())
 -> Transducer m x y)
-> (forall (d :: * -> *).
    Functor d =>
    Source m d x -> Sink m d y -> Coroutine d m ())
-> Transducer m x y
forall a b. (a -> b) -> a -> b
$ \Source m d x
source Sink m d y
sink->
                        PairBinder m
-> (forall (a' :: * -> *).
    OpenConsumer m a' (SourceFunctor (SinkFunctor d x) x) x ())
-> (forall (a' :: * -> *).
    OpenConsumer m a' (SourceFunctor d x) x x)
-> Source m d x
-> Coroutine d m ((), x)
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x r1 r2.
Monad m =>
PairBinder m
-> (forall (a' :: * -> *).
    OpenConsumer m a' (SourceFunctor (SinkFunctor d x) x) x r1)
-> (forall (a' :: * -> *).
    OpenConsumer m a' (SourceFunctor d x) x r2)
-> OpenConsumer m a d x (r1, r2)
teeConsumers PairBinder m
forall (m :: * -> *). Monad m => PairBinder m
sequentialBinder (Consumer m x ()
-> forall (a :: * -> *) (d :: * -> *).
   (AncestorFunctor a d, Monoid x) =>
   Source m a x -> Coroutine d m ()
forall (m :: * -> *) x r.
Consumer m x r
-> forall (a :: * -> *) (d :: * -> *).
   (AncestorFunctor a d, Monoid x) =>
   Source m a x -> Coroutine d m r
consume Consumer m x ()
c) forall (a' :: * -> *). OpenConsumer m a' (SourceFunctor d x) x x
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, Monoid x, AncestorFunctor a d) =>
Source m a x -> Coroutine d m x
getAll Source m d x
source
                        Coroutine d m ((), x)
-> (((), x) -> Coroutine d m ()) -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \(()
_, x
list)-> (Sink m (SinkFunctor d x) x -> Coroutine (SinkFunctor d x) m x)
-> (Source m (SourceFunctor d x) x
    -> Coroutine (SourceFunctor d x) m ())
-> Coroutine d m (x, ())
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
(Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2) -> Coroutine a m (r1, r2)
pipe ((Sink m (SinkFunctor d x) x
 -> x -> Coroutine (SinkFunctor d x) m x)
-> x
-> Sink m (SinkFunctor d x) x
-> Coroutine (SinkFunctor d x) m x
forall a b c. (a -> b -> c) -> b -> a -> c
flip Sink m (SinkFunctor d x) x -> x -> Coroutine (SinkFunctor d x) m x
forall (m :: * -> *) (a :: * -> *) x.
Sink m a x
-> forall (d :: * -> *).
   AncestorFunctor a d =>
   x -> Coroutine d m x
putChunk x
list) (\Source m (SourceFunctor d x) x
source'-> Transducer m x y
-> Source m (SourceFunctor d x) x
-> Sink m d y
-> Coroutine (SourceFunctor d x) m ()
forall (m :: * -> *) x y.
Transducer m x y
-> forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
   OpenTransducer m a1 a2 d x y ()
transduce Transducer m x y
t Source m (SourceFunctor d x) x
source' Sink m d y
sink)
                        Coroutine d m (x, ()) -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

instance forall m x y. (Monad m, Monoid x, Monoid y) =>
   JoinableComponentPair TransducerType (ConsumerType ()) TransducerType m x y
                         (Transducer m x y) (Consumer m x ()) (Transducer m x y)
   where join :: PairBinder m
-> Transducer m x y -> Consumer m x () -> Transducer m x y
join PairBinder m
binder Transducer m x y
t Consumer m x ()
c = PairBinder m
-> Consumer m x () -> Transducer m x y -> Transducer m x y
forall t1 t2 t3 (m :: * -> *) x y c1 c2 c3.
JoinableComponentPair t1 t2 t3 m x y c1 c2 c3 =>
PairBinder m -> c1 -> c2 -> c3
join PairBinder m
binder Consumer m x ()
c Transducer m x y
t
         sequence :: Transducer m x y -> Consumer m x () -> Transducer m x y
sequence Transducer m x y
t Consumer m x ()
c = (forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d y -> Coroutine d m ())
-> Transducer m x y
forall (m :: * -> *) x y.
(Monad m, Monoid x) =>
(forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d y -> Coroutine d m ())
-> Transducer m x y
isolateTransducer ((forall (d :: * -> *).
  Functor d =>
  Source m d x -> Sink m d y -> Coroutine d m ())
 -> Transducer m x y)
-> (forall (d :: * -> *).
    Functor d =>
    Source m d x -> Sink m d y -> Coroutine d m ())
-> Transducer m x y
forall a b. (a -> b) -> a -> b
$ \Source m d x
source Sink m d y
sink->
                        PairBinder m
-> (forall (a' :: * -> *).
    OpenConsumer m a' (SourceFunctor (SinkFunctor d x) x) x ())
-> (forall (a' :: * -> *).
    OpenConsumer m a' (SourceFunctor d x) x x)
-> Source m d x
-> Coroutine d m ((), x)
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x r1 r2.
Monad m =>
PairBinder m
-> (forall (a' :: * -> *).
    OpenConsumer m a' (SourceFunctor (SinkFunctor d x) x) x r1)
-> (forall (a' :: * -> *).
    OpenConsumer m a' (SourceFunctor d x) x r2)
-> OpenConsumer m a d x (r1, r2)
teeConsumers PairBinder m
forall (m :: * -> *). Monad m => PairBinder m
sequentialBinder (\Source m a' x
source'-> Transducer m x y
-> Source m a' x
-> Sink m d y
-> Coroutine (SourceFunctor (SinkFunctor d x) x) m ()
forall (m :: * -> *) x y.
Transducer m x y
-> forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
   OpenTransducer m a1 a2 d x y ()
transduce Transducer m x y
t Source m a' x
source' Sink m d y
sink) forall (a' :: * -> *). OpenConsumer m a' (SourceFunctor d x) x x
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, Monoid x, AncestorFunctor a d) =>
Source m a x -> Coroutine d m x
getAll Source m d x
source
                        Coroutine d m ((), x)
-> (((), x) -> Coroutine d m ()) -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \(()
_, x
list)-> (Sink m (SinkFunctor d x) x -> Coroutine (SinkFunctor d x) m x)
-> (Source m (SourceFunctor d x) x
    -> Coroutine (SourceFunctor d x) m ())
-> Coroutine d m (x, ())
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
(Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2) -> Coroutine a m (r1, r2)
pipe ((Sink m (SinkFunctor d x) x
 -> x -> Coroutine (SinkFunctor d x) m x)
-> x
-> Sink m (SinkFunctor d x) x
-> Coroutine (SinkFunctor d x) m x
forall a b c. (a -> b -> c) -> b -> a -> c
flip Sink m (SinkFunctor d x) x -> x -> Coroutine (SinkFunctor d x) m x
forall (m :: * -> *) (a :: * -> *) x.
Sink m a x
-> forall (d :: * -> *).
   AncestorFunctor a d =>
   x -> Coroutine d m x
putChunk x
list) (Consumer m x ()
-> forall (a :: * -> *) (d :: * -> *).
   (AncestorFunctor a d, Monoid x) =>
   Source m a x -> Coroutine d m ()
forall (m :: * -> *) x r.
Consumer m x r
-> forall (a :: * -> *) (d :: * -> *).
   (AncestorFunctor a d, Monoid x) =>
   Source m a x -> Coroutine d m r
consume Consumer m x ()
c)
                        Coroutine d m (x, ()) -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

instance forall m x y. Monad m =>
   JoinableComponentPair (ProducerType ()) (ConsumerType ()) TransducerType m x y
                         (Producer m y ()) (Consumer m x ()) (Transducer m x y)
   where join :: PairBinder m
-> Producer m y () -> Consumer m x () -> Transducer m x y
join PairBinder m
binder Producer m y ()
p Consumer m x ()
c = (forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
 OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
forall (m :: * -> *) x y.
(forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
 OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
Transducer ((forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
  OpenTransducer m a1 a2 d x y ())
 -> Transducer m x y)
-> (forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
    OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
forall a b. (a -> b) -> a -> b
$ 
                           \ Source m a1 x
source Sink m a2 y
sink -> PairBinder m
-> (() -> () -> Coroutine d m ())
-> Coroutine d m ()
-> Coroutine d m ()
-> Coroutine d m ()
forall (s :: * -> *) (m :: * -> *).
(Functor s, Monad m) =>
PairBinder m -> PairBinder (Coroutine s m)
liftBinder PairBinder m
binder (\ ()
_ ()
_ -> () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()) (Producer m y () -> Sink m a2 y -> Coroutine d m ()
forall (m :: * -> *) x r.
Producer m x r
-> forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r
produce Producer m y ()
p Sink m a2 y
sink) (Consumer m x () -> Source m a1 x -> Coroutine d m ()
forall (m :: * -> *) x r.
Consumer m x r
-> forall (a :: * -> *) (d :: * -> *).
   (AncestorFunctor a d, Monoid x) =>
   Source m a x -> Coroutine d m r
consume Consumer m x ()
c Source m a1 x
source)
         sequence :: Producer m y () -> Consumer m x () -> Transducer m x y
sequence Producer m y ()
p Consumer m x ()
c = (forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
 OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
forall (m :: * -> *) x y.
(forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
 OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
Transducer ((forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
  OpenTransducer m a1 a2 d x y ())
 -> Transducer m x y)
-> (forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
    OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
forall a b. (a -> b) -> a -> b
$ \ Source m a1 x
source Sink m a2 y
sink -> Producer m y () -> Sink m a2 y -> Coroutine d m ()
forall (m :: * -> *) x r.
Producer m x r
-> forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r
produce Producer m y ()
p Sink m a2 y
sink Coroutine d m () -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Consumer m x () -> Source m a1 x -> Coroutine d m ()
forall (m :: * -> *) x r.
Consumer m x r
-> forall (a :: * -> *) (d :: * -> *).
   (AncestorFunctor a d, Monoid x) =>
   Source m a x -> Coroutine d m r
consume Consumer m x ()
c Source m a1 x
source

instance forall m x y. Monad m =>
   JoinableComponentPair (ConsumerType ()) (ProducerType ()) TransducerType m x y
                         (Consumer m x ()) (Producer m y ()) (Transducer m x y)
   where join :: PairBinder m
-> Consumer m x () -> Producer m y () -> Transducer m x y
join PairBinder m
binder Consumer m x ()
c Producer m y ()
p = PairBinder m
-> Producer m y () -> Consumer m x () -> Transducer m x y
forall t1 t2 t3 (m :: * -> *) x y c1 c2 c3.
JoinableComponentPair t1 t2 t3 m x y c1 c2 c3 =>
PairBinder m -> c1 -> c2 -> c3
join PairBinder m
binder Producer m y ()
p Consumer m x ()
c
         sequence :: Consumer m x () -> Producer m y () -> Transducer m x y
sequence Consumer m x ()
c Producer m y ()
p = (forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
 OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
forall (m :: * -> *) x y.
(forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
 OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
Transducer ((forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
  OpenTransducer m a1 a2 d x y ())
 -> Transducer m x y)
-> (forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
    OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
forall a b. (a -> b) -> a -> b
$ \ Source m a1 x
source Sink m a2 y
sink -> Consumer m x () -> Source m a1 x -> Coroutine d m ()
forall (m :: * -> *) x r.
Consumer m x r
-> forall (a :: * -> *) (d :: * -> *).
   (AncestorFunctor a d, Monoid x) =>
   Source m a x -> Coroutine d m r
consume Consumer m x ()
c Source m a1 x
source Coroutine d m () -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Producer m y () -> Sink m a2 y -> Coroutine d m ()
forall (m :: * -> *) x r.
Producer m x r
-> forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r
produce Producer m y ()
p Sink m a2 y
sink

-- | Combinator 'prepend' converts the given producer to a 'Control.Concurrent.SCC.Types.Transducer' that passes all its
-- input through unmodified, except for prepending the output of the argument producer to it. The following law holds: @
-- 'prepend' /prefix/ = 'join' ('substitute' /prefix/) 'Control.Category.id' @
prepend :: forall m x r. Monad m => Producer m x r -> Transducer m x x
prepend :: Producer m x r -> Transducer m x x
prepend Producer m x r
prefixProducer = (forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
 OpenTransducer m a1 a2 d x x ())
-> Transducer m x x
forall (m :: * -> *) x y.
(forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
 OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
Transducer ((forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
  OpenTransducer m a1 a2 d x x ())
 -> Transducer m x x)
-> (forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
    OpenTransducer m a1 a2 d x x ())
-> Transducer m x x
forall a b. (a -> b) -> a -> b
$ \ Source m a1 x
source Sink m a2 x
sink -> Producer m x r -> Sink m a2 x -> Coroutine d m r
forall (m :: * -> *) x r.
Producer m x r
-> forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r
produce Producer m x r
prefixProducer Sink m a2 x
sink Coroutine d m r -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Source m a1 x -> Sink m a2 x -> Coroutine d m ()
forall (m :: * -> *) (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *) x.
(Monad m, Monoid x, AncestorFunctor a1 d, AncestorFunctor a2 d) =>
Source m a1 x -> Sink m a2 x -> Coroutine d m ()
pour_ Source m a1 x
source Sink m a2 x
sink

-- | Combinator 'append' converts the given producer to a 'Control.Concurrent.SCC.Types.Transducer' that passes all its
-- input through unmodified, finally appending the output of the argument producer to it. The following law holds: @
-- 'append' /suffix/ = 'join' 'Control.Category.id' ('substitute' /suffix/) @
append :: forall m x r. Monad m => Producer m x r -> Transducer m x x
append :: Producer m x r -> Transducer m x x
append Producer m x r
suffixProducer = (forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
 OpenTransducer m a1 a2 d x x ())
-> Transducer m x x
forall (m :: * -> *) x y.
(forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
 OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
Transducer ((forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
  OpenTransducer m a1 a2 d x x ())
 -> Transducer m x x)
-> (forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
    OpenTransducer m a1 a2 d x x ())
-> Transducer m x x
forall a b. (a -> b) -> a -> b
$ \ Source m a1 x
source Sink m a2 x
sink -> Source m a1 x -> Sink m a2 x -> Coroutine d m Bool
forall (m :: * -> *) (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *) x.
(Monad m, Monoid x, AncestorFunctor a1 d, AncestorFunctor a2 d) =>
Source m a1 x -> Sink m a2 x -> Coroutine d m Bool
pour Source m a1 x
source Sink m a2 x
sink Coroutine d m Bool -> Coroutine d m r -> Coroutine d m r
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Producer m x r -> Sink m a2 x -> Coroutine d m r
forall (m :: * -> *) x r.
Producer m x r
-> forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r
produce Producer m x r
suffixProducer Sink m a2 x
sink Coroutine d m r -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

-- | The 'substitute' combinator converts its argument producer to a 'Control.Concurrent.SCC.Types.Transducer' that
-- produces the same output, while consuming its entire input and ignoring it.
substitute :: forall m x y r. (Monad m, Monoid x) => Producer m y r -> Transducer m x y
substitute :: Producer m y r -> Transducer m x y
substitute Producer m y r
feed = (forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
 OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
forall (m :: * -> *) x y.
(forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
 OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
Transducer ((forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
  OpenTransducer m a1 a2 d x y ())
 -> Transducer m x y)
-> (forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
    OpenTransducer m a1 a2 d x y ())
-> Transducer m x y
forall a b. (a -> b) -> a -> b
$ 
                  \ Source m a1 x
source Sink m a2 y
sink -> (x -> Coroutine d m ()) -> Source m a1 x -> Coroutine d m ()
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x r.
(Monad m, Monoid x, AncestorFunctor a d) =>
(x -> Coroutine d m r) -> Source m a x -> Coroutine d m ()
mapMStreamChunks_ (Coroutine d m () -> x -> Coroutine d m ()
forall a b. a -> b -> a
const (Coroutine d m () -> x -> Coroutine d m ())
-> Coroutine d m () -> x -> Coroutine d m ()
forall a b. (a -> b) -> a -> b
$ () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()) Source m a1 x
source Coroutine d m () -> Coroutine d m r -> Coroutine d m r
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Producer m y r -> Sink m a2 y -> Coroutine d m r
forall (m :: * -> *) x r.
Producer m x r
-> forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r
produce Producer m y r
feed Sink m a2 y
sink Coroutine d m r -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

-- | 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 :: forall m x. (Monad m, Monoid x) => Splitter m x -> Splitter m x
sNot :: Splitter m x -> Splitter m x
sNot Splitter m x
splitter = (forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
-> Splitter m x
forall (m :: * -> *) x b.
(Monad m, Monoid x) =>
(forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
-> Splitter m x
isolateSplitter forall (d :: * -> *).
Functor d =>
Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ()
s
   where s :: forall d. Functor d => Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ()
         s :: Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ()
s Source m d x
source Sink m d x
true Sink m d x
false = Splitter m x
-> Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ()
forall (m :: * -> *) x.
Splitter m x
-> forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
          (d :: * -> *).
   (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
    Monoid x) =>
   Source m a1 x -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ()
split Splitter m x
splitter Source m d x
source Sink m d x
false Sink m d x
true

-- | The 'sAnd' 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.
sAnd :: forall m x. (Monad m, Monoid x) => PairBinder m -> Splitter m x -> Splitter m x -> Splitter m x
sAnd :: PairBinder m -> Splitter m x -> Splitter m x -> Splitter m x
sAnd PairBinder m
binder Splitter m x
s1 Splitter m x
s2 =
   (forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
-> Splitter m x
forall (m :: * -> *) x b.
(Monad m, Monoid x) =>
(forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
-> Splitter m x
isolateSplitter ((forall (d :: * -> *).
  Functor d =>
  Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
 -> Splitter m x)
-> (forall (d :: * -> *).
    Functor d =>
    Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
-> Splitter m x
forall a b. (a -> b) -> a -> b
$ \ Source m d x
source Sink m d x
true Sink m d x
false ->
   (((), ()) -> ()) -> Coroutine d m ((), ()) -> Coroutine d m ()
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM ((), ()) -> ()
forall a b. (a, b) -> a
fst (Coroutine d m ((), ()) -> Coroutine d m ())
-> Coroutine d m ((), ()) -> Coroutine d m ()
forall a b. (a -> b) -> a -> b
$
   PairBinder m
-> (Sink m (SinkFunctor d x) x -> Coroutine (SinkFunctor d x) m ())
-> (Source m (SourceFunctor d x) x
    -> Coroutine (SourceFunctor d x) m ())
-> Coroutine d m ((), ())
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
PairBinder m
-> (Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2)
-> Coroutine a m (r1, r2)
pipeG PairBinder m
binder
      (\Sink m (SinkFunctor d x) x
true'-> Splitter m x
-> Source m d x
-> Sink m (SinkFunctor d x) x
-> Sink m d x
-> Coroutine (SinkFunctor d x) m ()
forall (m :: * -> *) x.
Splitter m x
-> forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
          (d :: * -> *).
   (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
    Monoid x) =>
   Source m a1 x -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ()
split Splitter m x
s1 Source m d x
source Sink m (SinkFunctor d x) x
true' Sink m d x
false)
      (\Source m (SourceFunctor d x) x
source'-> Splitter m x
-> Source m (SourceFunctor d x) x
-> Sink m d x
-> Sink m d x
-> Coroutine (SourceFunctor d x) m ()
forall (m :: * -> *) x.
Splitter m x
-> forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
          (d :: * -> *).
   (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
    Monoid x) =>
   Source m a1 x -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ()
split Splitter m x
s2 Source m (SourceFunctor d x) x
source' Sink m d x
true Sink m d x
false)

-- | A 'sOr' combinator's input value can reach its /false/ sink only by going through both argument splitters' /false/
-- sinks.
sOr :: forall m x. (Monad m, Monoid x) => PairBinder m -> Splitter m x -> Splitter m x -> Splitter m x
sOr :: PairBinder m -> Splitter m x -> Splitter m x -> Splitter m x
sOr PairBinder m
binder Splitter m x
s1 Splitter m x
s2 = 
   (forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
-> Splitter m x
forall (m :: * -> *) x b.
(Monad m, Monoid x) =>
(forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
-> Splitter m x
isolateSplitter ((forall (d :: * -> *).
  Functor d =>
  Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
 -> Splitter m x)
-> (forall (d :: * -> *).
    Functor d =>
    Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
-> Splitter m x
forall a b. (a -> b) -> a -> b
$ \ Source m d x
source Sink m d x
true Sink m d x
false ->
   (((), ()) -> ()) -> Coroutine d m ((), ()) -> Coroutine d m ()
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM ((), ()) -> ()
forall a b. (a, b) -> a
fst (Coroutine d m ((), ()) -> Coroutine d m ())
-> Coroutine d m ((), ()) -> Coroutine d m ()
forall a b. (a -> b) -> a -> b
$
   PairBinder m
-> (Sink m (SinkFunctor d x) x -> Coroutine (SinkFunctor d x) m ())
-> (Source m (SourceFunctor d x) x
    -> Coroutine (SourceFunctor d x) m ())
-> Coroutine d m ((), ())
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
PairBinder m
-> (Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2)
-> Coroutine a m (r1, r2)
pipeG PairBinder m
binder
      (\Sink m (SinkFunctor d x) x
false'-> Splitter m x
-> Source m d x
-> Sink m d x
-> Sink m (SinkFunctor d x) x
-> Coroutine (SinkFunctor d x) m ()
forall (m :: * -> *) x.
Splitter m x
-> forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
          (d :: * -> *).
   (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
    Monoid x) =>
   Source m a1 x -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ()
split Splitter m x
s1 Source m d x
source Sink m d x
true Sink m (SinkFunctor d x) x
false')
      (\Source m (SourceFunctor d x) x
source'-> Splitter m x
-> Source m (SourceFunctor d x) x
-> Sink m d x
-> Sink m d x
-> Coroutine (SourceFunctor d x) m ()
forall (m :: * -> *) x.
Splitter m x
-> forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
          (d :: * -> *).
   (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
    Monoid x) =>
   Source m a1 x -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ()
split Splitter m x
s2 Source m (SourceFunctor d x) x
source' Sink m d x
true Sink m d x
false)

-- | Combinator 'pAnd' is a pairwise logical conjunction of two splitters run in parallel on the same input.
pAnd :: forall m x. (Monad m, FactorialMonoid x) => PairBinder m -> Splitter m x -> Splitter m x -> Splitter m x
pAnd :: PairBinder m -> Splitter m x -> Splitter m x -> Splitter m x
pAnd = (Bool -> Bool -> Bool)
-> PairBinder m -> Splitter m x -> Splitter m x -> Splitter m x
forall (m :: * -> *) x.
(Monad m, FactorialMonoid x) =>
(Bool -> Bool -> Bool)
-> PairBinder m -> Splitter m x -> Splitter m x -> Splitter m x
zipSplittersWith Bool -> Bool -> Bool
(&&)

-- | Combinator 'pOr' is a pairwise logical disjunction of two splitters run in parallel on the same input.
pOr :: forall m x. (Monad m, FactorialMonoid x) => PairBinder m -> Splitter m x -> Splitter m x -> Splitter m x
pOr :: PairBinder m -> Splitter m x -> Splitter m x -> Splitter m x
pOr = (Bool -> Bool -> Bool)
-> PairBinder m -> Splitter m x -> Splitter m x -> Splitter m x
forall (m :: * -> *) x.
(Monad m, FactorialMonoid x) =>
(Bool -> Bool -> Bool)
-> PairBinder m -> Splitter m x -> Splitter m x -> Splitter m x
zipSplittersWith Bool -> Bool -> Bool
(||)

ifs :: forall c m x. (Monad m, Branching c m x ()) => PairBinder m -> Splitter m x -> c -> c -> c
ifs :: PairBinder m -> Splitter m x -> c -> c -> c
ifs PairBinder m
binder Splitter m x
s c
c1 c
c2 = (forall (d :: * -> *).
 PairBinder m
 -> (forall (a :: * -> *) (d' :: * -> *).
     AncestorFunctor d d' =>
     OpenConsumer m a d' x ())
 -> (forall (a :: * -> *) (d' :: * -> *).
     AncestorFunctor d d' =>
     OpenConsumer m a d' x ())
 -> forall (a :: * -> *). OpenConsumer m a d x ())
-> PairBinder m -> c -> c -> c
forall c (m :: * -> *) x r.
Branching c m x r =>
(forall (d :: * -> *).
 PairBinder m
 -> (forall (a :: * -> *) (d' :: * -> *).
     AncestorFunctor d d' =>
     OpenConsumer m a d' x r)
 -> (forall (a :: * -> *) (d' :: * -> *).
     AncestorFunctor d d' =>
     OpenConsumer m a d' x r)
 -> forall (a :: * -> *). OpenConsumer m a d x r)
-> PairBinder m -> c -> c -> c
combineBranches forall (d :: * -> *).
PairBinder m
-> (forall (a :: * -> *) (d' :: * -> *).
    AncestorFunctor d d' =>
    OpenConsumer m a d' x ())
-> (forall (a :: * -> *) (d' :: * -> *).
    AncestorFunctor d d' =>
    OpenConsumer m a d' x ())
-> forall (a :: * -> *). OpenConsumer m a d x ()
if' PairBinder m
binder c
c1 c
c2
   where if' :: forall d. PairBinder m -> (forall a d'. AncestorFunctor d d' => OpenConsumer m a d' x ()) ->
                (forall a d'. AncestorFunctor d d' => OpenConsumer m a d' x ()) ->
                forall a. OpenConsumer m a d x ()
         if' :: PairBinder m
-> (forall (a :: * -> *) (d' :: * -> *).
    AncestorFunctor d d' =>
    OpenConsumer m a d' x ())
-> (forall (a :: * -> *) (d' :: * -> *).
    AncestorFunctor d d' =>
    OpenConsumer m a d' x ())
-> forall (a :: * -> *). OpenConsumer m a d x ()
if' PairBinder m
binder' forall (a :: * -> *) (d' :: * -> *).
AncestorFunctor d d' =>
OpenConsumer m a d' x ()
c1' forall (a :: * -> *) (d' :: * -> *).
AncestorFunctor d d' =>
OpenConsumer m a d' x ()
c2' Source m a x
source = PairBinder m
-> Splitter m x
-> Source m a x
-> (Source m (SourceFunctor (SinkFunctor d x) x) x
    -> Coroutine (SourceFunctor (SinkFunctor d x) x) m ())
-> (Source m (SourceFunctor d x) x
    -> Coroutine (SourceFunctor d x) m ())
-> Coroutine d m ()
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) (d1 :: * -> *) x.
(Monad m, Monoid x, d1 ~ SinkFunctor d x, AncestorFunctor a d) =>
PairBinder m
-> Splitter m x
-> Source m a x
-> (Source m (SourceFunctor d1 x) x
    -> Coroutine (SourceFunctor d1 x) m ())
-> (Source m (SourceFunctor d x) x
    -> Coroutine (SourceFunctor d x) m ())
-> Coroutine d m ()
splitInputToConsumers PairBinder m
binder' Splitter m x
s Source m a x
source Source m (SourceFunctor (SinkFunctor d x) x) x
-> Coroutine (SourceFunctor (SinkFunctor d x) x) m ()
forall (a :: * -> *) (d' :: * -> *).
AncestorFunctor d d' =>
OpenConsumer m a d' x ()
c1' Source m (SourceFunctor d x) x
-> Coroutine (SourceFunctor d x) m ()
forall (a :: * -> *) (d' :: * -> *).
AncestorFunctor d d' =>
OpenConsumer m a d' x ()
c2'

wherever :: forall m x. (Monad m, Monoid x) => PairBinder m -> Transducer m x x -> Splitter m x -> Transducer m x x
wherever :: PairBinder m
-> Transducer m x x -> Splitter m x -> Transducer m x x
wherever PairBinder m
binder Transducer m x x
t Splitter m x
s = (forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d x -> Coroutine d m ())
-> Transducer m x x
forall (m :: * -> *) x y.
(Monad m, Monoid x) =>
(forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d y -> Coroutine d m ())
-> Transducer m x y
isolateTransducer forall (d :: * -> *).
Functor d =>
Source m d x -> Sink m d x -> Coroutine d m ()
wherever'
   where wherever' :: forall d. Functor d => Source m d x -> Sink m d x -> Coroutine d m ()
         wherever' :: Source m d x -> Sink m d x -> Coroutine d m ()
wherever' Source m d x
source Sink m d x
sink = PairBinder m
-> (Sink m (SinkFunctor d x) x -> Coroutine (SinkFunctor d x) m ())
-> (Source m (SourceFunctor d x) x
    -> Coroutine (SourceFunctor d x) m ())
-> Coroutine d m ((), ())
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
PairBinder m
-> (Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2)
-> Coroutine a m (r1, r2)
pipeG PairBinder m
binder
                                    (\Sink m (SinkFunctor d x) x
true-> Splitter m x
-> Source m d x
-> Sink m (SinkFunctor d x) x
-> Sink m d x
-> Coroutine (SinkFunctor d x) m ()
forall (m :: * -> *) x.
Splitter m x
-> forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
          (d :: * -> *).
   (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
    Monoid x) =>
   Source m a1 x -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ()
split Splitter m x
s Source m d x
source Sink m (SinkFunctor d x) x
true Sink m d x
sink)
                                    ((Source m (SourceFunctor d x) x
 -> Sink m d x -> Coroutine (SourceFunctor d x) m ())
-> Sink m d x
-> Source m (SourceFunctor d x) x
-> Coroutine (SourceFunctor d x) m ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip (Transducer m x x
-> forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
   (AncestorFunctor a1 d, AncestorFunctor a2 d, Monoid x, Monoid x) =>
   Source m a1 x -> Sink m a2 x -> Coroutine d m ()
forall (m :: * -> *) x y.
Transducer m x y
-> forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
   OpenTransducer m a1 a2 d x y ()
transduce Transducer m x x
t) Sink m d x
sink)
                                 Coroutine d m ((), ()) -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

unless :: forall m x. (Monad m, Monoid x) => PairBinder m -> Transducer m x x -> Splitter m x -> Transducer m x x
unless :: PairBinder m
-> Transducer m x x -> Splitter m x -> Transducer m x x
unless PairBinder m
binder Transducer m x x
t Splitter m x
s = PairBinder m
-> Transducer m x x -> Splitter m x -> Transducer m x x
forall (m :: * -> *) x.
(Monad m, Monoid x) =>
PairBinder m
-> Transducer m x x -> Splitter m x -> Transducer m x x
wherever PairBinder m
binder Transducer m x x
t (Splitter m x -> Splitter m x
forall (m :: * -> *) x.
(Monad m, Monoid x) =>
Splitter m x -> Splitter m x
sNot Splitter m x
s)

select :: forall m x. (Monad m, Monoid x) => Splitter m x -> Transducer m x x
select :: Splitter m x -> Transducer m x x
select Splitter m x
s = (forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d x -> Coroutine d m ())
-> Transducer m x x
forall (m :: * -> *) x y.
(Monad m, Monoid x) =>
(forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d y -> Coroutine d m ())
-> Transducer m x y
isolateTransducer forall (d :: * -> *).
Functor d =>
Source m d x -> Sink m d x -> Coroutine d m ()
t 
   where t :: forall d. Functor d => Source m d x -> Sink m d x -> Coroutine d m ()
         t :: Source m d x -> Sink m d x -> Coroutine d m ()
t Source m d x
source Sink m d x
sink = Splitter m x
-> Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ()
forall (m :: * -> *) x.
Splitter m x
-> forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
          (d :: * -> *).
   (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
    Monoid x) =>
   Source m a1 x -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ()
split Splitter m x
s Source m d x
source Sink m d x
sink (Sink m d x
forall (m :: * -> *) (a :: * -> *) x.
(Monad m, Monoid x) =>
Sink m a x
nullSink :: Sink m d x)

-- | Converts a splitter into a parser.
parseRegions :: forall m x. (Monad m, MonoidNull x) => Splitter m x -> Parser m x ()
parseRegions :: Splitter m x -> Parser m x ()
parseRegions Splitter m x
s = (forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d [Markup () x] -> Coroutine d m ())
-> Parser m x ()
forall (m :: * -> *) x y.
(Monad m, Monoid x) =>
(forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d y -> Coroutine d m ())
-> Transducer m x y
isolateTransducer ((forall (d :: * -> *).
  Functor d =>
  Source m d x -> Sink m d [Markup () x] -> Coroutine d m ())
 -> Parser m x ())
-> (forall (d :: * -> *).
    Functor d =>
    Source m d x -> Sink m d [Markup () x] -> Coroutine d m ())
-> Parser m x ()
forall a b. (a -> b) -> a -> b
$ \Source m d x
source Sink m d [Markup () x]
sink->
                    (Sink m (SinkFunctor d [(x, Bool)]) [(x, Bool)]
 -> Coroutine (SinkFunctor d [(x, Bool)]) m ())
-> (Source m (SourceFunctor d [(x, Bool)]) [(x, Bool)]
    -> Coroutine (SourceFunctor d [(x, Bool)]) m ())
-> Coroutine d m ((), ())
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
(Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2) -> Coroutine a m (r1, r2)
pipe
                       (Transducer m x [(x, Bool)]
-> Source m d x
-> Sink m (SinkFunctor d [(x, Bool)]) [(x, Bool)]
-> Coroutine (SinkFunctor d [(x, Bool)]) m ()
forall (m :: * -> *) x y.
Transducer m x y
-> forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
   OpenTransducer m a1 a2 d x y ()
transduce (Splitter m x -> Transducer m x [(x, Bool)]
forall (m :: * -> *) x.
(Monad m, MonoidNull x) =>
Splitter m x -> Transducer m x [(x, Bool)]
splitterToMarker Splitter m x
s) Source m d x
source)
                       (\Source m (SourceFunctor d [(x, Bool)]) [(x, Bool)]
source'-> (Maybe ((), Bool)
 -> (x, Bool) -> (Maybe ((), Bool), [Markup () x]))
-> Maybe ((), Bool)
-> Source m (SourceFunctor d [(x, Bool)]) [(x, Bool)]
-> Sink m d [Markup () x]
-> Coroutine (SourceFunctor d [(x, Bool)]) m (Maybe ((), Bool))
forall (m :: * -> *) (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *) x
       y acc.
(Monad m, AncestorFunctor a1 d, AncestorFunctor a2 d) =>
(acc -> x -> (acc, [y]))
-> acc -> Source m a1 [x] -> Sink m a2 [y] -> Coroutine d m acc
concatMapAccumStream Maybe ((), Bool) -> (x, Bool) -> (Maybe ((), Bool), [Markup () x])
forall x.
MonoidNull x =>
Maybe ((), Bool) -> (x, Bool) -> (Maybe ((), Bool), [Markup () x])
wrap Maybe ((), Bool)
forall a. Maybe a
Nothing Source m (SourceFunctor d [(x, Bool)]) [(x, Bool)]
source' Sink m d [Markup () x]
sink 
                                   Coroutine (SourceFunctor d [(x, Bool)]) m (Maybe ((), Bool))
-> (Maybe ((), Bool)
    -> Coroutine (SourceFunctor d [(x, Bool)]) m ())
-> Coroutine (SourceFunctor d [(x, Bool)]) m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Coroutine (SourceFunctor d [(x, Bool)]) m ()
-> (((), Bool) -> Coroutine (SourceFunctor d [(x, Bool)]) m ())
-> Maybe ((), Bool)
-> Coroutine (SourceFunctor d [(x, Bool)]) m ()
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (() -> Coroutine (SourceFunctor d [(x, Bool)]) m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()) (Sink m d [Markup () x]
-> Markup () x -> Coroutine (SourceFunctor d [(x, Bool)]) m ()
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, AncestorFunctor a d) =>
Sink m a [x] -> x -> Coroutine d m ()
put Sink m d [Markup () x]
sink (Markup () x -> Coroutine (SourceFunctor d [(x, Bool)]) m ())
-> (((), Bool) -> Markup () x)
-> ((), Bool)
-> Coroutine (SourceFunctor d [(x, Bool)]) m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((), Bool) -> Markup () x
forall y x. (y, Bool) -> Markup y x
flush))
                    Coroutine d m ((), ()) -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
   where wrap :: Maybe ((), Bool) -> (x, Bool) -> (Maybe ((), Bool), [Markup () x])
wrap Maybe ((), Bool)
Nothing (x
x, Bool
False) = (Maybe ((), Bool)
forall a. Maybe a
Nothing, if x -> Bool
forall m. MonoidNull m => m -> Bool
null x
x then [] else [x -> Markup () x
forall y x. x -> Markup y x
Content x
x])
         wrap Maybe ((), Bool)
Nothing (x
x, Bool
True) | x -> Bool
forall m. MonoidNull m => m -> Bool
null x
x = (((), Bool) -> Maybe ((), Bool)
forall a. a -> Maybe a
Just ((), Bool
False), [])
                                | Bool
otherwise = (((), Bool) -> Maybe ((), Bool)
forall a. a -> Maybe a
Just ((), Bool
True), [Boundary () -> Markup () x
forall y x. Boundary y -> Markup y x
Markup (() -> Boundary ()
forall y. y -> Boundary y
Start ()), x -> Markup () x
forall y x. x -> Markup y x
Content x
x])
         wrap (Just ((), Bool)
p) (x
x, Bool
False) = (Maybe ((), Bool)
forall a. Maybe a
Nothing, if x -> Bool
forall m. MonoidNull m => m -> Bool
null x
x then [((), Bool) -> Markup () x
forall y x. (y, Bool) -> Markup y x
flush ((), Bool)
p] else [((), Bool) -> Markup () x
forall y x. (y, Bool) -> Markup y x
flush ((), Bool)
p, x -> Markup () x
forall y x. x -> Markup y x
Content x
x])
         wrap (Just (()
b, Bool
t)) (x
x, Bool
True) = (((), Bool) -> Maybe ((), Bool)
forall a. a -> Maybe a
Just (()
b, Bool
True), if Bool
t then [x -> Markup () x
forall y x. x -> Markup y x
Content x
x] else [Boundary () -> Markup () x
forall y x. Boundary y -> Markup y x
Markup (() -> Boundary ()
forall y. y -> Boundary y
Start ()
b), x -> Markup () x
forall y x. x -> Markup y x
Content x
x])
         flush :: (y, Bool) -> Markup y x
flush (y
b, Bool
t) = Boundary y -> Markup y x
forall y x. Boundary y -> Markup y x
Markup (Boundary y -> Markup y x) -> Boundary y -> Markup y x
forall a b. (a -> b) -> a -> b
$ (if Bool
t then y -> Boundary y
forall y. y -> Boundary y
End else y -> Boundary y
forall y. y -> Boundary y
Point) y
b

-- | 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 :: forall m x. (Monad m, MonoidNull x) => 
         PairBinder m -> Transducer m x x -> Splitter m x -> Transducer m x x -> Transducer m x x
while :: PairBinder m
-> Transducer m x x
-> Splitter m x
-> Transducer m x x
-> Transducer m x x
while PairBinder m
binder Transducer m x x
t Splitter m x
s Transducer m x x
whileRest = (forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d x -> Coroutine d m ())
-> Transducer m x x
forall (m :: * -> *) x y.
(Monad m, Monoid x) =>
(forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d y -> Coroutine d m ())
-> Transducer m x y
isolateTransducer forall (d :: * -> *).
Functor d =>
Source m d x -> Sink m d x -> Coroutine d m ()
while'
   where while' :: forall d. Functor d => Source m d x -> Sink m d x -> Coroutine d m ()
         while' :: Source m d x -> Sink m d x -> Coroutine d m ()
while' Source m d x
source Sink m d x
sink =
            PairBinder m
-> (Sink m (SinkFunctor d x) x -> Coroutine (SinkFunctor d x) m ())
-> (Source m (SourceFunctor d x) x
    -> Coroutine (SourceFunctor d x) m ())
-> Coroutine d m ((), ())
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
PairBinder m
-> (Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2)
-> Coroutine a m (r1, r2)
pipeG PairBinder m
binder
               (\Sink m (SinkFunctor d x) x
true'-> Splitter m x
-> Source m d x
-> Sink m (SinkFunctor d x) x
-> Sink m d x
-> Coroutine (SinkFunctor d x) m ()
forall (m :: * -> *) x.
Splitter m x
-> forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
          (d :: * -> *).
   (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
    Monoid x) =>
   Source m a1 x -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ()
split Splitter m x
s Source m d x
source Sink m (SinkFunctor d x) x
true' Sink m d x
sink)
               (\Source m (SourceFunctor d x) x
source'-> Reader x (Bool -> Bool) Bool
-> Source m (SourceFunctor d x) x
-> Coroutine (SourceFunctor d x) m Bool
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x y.
(Monad m, Monoid x, AncestorFunctor a d) =>
Reader x (y -> y) y -> Source m a x -> Coroutine d m y
getRead Reader x (Bool -> Bool) Bool
forall x. MonoidNull x => Reader x (Bool -> Bool) Bool
readEof Source m (SourceFunctor d x) x
source'
                           Coroutine (SourceFunctor d x) m Bool
-> (Bool -> Coroutine (SourceFunctor d x) m ())
-> Coroutine (SourceFunctor d x) m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Bool
 -> Coroutine (SourceFunctor d x) m ()
 -> Coroutine (SourceFunctor d x) m ())
-> Coroutine (SourceFunctor d x) m ()
-> Bool
-> Coroutine (SourceFunctor d x) m ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip (Bool
-> Coroutine (SourceFunctor d x) m ()
-> Coroutine (SourceFunctor d x) m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
 -> Coroutine (SourceFunctor d x) m ()
 -> Coroutine (SourceFunctor d x) m ())
-> (Bool -> Bool)
-> Bool
-> Coroutine (SourceFunctor d x) m ()
-> Coroutine (SourceFunctor d x) m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Bool
not) (Transducer m x x
-> Source m (SourceFunctor d x) x
-> Sink m d x
-> Coroutine (SourceFunctor d x) m ()
forall (m :: * -> *) x y.
Transducer m x y
-> forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
   OpenTransducer m a1 a2 d x y ()
transduce (PairBinder m
-> Transducer m x x -> Transducer m x x -> Transducer m x x
forall (m :: * -> *) w c1 c2 c3.
PipeableComponentPair m w c1 c2 c3 =>
PairBinder m -> c1 -> c2 -> c3
compose PairBinder m
binder Transducer m x x
t Transducer m x x
whileRest) Source m (SourceFunctor d x) x
source' Sink m d x
sink))
            Coroutine d m ((), ()) -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

-- | 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 :: forall m x. (Monad m, MonoidNull x) => 
            PairBinder m -> Splitter m x -> Splitter m x -> Splitter m x -> Splitter m x
nestedIn :: PairBinder m
-> Splitter m x -> Splitter m x -> Splitter m x -> Splitter m x
nestedIn PairBinder m
binder Splitter m x
s1 Splitter m x
s2 Splitter m x
nestedRest =
   (forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
-> Splitter m x
forall (m :: * -> *) x b.
(Monad m, Monoid x) =>
(forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
-> Splitter m x
isolateSplitter ((forall (d :: * -> *).
  Functor d =>
  Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
 -> Splitter m x)
-> (forall (d :: * -> *).
    Functor d =>
    Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
-> Splitter m x
forall a b. (a -> b) -> a -> b
$ \ Source m d x
source Sink m d x
true Sink m d x
false ->
   (((), ((), ())) -> ())
-> Coroutine d m ((), ((), ())) -> Coroutine d m ()
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM ((), ((), ())) -> ()
forall a b. (a, b) -> a
fst (Coroutine d m ((), ((), ())) -> Coroutine d m ())
-> Coroutine d m ((), ((), ())) -> Coroutine d m ()
forall a b. (a -> b) -> a -> b
$
      PairBinder m
-> (Sink m (SinkFunctor d x) x -> Coroutine (SinkFunctor d x) m ())
-> (Source m (SourceFunctor d x) x
    -> Coroutine (SourceFunctor d x) m ((), ()))
-> Coroutine d m ((), ((), ()))
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
PairBinder m
-> (Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2)
-> Coroutine a m (r1, r2)
pipeG PairBinder m
binder
         (\Sink m (SinkFunctor d x) x
false'-> Splitter m x
-> Source m d x
-> Sink m d x
-> Sink m (SinkFunctor d x) x
-> Coroutine (SinkFunctor d x) m ()
forall (m :: * -> *) x.
Splitter m x
-> forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
          (d :: * -> *).
   (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
    Monoid x) =>
   Source m a1 x -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ()
split Splitter m x
s1 Source m d x
source Sink m d x
true Sink m (SinkFunctor d x) x
false')
         (\Source m (SourceFunctor d x) x
source'-> (Sink m (SinkFunctor (SourceFunctor d x) x) x
 -> Coroutine (SinkFunctor (SourceFunctor d x) x) m ())
-> (Source m (SourceFunctor (SourceFunctor d x) x) x
    -> Coroutine (SourceFunctor (SourceFunctor d x) x) m ())
-> Coroutine (SourceFunctor d x) m ((), ())
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
(Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2) -> Coroutine a m (r1, r2)
pipe
                        (\Sink m (SinkFunctor (SourceFunctor d x) x) x
true'-> Splitter m x
-> Source m (SourceFunctor d x) x
-> Sink m (SinkFunctor (SourceFunctor d x) x) x
-> Sink m d x
-> Coroutine (SinkFunctor (SourceFunctor d x) x) m ()
forall (m :: * -> *) (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
       (d :: * -> *) x.
(Monad m, Monoid x, AncestorFunctor a1 d, AncestorFunctor a2 d,
 AncestorFunctor a3 d) =>
Splitter m x
-> Source m a1 x -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ()
splitInput Splitter m x
s2 Source m (SourceFunctor d x) x
source' Sink m (SinkFunctor (SourceFunctor d x) x) x
true' Sink m d x
false)
                        (\Source m (SourceFunctor (SourceFunctor d x) x) x
source''-> Reader x (Bool -> Bool) Bool
-> Source m (SourceFunctor (SourceFunctor d x) x) x
-> Coroutine (SourceFunctor (SourceFunctor d x) x) m Bool
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x y.
(Monad m, Monoid x, AncestorFunctor a d) =>
Reader x (y -> y) y -> Source m a x -> Coroutine d m y
getRead Reader x (Bool -> Bool) Bool
forall x. MonoidNull x => Reader x (Bool -> Bool) Bool
readEof Source m (SourceFunctor (SourceFunctor d x) x) x
source''
                                     Coroutine (SourceFunctor (SourceFunctor d x) x) m Bool
-> (Bool -> Coroutine (SourceFunctor (SourceFunctor d x) x) m ())
-> Coroutine (SourceFunctor (SourceFunctor d x) x) m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Bool
 -> Coroutine (SourceFunctor (SourceFunctor d x) x) m ()
 -> Coroutine (SourceFunctor (SourceFunctor d x) x) m ())
-> Coroutine (SourceFunctor (SourceFunctor d x) x) m ()
-> Bool
-> Coroutine (SourceFunctor (SourceFunctor d x) x) m ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip (Bool
-> Coroutine (SourceFunctor (SourceFunctor d x) x) m ()
-> Coroutine (SourceFunctor (SourceFunctor d x) x) m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
 -> Coroutine (SourceFunctor (SourceFunctor d x) x) m ()
 -> Coroutine (SourceFunctor (SourceFunctor d x) x) m ())
-> (Bool -> Bool)
-> Bool
-> Coroutine (SourceFunctor (SourceFunctor d x) x) m ()
-> Coroutine (SourceFunctor (SourceFunctor d x) x) m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Bool
not) (Splitter m x
-> Source m (SourceFunctor (SourceFunctor d x) x) x
-> Sink m d x
-> Sink m d x
-> Coroutine (SourceFunctor (SourceFunctor d x) x) m ()
forall (m :: * -> *) x.
Splitter m x
-> forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
          (d :: * -> *).
   (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
    Monoid x) =>
   Source m a1 x -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ()
split Splitter m x
nestedRest Source m (SourceFunctor (SourceFunctor d x) x) x
source'' Sink m d x
true Sink m d x
false)))

-- | 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 :: forall m x c. (Monad m, MonoidNull x, Branching c m x ()) => PairBinder m -> Splitter m x -> c -> c -> c
foreach :: PairBinder m -> Splitter m x -> c -> c -> c
foreach PairBinder m
binder Splitter m x
s c
c1 c
c2 = (forall (d :: * -> *).
 PairBinder m
 -> (forall (a :: * -> *) (d' :: * -> *).
     AncestorFunctor d d' =>
     OpenConsumer m a d' x ())
 -> (forall (a :: * -> *) (d' :: * -> *).
     AncestorFunctor d d' =>
     OpenConsumer m a d' x ())
 -> forall (a :: * -> *). OpenConsumer m a d x ())
-> PairBinder m -> c -> c -> c
forall c (m :: * -> *) x r.
Branching c m x r =>
(forall (d :: * -> *).
 PairBinder m
 -> (forall (a :: * -> *) (d' :: * -> *).
     AncestorFunctor d d' =>
     OpenConsumer m a d' x r)
 -> (forall (a :: * -> *) (d' :: * -> *).
     AncestorFunctor d d' =>
     OpenConsumer m a d' x r)
 -> forall (a :: * -> *). OpenConsumer m a d x r)
-> PairBinder m -> c -> c -> c
combineBranches forall (d :: * -> *).
PairBinder m
-> (forall (a :: * -> *) (d' :: * -> *).
    AncestorFunctor d d' =>
    OpenConsumer m a d' x ())
-> (forall (a :: * -> *) (d' :: * -> *).
    AncestorFunctor d d' =>
    OpenConsumer m a d' x ())
-> forall (a :: * -> *). OpenConsumer m a d x ()
foreach' PairBinder m
binder c
c1 c
c2
   where foreach' :: forall d. PairBinder m -> 
                     (forall a d'. AncestorFunctor d d' => OpenConsumer m a d' x ()) ->
                     (forall a d'. AncestorFunctor d d' => OpenConsumer m a d' x ()) ->
                     forall a. OpenConsumer m a d x ()
         foreach' :: PairBinder m
-> (forall (a :: * -> *) (d' :: * -> *).
    AncestorFunctor d d' =>
    OpenConsumer m a d' x ())
-> (forall (a :: * -> *) (d' :: * -> *).
    AncestorFunctor d d' =>
    OpenConsumer m a d' x ())
-> forall (a :: * -> *). OpenConsumer m a d x ()
foreach' PairBinder m
binder' forall (a :: * -> *) (d' :: * -> *).
AncestorFunctor d d' =>
OpenConsumer m a d' x ()
c1' forall (a :: * -> *) (d' :: * -> *).
AncestorFunctor d d' =>
OpenConsumer m a d' x ()
c2' Source m a x
source =
            (((), ()) -> ()) -> Coroutine d m ((), ()) -> Coroutine d m ()
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM ((), ()) -> ()
forall a b. (a, b) -> a
fst (Coroutine d m ((), ()) -> Coroutine d m ())
-> Coroutine d m ((), ()) -> Coroutine d m ()
forall a b. (a -> b) -> a -> b
$
            PairBinder m
-> (Sink m (SinkFunctor d [(x, Bool)]) [(x, Bool)]
    -> Coroutine (SinkFunctor d [(x, Bool)]) m ())
-> (Source m (SourceFunctor d [(x, Bool)]) [(x, Bool)]
    -> Coroutine (SourceFunctor d [(x, Bool)]) m ())
-> Coroutine d m ((), ())
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
PairBinder m
-> (Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2)
-> Coroutine a m (r1, r2)
pipeG PairBinder m
binder'
               (Transducer m x [(x, Bool)]
-> Source m d x
-> Sink m (SinkFunctor d [(x, Bool)]) [(x, Bool)]
-> Coroutine (SinkFunctor d [(x, Bool)]) m ()
forall (m :: * -> *) x y.
Transducer m x y
-> forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
   OpenTransducer m a1 a2 d x y ()
transduce (Splitter m x -> Transducer m x [(x, Bool)]
forall (m :: * -> *) x.
(Monad m, MonoidNull x) =>
Splitter m x -> Transducer m x [(x, Bool)]
splitterToMarker Splitter m x
s) (Source m a x -> Source m d x
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, AncestorFunctor a d) =>
Source m a x -> Source m d x
liftSource Source m a x
source :: Source m d x))
               (\Source m (SourceFunctor d [(x, Bool)]) [(x, Bool)]
source'-> Source m (SourceFunctor d [(x, Bool)]) [(x, Bool)]
-> (Bool
    -> Source m (SourceFunctor (SourceFunctor d [(x, Bool)]) x) x
    -> Coroutine (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m ())
-> Coroutine (SourceFunctor d [(x, Bool)]) m ()
forall (m :: * -> *) x (a :: * -> *) (d :: * -> *) r.
(Monad m, MonoidNull x, AncestorFunctor a d,
 AncestorFunctor a (SinkFunctor d x),
 AncestorFunctor a (SinkFunctor (SinkFunctor d x) [(x, Bool)])) =>
Source m a [(x, Bool)]
-> (Bool
    -> Source m (SourceFunctor d x) x
    -> Coroutine (SourceFunctor d x) m r)
-> Coroutine d m ()
groupMarks Source m (SourceFunctor d [(x, Bool)]) [(x, Bool)]
source' (\Bool
b-> if Bool
b then Source m (SourceFunctor (SourceFunctor d [(x, Bool)]) x) x
-> Coroutine (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m ()
forall (a :: * -> *) (d' :: * -> *).
AncestorFunctor d d' =>
OpenConsumer m a d' x ()
c1' else Source m (SourceFunctor (SourceFunctor d [(x, Bool)]) x) x
-> Coroutine (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m ()
forall (a :: * -> *) (d' :: * -> *).
AncestorFunctor d d' =>
OpenConsumer m a d' x ()
c2'))

-- | 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 :: forall m x y. (Monad m, MonoidNull x, MonoidNull y, Coercible x y) =>
          PairBinder m -> Splitter m x -> Splitter m y -> Splitter m x
having :: PairBinder m -> Splitter m x -> Splitter m y -> Splitter m x
having PairBinder m
binder Splitter m x
s1 Splitter m y
s2 = (forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
-> Splitter m x
forall (m :: * -> *) x b.
(Monad m, Monoid x) =>
(forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
-> Splitter m x
isolateSplitter forall (d :: * -> *).
Functor d =>
Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ()
s
   where s :: forall d. Functor d => Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ()
         s :: Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ()
s Source m d x
source Sink m d x
true Sink m d x
false = PairBinder m
-> (Sink m (SinkFunctor d [(x, Bool)]) [(x, Bool)]
    -> Coroutine (SinkFunctor d [(x, Bool)]) m ())
-> (Source m (SourceFunctor d [(x, Bool)]) [(x, Bool)]
    -> Coroutine (SourceFunctor d [(x, Bool)]) m ())
-> Coroutine d m ((), ())
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
PairBinder m
-> (Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2)
-> Coroutine a m (r1, r2)
pipeG PairBinder m
binder
                                  (Transducer m x [(x, Bool)]
-> Source m d x
-> Sink m (SinkFunctor d [(x, Bool)]) [(x, Bool)]
-> Coroutine (SinkFunctor d [(x, Bool)]) m ()
forall (m :: * -> *) x y.
Transducer m x y
-> forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
   OpenTransducer m a1 a2 d x y ()
transduce (Splitter m x -> Transducer m x [(x, Bool)]
forall (m :: * -> *) x.
(Monad m, MonoidNull x) =>
Splitter m x -> Transducer m x [(x, Bool)]
splitterToMarker Splitter m x
s1) Source m d x
source)
                                  ((Source m (SourceFunctor d [(x, Bool)]) [(x, Bool)]
 -> (Bool
     -> Source m (SourceFunctor (SourceFunctor d [(x, Bool)]) x) x
     -> Coroutine (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m ())
 -> Coroutine (SourceFunctor d [(x, Bool)]) m ())
-> (Bool
    -> Source m (SourceFunctor (SourceFunctor d [(x, Bool)]) x) x
    -> Coroutine (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m ())
-> Source m (SourceFunctor d [(x, Bool)]) [(x, Bool)]
-> Coroutine (SourceFunctor d [(x, Bool)]) m ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip Source m (SourceFunctor d [(x, Bool)]) [(x, Bool)]
-> (Bool
    -> Source m (SourceFunctor (SourceFunctor d [(x, Bool)]) x) x
    -> Coroutine (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m ())
-> Coroutine (SourceFunctor d [(x, Bool)]) m ()
forall (m :: * -> *) x (a :: * -> *) (d :: * -> *) r.
(Monad m, MonoidNull x, AncestorFunctor a d,
 AncestorFunctor a (SinkFunctor d x),
 AncestorFunctor a (SinkFunctor (SinkFunctor d x) [(x, Bool)])) =>
Source m a [(x, Bool)]
-> (Bool
    -> Source m (SourceFunctor d x) x
    -> Coroutine (SourceFunctor d x) m r)
-> Coroutine d m ()
groupMarks Bool
-> Source m (SourceFunctor (SourceFunctor d [(x, Bool)]) x) x
-> Coroutine (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m ()
test)
                               Coroutine d m ((), ()) -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
            where test :: Bool
-> Source m (SourceFunctor (SourceFunctor d [(x, Bool)]) x) x
-> Coroutine (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m ()
test Bool
False Source m (SourceFunctor (SourceFunctor d [(x, Bool)]) x) x
chunk = Source m (SourceFunctor (SourceFunctor d [(x, Bool)]) x) x
-> Sink m d x
-> Coroutine (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m ()
forall (m :: * -> *) (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *) x.
(Monad m, Monoid x, AncestorFunctor a1 d, AncestorFunctor a2 d) =>
Source m a1 x -> Sink m a2 x -> Coroutine d m ()
pour_ Source m (SourceFunctor (SourceFunctor d [(x, Bool)]) x) x
chunk Sink m d x
false
                  test Bool
True Source m (SourceFunctor (SourceFunctor d [(x, Bool)]) x) x
chunk =
                     do x
chunkBuffer <- Source m (SourceFunctor (SourceFunctor d [(x, Bool)]) x) x
-> Coroutine (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m x
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, Monoid x, AncestorFunctor a d) =>
Source m a x -> Coroutine d m x
getAll Source m (SourceFunctor (SourceFunctor d [(x, Bool)]) x) x
chunk
                        (x
_, Bool
found) <- (Sink
   m (SinkFunctor (SourceFunctor (SourceFunctor d [(x, Bool)]) x) y) y
 -> Coroutine
      (SinkFunctor (SourceFunctor (SourceFunctor d [(x, Bool)]) x) y)
      m
      x)
-> (Source
      m
      (SourceFunctor (SourceFunctor (SourceFunctor d [(x, Bool)]) x) y)
      y
    -> Coroutine
         (SourceFunctor (SourceFunctor (SourceFunctor d [(x, Bool)]) x) y)
         m
         Bool)
-> Coroutine
     (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m (x, Bool)
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
(Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2) -> Coroutine a m (r1, r2)
pipe (Producer m y x
-> forall (a :: * -> *) (d :: * -> *).
   (AncestorFunctor a d, Monoid y) =>
   Sink m a y -> Coroutine d m x
forall (m :: * -> *) x r.
Producer m x r
-> forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r
produce (Producer m y x
 -> forall (a :: * -> *) (d :: * -> *).
    (AncestorFunctor a d, Monoid y) =>
    Sink m a y -> Coroutine d m x)
-> Producer m y x
-> forall (a :: * -> *) (d :: * -> *).
   (AncestorFunctor a d, Monoid y) =>
   Sink m a y -> Coroutine d m x
forall a b. (a -> b) -> a -> b
$ Producer m x x -> Producer m y x
forall x y (m :: * -> *) r.
(Coercible x y, Monad m, Monoid x, Monoid y) =>
Producer m x r -> Producer m y r
adaptProducer (Producer m x x -> Producer m y x)
-> Producer m x x -> Producer m y x
forall a b. (a -> b) -> a -> b
$ (forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x x)
-> Producer m x x
forall (m :: * -> *) x r.
(forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r)
-> Producer m x r
Producer ((forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x x)
 -> Producer m x x)
-> (forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x x)
-> Producer m x x
forall a b. (a -> b) -> a -> b
$ x -> Sink m a x -> Coroutine d m x
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, MonoidNull x, AncestorFunctor a d) =>
x -> Sink m a x -> Coroutine d m x
putAll x
chunkBuffer) (Splitter m y
-> Source
     m
     (SourceFunctor (SourceFunctor (SourceFunctor d [(x, Bool)]) x) y)
     y
-> Coroutine
     (SourceFunctor (SourceFunctor (SourceFunctor d [(x, Bool)]) x) y)
     m
     Bool
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, MonoidNull x, AncestorFunctor a d) =>
Splitter m x -> Source m a x -> Coroutine d m Bool
findsTrueIn Splitter m y
s2)
                        if Bool
found
                           then Sink m d x
-> x
-> Coroutine (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m x
forall (m :: * -> *) (a :: * -> *) x.
Sink m a x
-> forall (d :: * -> *).
   AncestorFunctor a d =>
   x -> Coroutine d m x
putChunk Sink m d x
true x
chunkBuffer
                           else x
-> Sink m d x
-> Coroutine (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m x
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, MonoidNull x, AncestorFunctor a d) =>
x -> Sink m a x -> Coroutine d m x
putAll x
chunkBuffer Sink m d x
false
                        ()
-> Coroutine (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

-- | 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 :: forall m x y. (Monad m, MonoidNull x, MonoidNull y, Coercible x y) =>
              PairBinder m -> Splitter m x -> Splitter m y -> Splitter m x
havingOnly :: PairBinder m -> Splitter m x -> Splitter m y -> Splitter m x
havingOnly PairBinder m
binder Splitter m x
s1 Splitter m y
s2 = (forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
-> Splitter m x
forall (m :: * -> *) x b.
(Monad m, Monoid x) =>
(forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
-> Splitter m x
isolateSplitter forall (d :: * -> *).
Functor d =>
Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ()
s
   where s :: forall d. Functor d => Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ()
         s :: Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ()
s Source m d x
source Sink m d x
true Sink m d x
false = PairBinder m
-> (Sink m (SinkFunctor d [(x, Bool)]) [(x, Bool)]
    -> Coroutine (SinkFunctor d [(x, Bool)]) m ())
-> (Source m (SourceFunctor d [(x, Bool)]) [(x, Bool)]
    -> Coroutine (SourceFunctor d [(x, Bool)]) m ())
-> Coroutine d m ((), ())
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
PairBinder m
-> (Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2)
-> Coroutine a m (r1, r2)
pipeG PairBinder m
binder
                                  (Transducer m x [(x, Bool)]
-> Source m d x
-> Sink m (SinkFunctor d [(x, Bool)]) [(x, Bool)]
-> Coroutine (SinkFunctor d [(x, Bool)]) m ()
forall (m :: * -> *) x y.
Transducer m x y
-> forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
   OpenTransducer m a1 a2 d x y ()
transduce (Splitter m x -> Transducer m x [(x, Bool)]
forall (m :: * -> *) x.
(Monad m, MonoidNull x) =>
Splitter m x -> Transducer m x [(x, Bool)]
splitterToMarker Splitter m x
s1) Source m d x
source)
                                  ((Source m (SourceFunctor d [(x, Bool)]) [(x, Bool)]
 -> (Bool
     -> Source m (SourceFunctor (SourceFunctor d [(x, Bool)]) x) x
     -> Coroutine (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m ())
 -> Coroutine (SourceFunctor d [(x, Bool)]) m ())
-> (Bool
    -> Source m (SourceFunctor (SourceFunctor d [(x, Bool)]) x) x
    -> Coroutine (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m ())
-> Source m (SourceFunctor d [(x, Bool)]) [(x, Bool)]
-> Coroutine (SourceFunctor d [(x, Bool)]) m ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip Source m (SourceFunctor d [(x, Bool)]) [(x, Bool)]
-> (Bool
    -> Source m (SourceFunctor (SourceFunctor d [(x, Bool)]) x) x
    -> Coroutine (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m ())
-> Coroutine (SourceFunctor d [(x, Bool)]) m ()
forall (m :: * -> *) x (a :: * -> *) (d :: * -> *) r.
(Monad m, MonoidNull x, AncestorFunctor a d,
 AncestorFunctor a (SinkFunctor d x),
 AncestorFunctor a (SinkFunctor (SinkFunctor d x) [(x, Bool)])) =>
Source m a [(x, Bool)]
-> (Bool
    -> Source m (SourceFunctor d x) x
    -> Coroutine (SourceFunctor d x) m r)
-> Coroutine d m ()
groupMarks Bool
-> Source m (SourceFunctor (SourceFunctor d [(x, Bool)]) x) x
-> Coroutine (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m ()
test)
                               Coroutine d m ((), ()) -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
            where test :: Bool
-> Source m (SourceFunctor (SourceFunctor d [(x, Bool)]) x) x
-> Coroutine (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m ()
test Bool
False Source m (SourceFunctor (SourceFunctor d [(x, Bool)]) x) x
chunk = Source m (SourceFunctor (SourceFunctor d [(x, Bool)]) x) x
-> Sink m d x
-> Coroutine (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m ()
forall (m :: * -> *) (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *) x.
(Monad m, Monoid x, AncestorFunctor a1 d, AncestorFunctor a2 d) =>
Source m a1 x -> Sink m a2 x -> Coroutine d m ()
pour_ Source m (SourceFunctor (SourceFunctor d [(x, Bool)]) x) x
chunk Sink m d x
false
                  test Bool
True Source m (SourceFunctor (SourceFunctor d [(x, Bool)]) x) x
chunk =
                     do x
chunkBuffer <- Source m (SourceFunctor (SourceFunctor d [(x, Bool)]) x) x
-> Coroutine (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m x
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, Monoid x, AncestorFunctor a d) =>
Source m a x -> Coroutine d m x
getAll Source m (SourceFunctor (SourceFunctor d [(x, Bool)]) x) x
chunk
                        (x
_, Bool
anyFalse) <-
                           (Sink
   m (SinkFunctor (SourceFunctor (SourceFunctor d [(x, Bool)]) x) y) y
 -> Coroutine
      (SinkFunctor (SourceFunctor (SourceFunctor d [(x, Bool)]) x) y)
      m
      x)
-> (Source
      m
      (SourceFunctor (SourceFunctor (SourceFunctor d [(x, Bool)]) x) y)
      y
    -> Coroutine
         (SourceFunctor (SourceFunctor (SourceFunctor d [(x, Bool)]) x) y)
         m
         Bool)
-> Coroutine
     (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m (x, Bool)
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
(Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2) -> Coroutine a m (r1, r2)
pipe (Producer m y x
-> forall (a :: * -> *) (d :: * -> *).
   (AncestorFunctor a d, Monoid y) =>
   Sink m a y -> Coroutine d m x
forall (m :: * -> *) x r.
Producer m x r
-> forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r
produce (Producer m y x
 -> forall (a :: * -> *) (d :: * -> *).
    (AncestorFunctor a d, Monoid y) =>
    Sink m a y -> Coroutine d m x)
-> Producer m y x
-> forall (a :: * -> *) (d :: * -> *).
   (AncestorFunctor a d, Monoid y) =>
   Sink m a y -> Coroutine d m x
forall a b. (a -> b) -> a -> b
$ Producer m x x -> Producer m y x
forall x y (m :: * -> *) r.
(Coercible x y, Monad m, Monoid x, Monoid y) =>
Producer m x r -> Producer m y r
adaptProducer (Producer m x x -> Producer m y x)
-> Producer m x x -> Producer m y x
forall a b. (a -> b) -> a -> b
$ (forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x x)
-> Producer m x x
forall (m :: * -> *) x r.
(forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x r)
-> Producer m x r
Producer ((forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x x)
 -> Producer m x x)
-> (forall (a :: * -> *) (d :: * -> *). OpenProducer m a d x x)
-> Producer m x x
forall a b. (a -> b) -> a -> b
$ x -> Sink m a x -> Coroutine d m x
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, MonoidNull x, AncestorFunctor a d) =>
x -> Sink m a x -> Coroutine d m x
putAll x
chunkBuffer) (Splitter m y
-> Source
     m
     (SourceFunctor (SourceFunctor (SourceFunctor d [(x, Bool)]) x) y)
     y
-> Coroutine
     (SourceFunctor (SourceFunctor (SourceFunctor d [(x, Bool)]) x) y)
     m
     Bool
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, MonoidNull x, AncestorFunctor a d) =>
Splitter m x -> Source m a x -> Coroutine d m Bool
findsFalseIn Splitter m y
s2)
                        if Bool
anyFalse
                           then x
-> Sink m d x
-> Coroutine (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m x
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, MonoidNull x, AncestorFunctor a d) =>
x -> Sink m a x -> Coroutine d m x
putAll x
chunkBuffer Sink m d x
false
                           else Sink m d x
-> x
-> Coroutine (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m x
forall (m :: * -> *) (a :: * -> *) x.
Sink m a x
-> forall (d :: * -> *).
   AncestorFunctor a d =>
   x -> Coroutine d m x
putChunk Sink m d x
true x
chunkBuffer
                        ()
-> Coroutine (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

-- | 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 :: forall m x. (Monad m, MonoidNull x) => Splitter m x -> Splitter m x
first :: Splitter m x -> Splitter m x
first Splitter m x
splitter = Splitter m x
-> (forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
           (d :: * -> *).
    (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
     AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
     AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
    Source m a1 [(x, Bool)]
    -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
-> Splitter m x
forall (m :: * -> *) x.
(Monad m, MonoidNull x) =>
Splitter m x
-> (forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
           (d :: * -> *).
    (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
     AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
     AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
    Source m a1 [(x, Bool)]
    -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
-> Splitter m x
wrapMarkedSplitter Splitter m x
splitter ((forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
         (d :: * -> *).
  (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
   AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
   AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
  Source m a1 [(x, Bool)]
  -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
 -> Splitter m x)
-> (forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
           (d :: * -> *).
    (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
     AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
     AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
    Source m a1 [(x, Bool)]
    -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
-> Splitter m x
forall a b. (a -> b) -> a -> b
$
                 \Source m a1 [(x, Bool)]
source Sink m a2 x
true Sink m a3 x
false->
                    ([(x, Bool)] -> Bool)
-> Source m a1 [(x, Bool)]
-> Sink m a3 [(x, Bool)]
-> Coroutine d m (Maybe [(x, Bool)])
forall (m :: * -> *) (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *) x.
(Monad m, FactorialMonoid x, AncestorFunctor a1 d,
 AncestorFunctor a2 d) =>
(x -> Bool)
-> Source m a1 x -> Sink m a2 x -> Coroutine d m (Maybe x)
pourUntil ((x, Bool) -> Bool
forall a b. (a, b) -> b
snd ((x, Bool) -> Bool)
-> ([(x, Bool)] -> (x, Bool)) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(x, Bool)] -> (x, Bool)
forall a. [a] -> a
head) Source m a1 [(x, Bool)]
source (Sink m a3 x -> Sink m a3 [(x, Bool)]
forall (m :: * -> *) (a :: * -> *) x mark.
(Monad m, MonoidNull x) =>
Sink m a x -> Sink m a [(x, mark)]
markDown Sink m a3 x
false)
                    Coroutine d m (Maybe [(x, Bool)])
-> (Maybe [(x, Bool)] -> Coroutine d m ()) -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ([(x, Bool)] -> Coroutine d m ())
-> Maybe [(x, Bool)] -> Coroutine d m ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
Foldable.mapM_
                           (\[(x, Bool)]
_-> ([(x, Bool)] -> Bool)
-> Source m a1 [(x, Bool)]
-> Sink m a2 [(x, Bool)]
-> Coroutine d m ()
forall (m :: * -> *) (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *) x.
(Monad m, FactorialMonoid x, AncestorFunctor a1 d,
 AncestorFunctor a2 d) =>
(x -> Bool) -> Source m a1 x -> Sink m a2 x -> Coroutine d m ()
pourWhile ((x, Bool) -> Bool
forall a b. (a, b) -> b
snd ((x, Bool) -> Bool)
-> ([(x, Bool)] -> (x, Bool)) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(x, Bool)] -> (x, Bool)
forall a. [a] -> a
head) Source m a1 [(x, Bool)]
source (Sink m a2 x -> Sink m a2 [(x, Bool)]
forall (m :: * -> *) (a :: * -> *) x mark.
(Monad m, MonoidNull x) =>
Sink m a x -> Sink m a [(x, mark)]
markDown Sink m a2 x
true)
                                 Coroutine d m () -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ((x, Bool) -> x)
-> Source m a1 [(x, Bool)] -> Sink m a3 x -> Coroutine d m ()
forall (m :: * -> *) (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *) x
       y.
(Monad m, Monoid y, AncestorFunctor a1 d, AncestorFunctor a2 d) =>
(x -> y) -> Source m a1 [x] -> Sink m a2 y -> Coroutine d m ()
concatMapStream (x, Bool) -> x
forall a b. (a, b) -> a
fst Source m a1 [(x, Bool)]
source Sink m a3 x
false)

-- | 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 :: forall m x. (Monad m, MonoidNull x) => Splitter m x -> Splitter m x
uptoFirst :: Splitter m x -> Splitter m x
uptoFirst Splitter m x
splitter = Splitter m x
-> (forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
           (d :: * -> *).
    (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
     AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
     AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
    Source m a1 [(x, Bool)]
    -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
-> Splitter m x
forall (m :: * -> *) x.
(Monad m, MonoidNull x) =>
Splitter m x
-> (forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
           (d :: * -> *).
    (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
     AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
     AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
    Source m a1 [(x, Bool)]
    -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
-> Splitter m x
wrapMarkedSplitter Splitter m x
splitter ((forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
         (d :: * -> *).
  (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
   AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
   AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
  Source m a1 [(x, Bool)]
  -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
 -> Splitter m x)
-> (forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
           (d :: * -> *).
    (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
     AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
     AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
    Source m a1 [(x, Bool)]
    -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
-> Splitter m x
forall a b. (a -> b) -> a -> b
$
                     \Source m a1 [(x, Bool)]
source Sink m a2 x
true Sink m a3 x
false->
                     do ([(x, Bool)]
pfx, Maybe [(x, Bool)]
mx) <- ([(x, Bool)] -> Bool)
-> Source m a1 [(x, Bool)]
-> Coroutine d m ([(x, Bool)], Maybe [(x, Bool)])
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, FactorialMonoid x, AncestorFunctor a d) =>
(x -> Bool) -> Source m a x -> Coroutine d m (x, Maybe x)
getUntil ((x, Bool) -> Bool
forall a b. (a, b) -> b
snd ((x, Bool) -> Bool)
-> ([(x, Bool)] -> (x, Bool)) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(x, Bool)] -> (x, Bool)
forall a. [a] -> a
head) Source m a1 [(x, Bool)]
source
                        let prefix' :: x
prefix' = [x] -> x
forall a. Monoid a => [a] -> a
mconcat ([x] -> x) -> [x] -> x
forall a b. (a -> b) -> a -> b
$ ((x, Bool) -> x) -> [(x, Bool)] -> [x]
forall a b. (a -> b) -> [a] -> [b]
List.map (\(x
x, Bool
False)-> x
x) [(x, Bool)]
pfx
                        Coroutine d m ()
-> ([(x, Bool)] -> Coroutine d m ())
-> Maybe [(x, Bool)]
-> Coroutine d m ()
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
                           (x -> Sink m a3 x -> Coroutine d m x
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, MonoidNull x, AncestorFunctor a d) =>
x -> Sink m a x -> Coroutine d m x
putAll x
prefix' Sink m a3 x
false Coroutine d m x -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ())
                           (\[(x, Bool)
x]-> x -> Sink m a2 x -> Coroutine d m x
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, MonoidNull x, AncestorFunctor a d) =>
x -> Sink m a x -> Coroutine d m x
putAll x
prefix' Sink m a2 x
true
                                   Coroutine d m x -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ([(x, Bool)] -> Bool)
-> Source m a1 [(x, Bool)]
-> Sink m a2 [(x, Bool)]
-> Coroutine d m ()
forall (m :: * -> *) (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *) x.
(Monad m, FactorialMonoid x, AncestorFunctor a1 d,
 AncestorFunctor a2 d) =>
(x -> Bool) -> Source m a1 x -> Sink m a2 x -> Coroutine d m ()
pourWhile ((x, Bool) -> Bool
forall a b. (a, b) -> b
snd ((x, Bool) -> Bool)
-> ([(x, Bool)] -> (x, Bool)) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(x, Bool)] -> (x, Bool)
forall a. [a] -> a
head) Source m a1 [(x, Bool)]
source (Sink m a2 x -> Sink m a2 [(x, Bool)]
forall (m :: * -> *) (a :: * -> *) x mark.
(Monad m, MonoidNull x) =>
Sink m a x -> Sink m a [(x, mark)]
markDown Sink m a2 x
true)
                                   Coroutine d m () -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ((x, Bool) -> x)
-> Source m a1 [(x, Bool)] -> Sink m a3 x -> Coroutine d m ()
forall (m :: * -> *) (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *) x
       y.
(Monad m, Monoid y, AncestorFunctor a1 d, AncestorFunctor a2 d) =>
(x -> y) -> Source m a1 [x] -> Sink m a2 y -> Coroutine d m ()
concatMapStream (x, Bool) -> x
forall a b. (a, b) -> a
fst Source m a1 [(x, Bool)]
source Sink m a3 x
false)
                           Maybe [(x, Bool)]
mx

-- | 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 :: forall m x. (Monad m, MonoidNull x) => Splitter m x -> Splitter m x
last :: Splitter m x -> Splitter m x
last Splitter m x
splitter = 
   Splitter m x
-> (forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
           (d :: * -> *).
    (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
     AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
     AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
    Source m a1 [(x, Bool)]
    -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
-> Splitter m x
forall (m :: * -> *) x.
(Monad m, MonoidNull x) =>
Splitter m x
-> (forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
           (d :: * -> *).
    (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
     AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
     AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
    Source m a1 [(x, Bool)]
    -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
-> Splitter m x
wrapMarkedSplitter Splitter m x
splitter ((forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
         (d :: * -> *).
  (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
   AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
   AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
  Source m a1 [(x, Bool)]
  -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
 -> Splitter m x)
-> (forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
           (d :: * -> *).
    (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
     AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
     AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
    Source m a1 [(x, Bool)]
    -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
-> Splitter m x
forall a b. (a -> b) -> a -> b
$ 
   \Source m a1 [(x, Bool)]
source Sink m a2 x
true Sink m a3 x
false->
   let split1 :: Coroutine d m x
split1 = ([(x, Bool)] -> Bool)
-> Source m a1 [(x, Bool)]
-> Coroutine d m ([(x, Bool)], Maybe [(x, Bool)])
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, FactorialMonoid x, AncestorFunctor a d) =>
(x -> Bool) -> Source m a x -> Coroutine d m (x, Maybe x)
getUntil (Bool -> Bool
not (Bool -> Bool) -> ([(x, Bool)] -> Bool) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (x, Bool) -> Bool
forall a b. (a, b) -> b
snd ((x, Bool) -> Bool)
-> ([(x, Bool)] -> (x, Bool)) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(x, Bool)] -> (x, Bool)
forall a. [a] -> a
head) Source m a1 [(x, Bool)]
source Coroutine d m ([(x, Bool)], Maybe [(x, Bool)])
-> (([(x, Bool)], Maybe [(x, Bool)]) -> Coroutine d m x)
-> Coroutine d m x
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ([(x, Bool)], Maybe [(x, Bool)]) -> Coroutine d m x
split2
       split2 :: ([(x, Bool)], Maybe [(x, Bool)]) -> Coroutine d m x
split2 ([(x, Bool)]
trues, Maybe [(x, Bool)]
Nothing) = Sink m a2 x -> x -> Coroutine d m x
forall (m :: * -> *) (a :: * -> *) x.
Sink m a x
-> forall (d :: * -> *).
   AncestorFunctor a d =>
   x -> Coroutine d m x
putChunk Sink m a2 x
true ([x] -> x
forall a. Monoid a => [a] -> a
mconcat ([x] -> x) -> [x] -> x
forall a b. (a -> b) -> a -> b
$ ((x, Bool) -> x) -> [(x, Bool)] -> [x]
forall a b. (a -> b) -> [a] -> [b]
List.map (x, Bool) -> x
forall a b. (a, b) -> a
fst [(x, Bool)]
trues)
       split2 ([(x, Bool)]
trues, Just [~(x
_, Bool
False)]) = ([(x, Bool)] -> Bool)
-> Source m a1 [(x, Bool)]
-> Coroutine d m ([(x, Bool)], Maybe [(x, Bool)])
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, FactorialMonoid x, AncestorFunctor a d) =>
(x -> Bool) -> Source m a x -> Coroutine d m (x, Maybe x)
getUntil ((x, Bool) -> Bool
forall a b. (a, b) -> b
snd ((x, Bool) -> Bool)
-> ([(x, Bool)] -> (x, Bool)) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(x, Bool)] -> (x, Bool)
forall a. [a] -> a
head) Source m a1 [(x, Bool)]
source Coroutine d m ([(x, Bool)], Maybe [(x, Bool)])
-> (([(x, Bool)], Maybe [(x, Bool)]) -> Coroutine d m x)
-> Coroutine d m x
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [(x, Bool)] -> ([(x, Bool)], Maybe [(x, Bool)]) -> Coroutine d m x
split3 [(x, Bool)]
trues
       split3 :: [(x, Bool)] -> ([(x, Bool)], Maybe [(x, Bool)]) -> Coroutine d m x
split3 [(x, Bool)]
ts ([(x, Bool)]
fs, Maybe [(x, Bool)]
Nothing) = Sink m a2 x -> x -> Coroutine d m x
forall (m :: * -> *) (a :: * -> *) x.
Sink m a x
-> forall (d :: * -> *).
   AncestorFunctor a d =>
   x -> Coroutine d m x
putChunk Sink m a2 x
true ([x] -> x
forall a. Monoid a => [a] -> a
mconcat ([x] -> x) -> [x] -> x
forall a b. (a -> b) -> a -> b
$ ((x, Bool) -> x) -> [(x, Bool)] -> [x]
forall a b. (a -> b) -> [a] -> [b]
List.map (x, Bool) -> x
forall a b. (a, b) -> a
fst [(x, Bool)]
ts) Coroutine d m x -> Coroutine d m x -> Coroutine d m x
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> x -> Sink m a3 x -> Coroutine d m x
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, MonoidNull x, AncestorFunctor a d) =>
x -> Sink m a x -> Coroutine d m x
putAll ([x] -> x
forall a. Monoid a => [a] -> a
mconcat ([x] -> x) -> [x] -> x
forall a b. (a -> b) -> a -> b
$ ((x, Bool) -> x) -> [(x, Bool)] -> [x]
forall a b. (a -> b) -> [a] -> [b]
List.map (x, Bool) -> x
forall a b. (a, b) -> a
fst [(x, Bool)]
fs) Sink m a3 x
false
       split3 [(x, Bool)]
ts ([(x, Bool)]
fs, x :: Maybe [(x, Bool)]
x@Just{}) = x -> Sink m a3 x -> Coroutine d m x
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, MonoidNull x, AncestorFunctor a d) =>
x -> Sink m a x -> Coroutine d m x
putAll ([x] -> x
forall a. Monoid a => [a] -> a
mconcat ([x] -> x) -> [x] -> x
forall a b. (a -> b) -> a -> b
$ ((x, Bool) -> x) -> [(x, Bool)] -> [x]
forall a b. (a -> b) -> [a] -> [b]
List.map (x, Bool) -> x
forall a b. (a, b) -> a
fst [(x, Bool)]
ts) Sink m a3 x
false Coroutine d m x -> Coroutine d m x -> Coroutine d m x
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> x -> Sink m a3 x -> Coroutine d m x
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, MonoidNull x, AncestorFunctor a d) =>
x -> Sink m a x -> Coroutine d m x
putAll ([x] -> x
forall a. Monoid a => [a] -> a
mconcat ([x] -> x) -> [x] -> x
forall a b. (a -> b) -> a -> b
$ ((x, Bool) -> x) -> [(x, Bool)] -> [x]
forall a b. (a -> b) -> [a] -> [b]
List.map (x, Bool) -> x
forall a b. (a, b) -> a
fst [(x, Bool)]
fs) Sink m a3 x
false 
                                  Coroutine d m x -> Coroutine d m x -> Coroutine d m x
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Coroutine d m x
split1
   in ([(x, Bool)] -> Bool)
-> Source m a1 [(x, Bool)]
-> Sink m a3 [(x, Bool)]
-> Coroutine d m (Maybe [(x, Bool)])
forall (m :: * -> *) (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *) x.
(Monad m, FactorialMonoid x, AncestorFunctor a1 d,
 AncestorFunctor a2 d) =>
(x -> Bool)
-> Source m a1 x -> Sink m a2 x -> Coroutine d m (Maybe x)
pourUntil ((x, Bool) -> Bool
forall a b. (a, b) -> b
snd ((x, Bool) -> Bool)
-> ([(x, Bool)] -> (x, Bool)) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(x, Bool)] -> (x, Bool)
forall a. [a] -> a
head) Source m a1 [(x, Bool)]
source (Sink m a3 x -> Sink m a3 [(x, Bool)]
forall (m :: * -> *) (a :: * -> *) x mark.
(Monad m, MonoidNull x) =>
Sink m a x -> Sink m a [(x, mark)]
markDown Sink m a3 x
false) 
      Coroutine d m (Maybe [(x, Bool)])
-> (Maybe [(x, Bool)] -> Coroutine d m ()) -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ([(x, Bool)] -> Coroutine d m x)
-> Maybe [(x, Bool)] -> Coroutine d m ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
Foldable.mapM_ (Coroutine d m x -> [(x, Bool)] -> Coroutine d m x
forall a b. a -> b -> a
const Coroutine d m x
split1)

-- | 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 :: forall m x. (Monad m, MonoidNull x) => Splitter m x -> Splitter m x
lastAndAfter :: Splitter m x -> Splitter m x
lastAndAfter Splitter m x
splitter = 
   Splitter m x
-> (forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
           (d :: * -> *).
    (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
     AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
     AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
    Source m a1 [(x, Bool)]
    -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
-> Splitter m x
forall (m :: * -> *) x.
(Monad m, MonoidNull x) =>
Splitter m x
-> (forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
           (d :: * -> *).
    (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
     AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
     AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
    Source m a1 [(x, Bool)]
    -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
-> Splitter m x
wrapMarkedSplitter Splitter m x
splitter ((forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
         (d :: * -> *).
  (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
   AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
   AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
  Source m a1 [(x, Bool)]
  -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
 -> Splitter m x)
-> (forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
           (d :: * -> *).
    (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
     AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
     AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
    Source m a1 [(x, Bool)]
    -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
-> Splitter m x
forall a b. (a -> b) -> a -> b
$
   \Source m a1 [(x, Bool)]
source Sink m a2 x
true Sink m a3 x
false->
   let split1 :: Coroutine d m x
split1 = ([(x, Bool)] -> Bool)
-> Source m a1 [(x, Bool)]
-> Coroutine d m ([(x, Bool)], Maybe [(x, Bool)])
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, FactorialMonoid x, AncestorFunctor a d) =>
(x -> Bool) -> Source m a x -> Coroutine d m (x, Maybe x)
getUntil (Bool -> Bool
not (Bool -> Bool) -> ([(x, Bool)] -> Bool) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (x, Bool) -> Bool
forall a b. (a, b) -> b
snd ((x, Bool) -> Bool)
-> ([(x, Bool)] -> (x, Bool)) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(x, Bool)] -> (x, Bool)
forall a. [a] -> a
head) Source m a1 [(x, Bool)]
source Coroutine d m ([(x, Bool)], Maybe [(x, Bool)])
-> (([(x, Bool)], Maybe [(x, Bool)]) -> Coroutine d m x)
-> Coroutine d m x
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ([(x, Bool)], Maybe [(x, Bool)]) -> Coroutine d m x
split2
       split2 :: ([(x, Bool)], Maybe [(x, Bool)]) -> Coroutine d m x
split2 ([(x, Bool)]
trues, Maybe [(x, Bool)]
Nothing) = Sink m a2 x -> x -> Coroutine d m x
forall (m :: * -> *) (a :: * -> *) x.
Sink m a x
-> forall (d :: * -> *).
   AncestorFunctor a d =>
   x -> Coroutine d m x
putChunk Sink m a2 x
true ([x] -> x
forall a. Monoid a => [a] -> a
mconcat ([x] -> x) -> [x] -> x
forall a b. (a -> b) -> a -> b
$ ((x, Bool) -> x) -> [(x, Bool)] -> [x]
forall a b. (a -> b) -> [a] -> [b]
List.map (x, Bool) -> x
forall a b. (a, b) -> a
fst [(x, Bool)]
trues)
       split2 ([(x, Bool)]
trues, Just [~(x
_, Bool
False)]) = ([(x, Bool)] -> Bool)
-> Source m a1 [(x, Bool)]
-> Coroutine d m ([(x, Bool)], Maybe [(x, Bool)])
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, FactorialMonoid x, AncestorFunctor a d) =>
(x -> Bool) -> Source m a x -> Coroutine d m (x, Maybe x)
getUntil ((x, Bool) -> Bool
forall a b. (a, b) -> b
snd ((x, Bool) -> Bool)
-> ([(x, Bool)] -> (x, Bool)) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(x, Bool)] -> (x, Bool)
forall a. [a] -> a
head) Source m a1 [(x, Bool)]
source Coroutine d m ([(x, Bool)], Maybe [(x, Bool)])
-> (([(x, Bool)], Maybe [(x, Bool)]) -> Coroutine d m x)
-> Coroutine d m x
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [(x, Bool)] -> ([(x, Bool)], Maybe [(x, Bool)]) -> Coroutine d m x
split3 [(x, Bool)]
trues
       split3 :: [(x, Bool)] -> ([(x, Bool)], Maybe [(x, Bool)]) -> Coroutine d m x
split3 [(x, Bool)]
ts ([(x, Bool)]
fs, Maybe [(x, Bool)]
Nothing) = Sink m a2 x -> x -> Coroutine d m x
forall (m :: * -> *) (a :: * -> *) x.
Sink m a x
-> forall (d :: * -> *).
   AncestorFunctor a d =>
   x -> Coroutine d m x
putChunk Sink m a2 x
true ([x] -> x
forall a. Monoid a => [a] -> a
mconcat ([x] -> x) -> [x] -> x
forall a b. (a -> b) -> a -> b
$ ((x, Bool) -> x) -> [(x, Bool)] -> [x]
forall a b. (a -> b) -> [a] -> [b]
List.map (x, Bool) -> x
forall a b. (a, b) -> a
fst [(x, Bool)]
ts) Coroutine d m x -> Coroutine d m x -> Coroutine d m x
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Sink m a2 x -> x -> Coroutine d m x
forall (m :: * -> *) (a :: * -> *) x.
Sink m a x
-> forall (d :: * -> *).
   AncestorFunctor a d =>
   x -> Coroutine d m x
putChunk Sink m a2 x
true ([x] -> x
forall a. Monoid a => [a] -> a
mconcat ([x] -> x) -> [x] -> x
forall a b. (a -> b) -> a -> b
$ ((x, Bool) -> x) -> [(x, Bool)] -> [x]
forall a b. (a -> b) -> [a] -> [b]
List.map (x, Bool) -> x
forall a b. (a, b) -> a
fst [(x, Bool)]
fs)
       split3 [(x, Bool)]
ts ([(x, Bool)]
fs, x :: Maybe [(x, Bool)]
x@Just{}) = x -> Sink m a3 x -> Coroutine d m x
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, MonoidNull x, AncestorFunctor a d) =>
x -> Sink m a x -> Coroutine d m x
putAll ([x] -> x
forall a. Monoid a => [a] -> a
mconcat ([x] -> x) -> [x] -> x
forall a b. (a -> b) -> a -> b
$ ((x, Bool) -> x) -> [(x, Bool)] -> [x]
forall a b. (a -> b) -> [a] -> [b]
List.map (x, Bool) -> x
forall a b. (a, b) -> a
fst [(x, Bool)]
ts) Sink m a3 x
false Coroutine d m x -> Coroutine d m x -> Coroutine d m x
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> x -> Sink m a3 x -> Coroutine d m x
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, MonoidNull x, AncestorFunctor a d) =>
x -> Sink m a x -> Coroutine d m x
putAll ([x] -> x
forall a. Monoid a => [a] -> a
mconcat ([x] -> x) -> [x] -> x
forall a b. (a -> b) -> a -> b
$ ((x, Bool) -> x) -> [(x, Bool)] -> [x]
forall a b. (a -> b) -> [a] -> [b]
List.map (x, Bool) -> x
forall a b. (a, b) -> a
fst [(x, Bool)]
fs) Sink m a3 x
false 
                                  Coroutine d m x -> Coroutine d m x -> Coroutine d m x
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Coroutine d m x
split1
   in ([(x, Bool)] -> Bool)
-> Source m a1 [(x, Bool)]
-> Sink m a3 [(x, Bool)]
-> Coroutine d m (Maybe [(x, Bool)])
forall (m :: * -> *) (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *) x.
(Monad m, FactorialMonoid x, AncestorFunctor a1 d,
 AncestorFunctor a2 d) =>
(x -> Bool)
-> Source m a1 x -> Sink m a2 x -> Coroutine d m (Maybe x)
pourUntil ((x, Bool) -> Bool
forall a b. (a, b) -> b
snd ((x, Bool) -> Bool)
-> ([(x, Bool)] -> (x, Bool)) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(x, Bool)] -> (x, Bool)
forall a. [a] -> a
head) Source m a1 [(x, Bool)]
source (Sink m a3 x -> Sink m a3 [(x, Bool)]
forall (m :: * -> *) (a :: * -> *) x mark.
(Monad m, MonoidNull x) =>
Sink m a x -> Sink m a [(x, mark)]
markDown Sink m a3 x
false) 
      Coroutine d m (Maybe [(x, Bool)])
-> (Maybe [(x, Bool)] -> Coroutine d m ()) -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ([(x, Bool)] -> Coroutine d m x)
-> Maybe [(x, Bool)] -> Coroutine d m ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
Foldable.mapM_ (Coroutine d m x -> [(x, Bool)] -> Coroutine d m x
forall a b. a -> b -> a
const Coroutine d m x
split1)

-- | 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 :: forall m x. (Monad m, MonoidNull x) => Splitter m x -> Splitter m x
prefix :: Splitter m x -> Splitter m x
prefix Splitter m x
splitter = Splitter m x
-> (forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
           (d :: * -> *).
    (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
     AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
     AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
    Source m a1 [(x, Bool)]
    -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
-> Splitter m x
forall (m :: * -> *) x.
(Monad m, MonoidNull x) =>
Splitter m x
-> (forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
           (d :: * -> *).
    (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
     AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
     AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
    Source m a1 [(x, Bool)]
    -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
-> Splitter m x
wrapMarkedSplitter Splitter m x
splitter forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *) (d :: * -> *).
(AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
 AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
 AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
Source m a1 [(x, Bool)]
-> Sink m a2 x -> Sink m a3 x -> Coroutine d m ()
splitMarked
   where splitMarked :: forall a1 a2 a3 d. (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
                                            AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
                                            AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
                        Source m a1 [(x, Bool)] -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ()
         splitMarked :: Source m a1 [(x, Bool)]
-> Sink m a2 x -> Sink m a3 x -> Coroutine d m ()
splitMarked Source m a1 [(x, Bool)]
source Sink m a2 x
true Sink m a3 x
false =
            ([(x, Bool)] -> Bool)
-> Source m a1 [(x, Bool)]
-> Sink m d [(x, Bool)]
-> Coroutine d m (Maybe [(x, Bool)])
forall (m :: * -> *) (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *) x.
(Monad m, FactorialMonoid x, AncestorFunctor a1 d,
 AncestorFunctor a2 d) =>
(x -> Bool)
-> Source m a1 x -> Sink m a2 x -> Coroutine d m (Maybe x)
pourUntil (Bool -> Bool
not (Bool -> Bool) -> ([(x, Bool)] -> Bool) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. x -> Bool
forall m. MonoidNull m => m -> Bool
null (x -> Bool) -> ([(x, Bool)] -> x) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (x, Bool) -> x
forall a b. (a, b) -> a
fst ((x, Bool) -> x) -> ([(x, Bool)] -> (x, Bool)) -> [(x, Bool)] -> x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(x, Bool)] -> (x, Bool)
forall a. [a] -> a
head) Source m a1 [(x, Bool)]
source (Sink m d [(x, Bool)]
forall (m :: * -> *) (a :: * -> *) x.
(Monad m, Monoid x) =>
Sink m a x
nullSink :: Sink m d [(x, Bool)])
            Coroutine d m (Maybe [(x, Bool)])
-> (Maybe [(x, Bool)] -> Coroutine d m ()) -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Coroutine d m ()
-> ([(x, Bool)] -> Coroutine d m ())
-> Maybe [(x, Bool)]
-> Coroutine d m ()
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
                   (() -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ())
                   (\[(x, Bool)
x0]-> Bool -> Coroutine d m () -> Coroutine d m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when ((x, Bool) -> Bool
forall a b. (a, b) -> b
snd (x, Bool)
x0) (([(x, Bool)] -> Bool)
-> Source m a1 [(x, Bool)]
-> Sink m a2 [(x, Bool)]
-> Coroutine d m ()
forall (m :: * -> *) (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *) x.
(Monad m, FactorialMonoid x, AncestorFunctor a1 d,
 AncestorFunctor a2 d) =>
(x -> Bool) -> Source m a1 x -> Sink m a2 x -> Coroutine d m ()
pourWhile ((x, Bool) -> Bool
forall a b. (a, b) -> b
snd ((x, Bool) -> Bool)
-> ([(x, Bool)] -> (x, Bool)) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(x, Bool)] -> (x, Bool)
forall a. [a] -> a
head) Source m a1 [(x, Bool)]
source (Sink m a2 x -> Sink m a2 [(x, Bool)]
forall (m :: * -> *) (a :: * -> *) x mark.
(Monad m, MonoidNull x) =>
Sink m a x -> Sink m a [(x, mark)]
markDown Sink m a2 x
true))
                            Coroutine d m () -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ((x, Bool) -> x)
-> Source m a1 [(x, Bool)] -> Sink m a3 x -> Coroutine d m ()
forall (m :: * -> *) (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *) x
       y.
(Monad m, Monoid y, AncestorFunctor a1 d, AncestorFunctor a2 d) =>
(x -> y) -> Source m a1 [x] -> Sink m a2 y -> Coroutine d m ()
concatMapStream (x, Bool) -> x
forall a b. (a, b) -> a
fst Source m a1 [(x, Bool)]
source Sink m a3 x
false)

-- | 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 :: forall m x. (Monad m, MonoidNull x) => Splitter m x -> Splitter m x
suffix :: Splitter m x -> Splitter m x
suffix Splitter m x
splitter = 
   Splitter m x
-> (forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
           (d :: * -> *).
    (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
     AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
     AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
    Source m a1 [(x, Bool)]
    -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
-> Splitter m x
forall (m :: * -> *) x.
(Monad m, MonoidNull x) =>
Splitter m x
-> (forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
           (d :: * -> *).
    (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
     AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
     AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
    Source m a1 [(x, Bool)]
    -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
-> Splitter m x
wrapMarkedSplitter Splitter m x
splitter ((forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
         (d :: * -> *).
  (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
   AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
   AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
  Source m a1 [(x, Bool)]
  -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
 -> Splitter m x)
-> (forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
           (d :: * -> *).
    (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
     AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
     AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
    Source m a1 [(x, Bool)]
    -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
-> Splitter m x
forall a b. (a -> b) -> a -> b
$
   \Source m a1 [(x, Bool)]
source Sink m a2 x
true Sink m a3 x
false->
   let split0 :: Coroutine d m ()
split0 = ([(x, Bool)] -> Bool)
-> Source m a1 [(x, Bool)]
-> Sink m a3 [(x, Bool)]
-> Coroutine d m (Maybe [(x, Bool)])
forall (m :: * -> *) (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *) x.
(Monad m, FactorialMonoid x, AncestorFunctor a1 d,
 AncestorFunctor a2 d) =>
(x -> Bool)
-> Source m a1 x -> Sink m a2 x -> Coroutine d m (Maybe x)
pourUntil ((x, Bool) -> Bool
forall a b. (a, b) -> b
snd ((x, Bool) -> Bool)
-> ([(x, Bool)] -> (x, Bool)) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(x, Bool)] -> (x, Bool)
forall a. [a] -> a
head) Source m a1 [(x, Bool)]
source (Sink m a3 x -> Sink m a3 [(x, Bool)]
forall (m :: * -> *) (a :: * -> *) x mark.
(Monad m, MonoidNull x) =>
Sink m a x -> Sink m a [(x, mark)]
markDown Sink m a3 x
false)
                Coroutine d m (Maybe [(x, Bool)])
-> (Maybe [(x, Bool)] -> Coroutine d m ()) -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ([(x, Bool)] -> Coroutine d m ())
-> Maybe [(x, Bool)] -> Coroutine d m ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
Foldable.mapM_ (Coroutine d m () -> [(x, Bool)] -> Coroutine d m ()
forall a b. a -> b -> a
const Coroutine d m ()
split1)
       split1 :: Coroutine d m ()
split1 = ([(x, Bool)] -> Bool)
-> Source m a1 [(x, Bool)]
-> Coroutine d m ([(x, Bool)], Maybe [(x, Bool)])
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, FactorialMonoid x, AncestorFunctor a d) =>
(x -> Bool) -> Source m a x -> Coroutine d m (x, Maybe x)
getUntil (Bool -> Bool
not (Bool -> Bool) -> ([(x, Bool)] -> Bool) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (x, Bool) -> Bool
forall a b. (a, b) -> b
snd ((x, Bool) -> Bool)
-> ([(x, Bool)] -> (x, Bool)) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(x, Bool)] -> (x, Bool)
forall a. [a] -> a
head) Source m a1 [(x, Bool)]
source Coroutine d m ([(x, Bool)], Maybe [(x, Bool)])
-> (([(x, Bool)], Maybe [(x, Bool)]) -> Coroutine d m ())
-> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ([(x, Bool)], Maybe [(x, Bool)]) -> Coroutine d m ()
split2
       split2 :: ([(x, Bool)], Maybe [(x, Bool)]) -> Coroutine d m ()
split2 ([(x, Bool)]
trues, Maybe [(x, Bool)]
Nothing) = x -> Sink m a2 x -> Coroutine d m x
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, MonoidNull x, AncestorFunctor a d) =>
x -> Sink m a x -> Coroutine d m x
putAll ([x] -> x
forall a. Monoid a => [a] -> a
mconcat ([x] -> x) -> [x] -> x
forall a b. (a -> b) -> a -> b
$ ((x, Bool) -> x) -> [(x, Bool)] -> [x]
forall a b. (a -> b) -> [a] -> [b]
List.map (x, Bool) -> x
forall a b. (a, b) -> a
fst [(x, Bool)]
trues) Sink m a2 x
true Coroutine d m x -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
       split2 ([(x, Bool)]
trues, Just [(x
x, Bool
False)]) 
          | x -> Bool
forall m. MonoidNull m => m -> Bool
null x
x = do ([(x, Bool)]
_, Maybe [(x, Bool)]
mr) <- ([(x, Bool)] -> Bool)
-> Source m a1 [(x, Bool)]
-> Coroutine d m ([(x, Bool)], Maybe [(x, Bool)])
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, FactorialMonoid x, AncestorFunctor a d) =>
(x -> Bool) -> Source m a x -> Coroutine d m (x, Maybe x)
getUntil (Bool -> Bool
not (Bool -> Bool) -> ([(x, Bool)] -> Bool) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. x -> Bool
forall m. MonoidNull m => m -> Bool
null (x -> Bool) -> ([(x, Bool)] -> x) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (x, Bool) -> x
forall a b. (a, b) -> a
fst ((x, Bool) -> x) -> ([(x, Bool)] -> (x, Bool)) -> [(x, Bool)] -> x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(x, Bool)] -> (x, Bool)
forall a. [a] -> a
head) Source m a1 [(x, Bool)]
source
                        case Maybe [(x, Bool)]
mr of Maybe [(x, Bool)]
Nothing -> x -> Sink m a2 x -> Coroutine d m x
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, MonoidNull x, AncestorFunctor a d) =>
x -> Sink m a x -> Coroutine d m x
putAll ([x] -> x
forall a. Monoid a => [a] -> a
mconcat ([x] -> x) -> [x] -> x
forall a b. (a -> b) -> a -> b
$ ((x, Bool) -> x) -> [(x, Bool)] -> [x]
forall a b. (a -> b) -> [a] -> [b]
List.map (x, Bool) -> x
forall a b. (a, b) -> a
fst [(x, Bool)]
trues) Sink m a2 x
true 
                                              Coroutine d m x -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
                                   Just{} -> x -> Sink m a3 x -> Coroutine d m x
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, MonoidNull x, AncestorFunctor a d) =>
x -> Sink m a x -> Coroutine d m x
putAll ([x] -> x
forall a. Monoid a => [a] -> a
mconcat ([x] -> x) -> [x] -> x
forall a b. (a -> b) -> a -> b
$ ((x, Bool) -> x) -> [(x, Bool)] -> [x]
forall a b. (a -> b) -> [a] -> [b]
List.map (x, Bool) -> x
forall a b. (a, b) -> a
fst [(x, Bool)]
trues) Sink m a3 x
false 
                                             Coroutine d m x -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Coroutine d m ()
split0
          | Bool
otherwise = x -> Sink m a3 x -> Coroutine d m x
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, MonoidNull x, AncestorFunctor a d) =>
x -> Sink m a x -> Coroutine d m x
putAll ([x] -> x
forall a. Monoid a => [a] -> a
mconcat ([x] -> x) -> [x] -> x
forall a b. (a -> b) -> a -> b
$ ((x, Bool) -> x) -> [(x, Bool)] -> [x]
forall a b. (a -> b) -> [a] -> [b]
List.map (x, Bool) -> x
forall a b. (a, b) -> a
fst [(x, Bool)]
trues) Sink m a3 x
false  Coroutine d m x -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Coroutine d m ()
split0
   in Coroutine d m ()
split0

-- | 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 :: forall m x. (Monad m, MonoidNull x) => Splitter m x -> Splitter m x
even :: Splitter m x -> Splitter m x
even Splitter m x
splitter = Splitter m x
-> (forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
           (d :: * -> *).
    (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
     AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
     AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
    Source m a1 [(x, Bool)]
    -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
-> Splitter m x
forall (m :: * -> *) x.
(Monad m, MonoidNull x) =>
Splitter m x
-> (forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
           (d :: * -> *).
    (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
     AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
     AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
    Source m a1 [(x, Bool)]
    -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
-> Splitter m x
wrapMarkedSplitter Splitter m x
splitter ((forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
         (d :: * -> *).
  (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
   AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
   AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
  Source m a1 [(x, Bool)]
  -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
 -> Splitter m x)
-> (forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
           (d :: * -> *).
    (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
     AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
     AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
    Source m a1 [(x, Bool)]
    -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
-> Splitter m x
forall a b. (a -> b) -> a -> b
$
                \Source m a1 [(x, Bool)]
source Sink m a2 x
true Sink m a3 x
false->
                let false' :: Sink m a3 [(x, Bool)]
false' = Sink m a3 x -> Sink m a3 [(x, Bool)]
forall (m :: * -> *) (a :: * -> *) x mark.
(Monad m, MonoidNull x) =>
Sink m a x -> Sink m a [(x, mark)]
markDown Sink m a3 x
false
                    split0 :: Coroutine d m ()
split0 = ([(x, Bool)] -> Bool)
-> Source m a1 [(x, Bool)]
-> Sink m a3 [(x, Bool)]
-> Coroutine d m (Maybe [(x, Bool)])
forall (m :: * -> *) (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *) x.
(Monad m, FactorialMonoid x, AncestorFunctor a1 d,
 AncestorFunctor a2 d) =>
(x -> Bool)
-> Source m a1 x -> Sink m a2 x -> Coroutine d m (Maybe x)
pourUntil ((x, Bool) -> Bool
forall a b. (a, b) -> b
snd ((x, Bool) -> Bool)
-> ([(x, Bool)] -> (x, Bool)) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(x, Bool)] -> (x, Bool)
forall a. [a] -> a
head) Source m a1 [(x, Bool)]
source Sink m a3 [(x, Bool)]
false' Coroutine d m (Maybe [(x, Bool)])
-> (Maybe [(x, Bool)] -> Coroutine d m ()) -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Maybe [(x, Bool)] -> Coroutine d m ()
split1
                    split1 :: Maybe [(x, Bool)] -> Coroutine d m ()
split1 Maybe [(x, Bool)]
Nothing = () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
                    split1 (Just [~(x
_, Bool
True)]) = Coroutine d m ()
split2
                    split2 :: Coroutine d m ()
split2 = ([(x, Bool)] -> Bool)
-> Source m a1 [(x, Bool)]
-> Sink m a3 [(x, Bool)]
-> Coroutine d m (Maybe [(x, Bool)])
forall (m :: * -> *) (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *) x.
(Monad m, FactorialMonoid x, AncestorFunctor a1 d,
 AncestorFunctor a2 d) =>
(x -> Bool)
-> Source m a1 x -> Sink m a2 x -> Coroutine d m (Maybe x)
pourUntil (Bool -> Bool
not (Bool -> Bool) -> ([(x, Bool)] -> Bool) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (x, Bool) -> Bool
forall a b. (a, b) -> b
snd ((x, Bool) -> Bool)
-> ([(x, Bool)] -> (x, Bool)) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(x, Bool)] -> (x, Bool)
forall a. [a] -> a
head) Source m a1 [(x, Bool)]
source Sink m a3 [(x, Bool)]
false' Coroutine d m (Maybe [(x, Bool)])
-> (Maybe [(x, Bool)] -> Coroutine d m ()) -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Maybe [(x, Bool)] -> Coroutine d m ()
split3
                    split3 :: Maybe [(x, Bool)] -> Coroutine d m ()
split3 Maybe [(x, Bool)]
Nothing = () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
                    split3 (Just [~(x
_, Bool
False)]) = ([(x, Bool)] -> Bool)
-> Source m a1 [(x, Bool)]
-> Sink m a3 [(x, Bool)]
-> Coroutine d m (Maybe [(x, Bool)])
forall (m :: * -> *) (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *) x.
(Monad m, FactorialMonoid x, AncestorFunctor a1 d,
 AncestorFunctor a2 d) =>
(x -> Bool)
-> Source m a1 x -> Sink m a2 x -> Coroutine d m (Maybe x)
pourUntil ((x, Bool) -> Bool
forall a b. (a, b) -> b
snd ((x, Bool) -> Bool)
-> ([(x, Bool)] -> (x, Bool)) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(x, Bool)] -> (x, Bool)
forall a. [a] -> a
head) Source m a1 [(x, Bool)]
source Sink m a3 [(x, Bool)]
false' Coroutine d m (Maybe [(x, Bool)])
-> (Maybe [(x, Bool)] -> Coroutine d m ()) -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Maybe [(x, Bool)] -> Coroutine d m ()
split4
                    split4 :: Maybe [(x, Bool)] -> Coroutine d m ()
split4 Maybe [(x, Bool)]
Nothing = () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
                    split4 (Just [~(x
_, Bool
True)]) = Coroutine d m ()
split5
                    split5 :: Coroutine d m ()
split5 = ([(x, Bool)] -> Bool)
-> Source m a1 [(x, Bool)]
-> Sink m a2 [(x, Bool)]
-> Coroutine d m ()
forall (m :: * -> *) (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *) x.
(Monad m, FactorialMonoid x, AncestorFunctor a1 d,
 AncestorFunctor a2 d) =>
(x -> Bool) -> Source m a1 x -> Sink m a2 x -> Coroutine d m ()
pourWhile ((x, Bool) -> Bool
forall a b. (a, b) -> b
snd ((x, Bool) -> Bool)
-> ([(x, Bool)] -> (x, Bool)) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(x, Bool)] -> (x, Bool)
forall a. [a] -> a
head) Source m a1 [(x, Bool)]
source (Sink m a2 x -> Sink m a2 [(x, Bool)]
forall (m :: * -> *) (a :: * -> *) x mark.
(Monad m, MonoidNull x) =>
Sink m a x -> Sink m a [(x, mark)]
markDown Sink m a2 x
true) Coroutine d m () -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Coroutine d m ()
split0
                in Coroutine d m ()
split0

-- | 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 :: forall m x. (Monad m, MonoidNull x) => Splitter m x -> Splitter m x
startOf :: Splitter m x -> Splitter m x
startOf Splitter m x
splitter = Splitter m x
-> (forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
           (d :: * -> *).
    (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
     AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
     AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
    Source m a1 [(x, Bool)]
    -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
-> Splitter m x
forall (m :: * -> *) x.
(Monad m, MonoidNull x) =>
Splitter m x
-> (forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
           (d :: * -> *).
    (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
     AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
     AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
    Source m a1 [(x, Bool)]
    -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
-> Splitter m x
wrapMarkedSplitter Splitter m x
splitter ((forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
         (d :: * -> *).
  (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
   AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
   AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
  Source m a1 [(x, Bool)]
  -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
 -> Splitter m x)
-> (forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
           (d :: * -> *).
    (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
     AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
     AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
    Source m a1 [(x, Bool)]
    -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
-> Splitter m x
forall a b. (a -> b) -> a -> b
$
                   \Source m a1 [(x, Bool)]
source Sink m a2 x
true Sink m a3 x
false->
                   let false' :: Sink m a3 [(x, Bool)]
false' = Sink m a3 x -> Sink m a3 [(x, Bool)]
forall (m :: * -> *) (a :: * -> *) x mark.
(Monad m, MonoidNull x) =>
Sink m a x -> Sink m a [(x, mark)]
markDown Sink m a3 x
false
                       split0 :: Coroutine d m ()
split0 = ([(x, Bool)] -> Bool)
-> Source m a1 [(x, Bool)]
-> Sink m a3 [(x, Bool)]
-> Coroutine d m (Maybe [(x, Bool)])
forall (m :: * -> *) (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *) x.
(Monad m, FactorialMonoid x, AncestorFunctor a1 d,
 AncestorFunctor a2 d) =>
(x -> Bool)
-> Source m a1 x -> Sink m a2 x -> Coroutine d m (Maybe x)
pourUntil ((x, Bool) -> Bool
forall a b. (a, b) -> b
snd ((x, Bool) -> Bool)
-> ([(x, Bool)] -> (x, Bool)) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(x, Bool)] -> (x, Bool)
forall a. [a] -> a
head) Source m a1 [(x, Bool)]
source Sink m a3 [(x, Bool)]
false' Coroutine d m (Maybe [(x, Bool)])
-> (Maybe [(x, Bool)] -> Coroutine d m ()) -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Maybe [(x, Bool)] -> Coroutine d m ()
split1
                       split1 :: Maybe [(x, Bool)] -> Coroutine d m ()
split1 Maybe [(x, Bool)]
Nothing = () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
                       split1 (Just [~(x
_, Bool
True)]) = Sink m a2 x -> x -> Coroutine d m x
forall (m :: * -> *) (a :: * -> *) x.
Sink m a x
-> forall (d :: * -> *).
   AncestorFunctor a d =>
   x -> Coroutine d m x
putChunk Sink m a2 x
true x
forall a. Monoid a => a
mempty Coroutine d m x -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Coroutine d m ()
split2
                       split2 :: Coroutine d m ()
split2 = ([(x, Bool)] -> Bool)
-> Source m a1 [(x, Bool)]
-> Sink m a3 [(x, Bool)]
-> Coroutine d m (Maybe [(x, Bool)])
forall (m :: * -> *) (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *) x.
(Monad m, FactorialMonoid x, AncestorFunctor a1 d,
 AncestorFunctor a2 d) =>
(x -> Bool)
-> Source m a1 x -> Sink m a2 x -> Coroutine d m (Maybe x)
pourUntil (Bool -> Bool
not (Bool -> Bool) -> ([(x, Bool)] -> Bool) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (x, Bool) -> Bool
forall a b. (a, b) -> b
snd ((x, Bool) -> Bool)
-> ([(x, Bool)] -> (x, Bool)) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(x, Bool)] -> (x, Bool)
forall a. [a] -> a
head) Source m a1 [(x, Bool)]
source Sink m a3 [(x, Bool)]
false' Coroutine d m (Maybe [(x, Bool)])
-> (Maybe [(x, Bool)] -> Coroutine d m ()) -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Maybe [(x, Bool)] -> Coroutine d m ()
split3
                       split3 :: Maybe [(x, Bool)] -> Coroutine d m ()
split3 Maybe [(x, Bool)]
Nothing = () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
                       split3 (Just [~(x
_, Bool
False)]) = Coroutine d m ()
split0
                   in Coroutine d m ()
split0

-- | 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 :: forall m x. (Monad m, MonoidNull x) => Splitter m x -> Splitter m x
endOf :: Splitter m x -> Splitter m x
endOf Splitter m x
splitter = Splitter m x
-> (forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
           (d :: * -> *).
    (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
     AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
     AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
    Source m a1 [(x, Bool)]
    -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
-> Splitter m x
forall (m :: * -> *) x.
(Monad m, MonoidNull x) =>
Splitter m x
-> (forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
           (d :: * -> *).
    (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
     AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
     AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
    Source m a1 [(x, Bool)]
    -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
-> Splitter m x
wrapMarkedSplitter Splitter m x
splitter ((forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
         (d :: * -> *).
  (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
   AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
   AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
  Source m a1 [(x, Bool)]
  -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
 -> Splitter m x)
-> (forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
           (d :: * -> *).
    (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
     AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
     AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
    Source m a1 [(x, Bool)]
    -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
-> Splitter m x
forall a b. (a -> b) -> a -> b
$
                 \Source m a1 [(x, Bool)]
source Sink m a2 x
true Sink m a3 x
false->
                 let false' :: Sink m a3 [(x, Bool)]
false' = Sink m a3 x -> Sink m a3 [(x, Bool)]
forall (m :: * -> *) (a :: * -> *) x mark.
(Monad m, MonoidNull x) =>
Sink m a x -> Sink m a [(x, mark)]
markDown Sink m a3 x
false
                     split0 :: Coroutine d m ()
split0 = ([(x, Bool)] -> Bool)
-> Source m a1 [(x, Bool)]
-> Sink m a3 [(x, Bool)]
-> Coroutine d m (Maybe [(x, Bool)])
forall (m :: * -> *) (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *) x.
(Monad m, FactorialMonoid x, AncestorFunctor a1 d,
 AncestorFunctor a2 d) =>
(x -> Bool)
-> Source m a1 x -> Sink m a2 x -> Coroutine d m (Maybe x)
pourUntil ((x, Bool) -> Bool
forall a b. (a, b) -> b
snd ((x, Bool) -> Bool)
-> ([(x, Bool)] -> (x, Bool)) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(x, Bool)] -> (x, Bool)
forall a. [a] -> a
head) Source m a1 [(x, Bool)]
source Sink m a3 [(x, Bool)]
false' Coroutine d m (Maybe [(x, Bool)])
-> (Maybe [(x, Bool)] -> Coroutine d m ()) -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Maybe [(x, Bool)] -> Coroutine d m ()
split1
                     split1 :: Maybe [(x, Bool)] -> Coroutine d m ()
split1 Maybe [(x, Bool)]
Nothing = () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
                     split1 (Just [~(x
_, Bool
True)]) = Coroutine d m ()
split2
                     split2 :: Coroutine d m ()
split2 = ([(x, Bool)] -> Bool)
-> Source m a1 [(x, Bool)]
-> Sink m a3 [(x, Bool)]
-> Coroutine d m (Maybe [(x, Bool)])
forall (m :: * -> *) (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *) x.
(Monad m, FactorialMonoid x, AncestorFunctor a1 d,
 AncestorFunctor a2 d) =>
(x -> Bool)
-> Source m a1 x -> Sink m a2 x -> Coroutine d m (Maybe x)
pourUntil (Bool -> Bool
not (Bool -> Bool) -> ([(x, Bool)] -> Bool) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (x, Bool) -> Bool
forall a b. (a, b) -> b
snd ((x, Bool) -> Bool)
-> ([(x, Bool)] -> (x, Bool)) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(x, Bool)] -> (x, Bool)
forall a. [a] -> a
head) Source m a1 [(x, Bool)]
source Sink m a3 [(x, Bool)]
false'
                              Coroutine d m (Maybe [(x, Bool)])
-> (Maybe [(x, Bool)] -> Coroutine d m ()) -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Sink m a2 x -> x -> Coroutine d m x
forall (m :: * -> *) (a :: * -> *) x.
Sink m a x
-> forall (d :: * -> *).
   AncestorFunctor a d =>
   x -> Coroutine d m x
putChunk Sink m a2 x
true x
forall a. Monoid a => a
mempty Coroutine d m x -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>) (Coroutine d m () -> Coroutine d m ())
-> (Maybe [(x, Bool)] -> Coroutine d m ())
-> Maybe [(x, Bool)]
-> Coroutine d m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe [(x, Bool)] -> Coroutine d m ()
split3
                     split3 :: Maybe [(x, Bool)] -> Coroutine d m ()
split3 Maybe [(x, Bool)]
Nothing = () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
                     split3 (Just [~(x
_, Bool
False)]) = Coroutine d m ()
split0
                 in Coroutine d m ()
split0

-- | Combinator 'followedBy' treats its argument 'Splitter's 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 :: forall m x. (Monad m, FactorialMonoid x) => PairBinder m -> Splitter m x -> Splitter m x -> Splitter m x
followedBy :: PairBinder m -> Splitter m x -> Splitter m x -> Splitter m x
followedBy PairBinder m
binder Splitter m x
s1 Splitter m x
s2 =
   (forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
-> Splitter m x
forall (m :: * -> *) x b.
(Monad m, Monoid x) =>
(forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
-> Splitter m x
isolateSplitter ((forall (d :: * -> *).
  Functor d =>
  Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
 -> Splitter m x)
-> (forall (d :: * -> *).
    Functor d =>
    Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
-> Splitter m x
forall a b. (a -> b) -> a -> b
$ \ Source m d x
source Sink m d x
true Sink m d x
false ->
   PairBinder m
-> (Sink m (SinkFunctor d [(x, Bool)]) [(x, Bool)]
    -> Coroutine (SinkFunctor d [(x, Bool)]) m ())
-> (Source m (SourceFunctor d [(x, Bool)]) [(x, Bool)]
    -> Coroutine (SourceFunctor d [(x, Bool)]) m ())
-> Coroutine d m ((), ())
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
PairBinder m
-> (Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2)
-> Coroutine a m (r1, r2)
pipeG PairBinder m
binder
      (Transducer m x [(x, Bool)]
-> Source m d x
-> Sink m (SinkFunctor d [(x, Bool)]) [(x, Bool)]
-> Coroutine (SinkFunctor d [(x, Bool)]) m ()
forall (m :: * -> *) x y.
Transducer m x y
-> forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
   OpenTransducer m a1 a2 d x y ()
transduce (Splitter m x -> Transducer m x [(x, Bool)]
forall (m :: * -> *) x.
(Monad m, MonoidNull x) =>
Splitter m x -> Transducer m x [(x, Bool)]
splitterToMarker Splitter m x
s1) Source m d x
source)
      (\Source m (SourceFunctor d [(x, Bool)]) [(x, Bool)]
source'->
       let false' :: Sink m d [(x, Bool)]
false' = Sink m d x -> Sink m d [(x, Bool)]
forall (m :: * -> *) (a :: * -> *) x mark.
(Monad m, MonoidNull x) =>
Sink m a x -> Sink m a [(x, mark)]
markDown Sink m d x
false
           get0 :: Seq (x, Bool) -> Coroutine (SourceFunctor d [(x, Bool)]) m ()
get0 Seq (x, Bool)
q = case Seq (x, Bool) -> ViewL (x, Bool)
forall a. Seq a -> ViewL a
Seq.viewl Seq (x, Bool)
q
                    of ViewL (x, Bool)
Seq.EmptyL -> Coroutine (SourceFunctor d [(x, Bool)]) m ()
split0
                       (x
x, Bool
False) :< Seq (x, Bool)
rest -> Sink m d x -> x -> Coroutine (SourceFunctor d [(x, Bool)]) m x
forall (m :: * -> *) (a :: * -> *) x.
Sink m a x
-> forall (d :: * -> *).
   AncestorFunctor a d =>
   x -> Coroutine d m x
putChunk Sink m d x
false x
x Coroutine (SourceFunctor d [(x, Bool)]) m x
-> Coroutine (SourceFunctor d [(x, Bool)]) m ()
-> Coroutine (SourceFunctor d [(x, Bool)]) m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Seq (x, Bool) -> Coroutine (SourceFunctor d [(x, Bool)]) m ()
get0 Seq (x, Bool)
rest
                       (x
_, Bool
True) :< Seq (x, Bool)
_ -> Seq x
-> Seq (x, Bool) -> Coroutine (SourceFunctor d [(x, Bool)]) m ()
get2 Seq x
forall a. Seq a
Seq.empty Seq (x, Bool)
q
           split0 :: Coroutine (SourceFunctor d [(x, Bool)]) m ()
split0 = ([(x, Bool)] -> Bool)
-> Source m (SourceFunctor d [(x, Bool)]) [(x, Bool)]
-> Sink m d [(x, Bool)]
-> Coroutine (SourceFunctor d [(x, Bool)]) m (Maybe [(x, Bool)])
forall (m :: * -> *) (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *) x.
(Monad m, FactorialMonoid x, AncestorFunctor a1 d,
 AncestorFunctor a2 d) =>
(x -> Bool)
-> Source m a1 x -> Sink m a2 x -> Coroutine d m (Maybe x)
pourUntil ((x, Bool) -> Bool
forall a b. (a, b) -> b
snd ((x, Bool) -> Bool)
-> ([(x, Bool)] -> (x, Bool)) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(x, Bool)] -> (x, Bool)
forall a. [a] -> a
head) Source m (SourceFunctor d [(x, Bool)]) [(x, Bool)]
source' Sink m d [(x, Bool)]
false'
                    Coroutine (SourceFunctor d [(x, Bool)]) m (Maybe [(x, Bool)])
-> (Maybe [(x, Bool)]
    -> Coroutine (SourceFunctor d [(x, Bool)]) m ())
-> Coroutine (SourceFunctor d [(x, Bool)]) m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Coroutine (SourceFunctor d [(x, Bool)]) m ()
-> ([(x, Bool)] -> Coroutine (SourceFunctor d [(x, Bool)]) m ())
-> Maybe [(x, Bool)]
-> Coroutine (SourceFunctor d [(x, Bool)]) m ()
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
                           (() -> Coroutine (SourceFunctor d [(x, Bool)]) m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ())
                           (Coroutine (SourceFunctor d [(x, Bool)]) m ()
-> [(x, Bool)] -> Coroutine (SourceFunctor d [(x, Bool)]) m ()
forall a b. a -> b -> a
const (Coroutine (SourceFunctor d [(x, Bool)]) m ()
 -> [(x, Bool)] -> Coroutine (SourceFunctor d [(x, Bool)]) m ())
-> Coroutine (SourceFunctor d [(x, Bool)]) m ()
-> [(x, Bool)]
-> Coroutine (SourceFunctor d [(x, Bool)]) m ()
forall a b. (a -> b) -> a -> b
$ Coroutine (SourceFunctor d [(x, Bool)]) m ()
split1) 
           split1 :: Coroutine (SourceFunctor d [(x, Bool)]) m ()
split1 = do ([(x, Bool)]
list, Maybe [(x, Bool)]
mx) <- ([(x, Bool)] -> Bool)
-> Source m (SourceFunctor d [(x, Bool)]) [(x, Bool)]
-> Coroutine
     (SourceFunctor d [(x, Bool)]) m ([(x, Bool)], Maybe [(x, Bool)])
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, FactorialMonoid x, AncestorFunctor a d) =>
(x -> Bool) -> Source m a x -> Coroutine d m (x, Maybe x)
getUntil (Bool -> Bool
not (Bool -> Bool) -> ([(x, Bool)] -> Bool) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (x, Bool) -> Bool
forall a b. (a, b) -> b
snd ((x, Bool) -> Bool)
-> ([(x, Bool)] -> (x, Bool)) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(x, Bool)] -> (x, Bool)
forall a. [a] -> a
head) Source m (SourceFunctor d [(x, Bool)]) [(x, Bool)]
source'
                       let list' :: Seq x
list' = [x] -> Seq x
forall a. [a] -> Seq a
Seq.fromList ([x] -> Seq x) -> [x] -> Seq x
forall a b. (a -> b) -> a -> b
$ ((x, Bool) -> x) -> [(x, Bool)] -> [x]
forall a b. (a -> b) -> [a] -> [b]
List.map (\(x
x, Bool
True)-> x
x) [(x, Bool)]
list
                       Coroutine (SourceFunctor d [(x, Bool)]) m ()
-> ([(x, Bool)] -> Coroutine (SourceFunctor d [(x, Bool)]) m ())
-> Maybe [(x, Bool)]
-> Coroutine (SourceFunctor d [(x, Bool)]) m ()
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
                          (Seq x -> Coroutine (SourceFunctor d [(x, Bool)]) m ()
testEnd ([x] -> Seq x
forall a. [a] -> Seq a
Seq.fromList ([x] -> Seq x) -> [x] -> Seq x
forall a b. (a -> b) -> a -> b
$ ((x, Bool) -> x) -> [(x, Bool)] -> [x]
forall a b. (a -> b) -> [a] -> [b]
List.map (\(x
x, Bool
True)-> x
x) [(x, Bool)]
list))
                          ((Source m (SourceFunctor d [(x, Bool)]) [(x, Bool)]
-> Coroutine (SourceFunctor d [(x, Bool)]) m [(x, Bool)]
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, FactorialMonoid x, AncestorFunctor a d) =>
Source m a x -> Coroutine d m x
getPrime Source m (SourceFunctor d [(x, Bool)]) [(x, Bool)]
source' Coroutine (SourceFunctor d [(x, Bool)]) m [(x, Bool)]
-> Coroutine (SourceFunctor d [(x, Bool)]) m ()
-> Coroutine (SourceFunctor d [(x, Bool)]) m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>) (Coroutine (SourceFunctor d [(x, Bool)]) m ()
 -> Coroutine (SourceFunctor d [(x, Bool)]) m ())
-> ([(x, Bool)] -> Coroutine (SourceFunctor d [(x, Bool)]) m ())
-> [(x, Bool)]
-> Coroutine (SourceFunctor d [(x, Bool)]) m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Seq x
-> Seq (x, Bool) -> Coroutine (SourceFunctor d [(x, Bool)]) m ()
get3 Seq x
list' (Seq (x, Bool) -> Coroutine (SourceFunctor d [(x, Bool)]) m ())
-> ([(x, Bool)] -> Seq (x, Bool))
-> [(x, Bool)]
-> Coroutine (SourceFunctor d [(x, Bool)]) m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (x, Bool) -> Seq (x, Bool)
forall a. a -> Seq a
Seq.singleton ((x, Bool) -> Seq (x, Bool))
-> ([(x, Bool)] -> (x, Bool)) -> [(x, Bool)] -> Seq (x, Bool)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(x, Bool)] -> (x, Bool)
forall a. [a] -> a
head)
                          Maybe [(x, Bool)]
mx
           get2 :: Seq x
-> Seq (x, Bool) -> Coroutine (SourceFunctor d [(x, Bool)]) m ()
get2 Seq x
q Seq (x, Bool)
q' = case Seq (x, Bool) -> ViewL (x, Bool)
forall a. Seq a -> ViewL a
Seq.viewl Seq (x, Bool)
q'
                       of ViewL (x, Bool)
Seq.EmptyL -> Source m (SourceFunctor d [(x, Bool)]) [(x, Bool)]
-> Coroutine (SourceFunctor d [(x, Bool)]) m (Maybe (x, Bool))
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, AncestorFunctor a d) =>
Source m a [x] -> Coroutine d m (Maybe x)
get Source m (SourceFunctor d [(x, Bool)]) [(x, Bool)]
source'
                                        Coroutine (SourceFunctor d [(x, Bool)]) m (Maybe (x, Bool))
-> (Maybe (x, Bool)
    -> Coroutine (SourceFunctor d [(x, Bool)]) m ())
-> Coroutine (SourceFunctor d [(x, Bool)]) m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Coroutine (SourceFunctor d [(x, Bool)]) m ()
-> ((x, Bool) -> Coroutine (SourceFunctor d [(x, Bool)]) m ())
-> Maybe (x, Bool)
-> Coroutine (SourceFunctor d [(x, Bool)]) m ()
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Seq x -> Coroutine (SourceFunctor d [(x, Bool)]) m ()
testEnd Seq x
q) (Seq x
-> Seq (x, Bool) -> Coroutine (SourceFunctor d [(x, Bool)]) m ()
get2 Seq x
q (Seq (x, Bool) -> Coroutine (SourceFunctor d [(x, Bool)]) m ())
-> ((x, Bool) -> Seq (x, Bool))
-> (x, Bool)
-> Coroutine (SourceFunctor d [(x, Bool)]) m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (x, Bool) -> Seq (x, Bool)
forall a. a -> Seq a
Seq.singleton)
                          (x
x, Bool
True) :< Seq (x, Bool)
rest -> Seq x
-> Seq (x, Bool) -> Coroutine (SourceFunctor d [(x, Bool)]) m ()
get2 (Seq x
q Seq x -> x -> Seq x
forall a. Seq a -> a -> Seq a
|> x
x) Seq (x, Bool)
rest
                          (x
_, Bool
False) :< Seq (x, Bool)
_ -> Seq x
-> Seq (x, Bool) -> Coroutine (SourceFunctor d [(x, Bool)]) m ()
get3 Seq x
q Seq (x, Bool)
q'
           get3 :: Seq x
-> Seq (x, Bool) -> Coroutine (SourceFunctor d [(x, Bool)]) m ()
get3 Seq x
q Seq (x, Bool)
q' = do let list :: x
list = [x] -> x
forall a. Monoid a => [a] -> a
mconcat ([x] -> x) -> [x] -> x
forall a b. (a -> b) -> a -> b
$ ((x, Bool) -> x) -> [(x, Bool)] -> [x]
forall a b. (a -> b) -> [a] -> [b]
List.map (x, Bool) -> x
forall a b. (a, b) -> a
fst (ViewL (x, Bool) -> [(x, Bool)]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Foldable.toList (ViewL (x, Bool) -> [(x, Bool)]) -> ViewL (x, Bool) -> [(x, Bool)]
forall a b. (a -> b) -> a -> b
$ Seq (x, Bool) -> ViewL (x, Bool)
forall a. Seq a -> ViewL a
Seq.viewl Seq (x, Bool)
q')
                          (Seq (x, Bool)
q'', Maybe Int
mn) <- (Sink m (SinkFunctor (SourceFunctor d [(x, Bool)]) x) x
 -> Coroutine
      (SinkFunctor (SourceFunctor d [(x, Bool)]) x) m (Seq (x, Bool)))
-> (Source m (SourceFunctor (SourceFunctor d [(x, Bool)]) x) x
    -> Coroutine
         (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m (Maybe Int))
-> Coroutine
     (SourceFunctor d [(x, Bool)]) m (Seq (x, Bool), Maybe Int)
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
(Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2) -> Coroutine a m (r1, r2)
pipe (\Sink m (SinkFunctor (SourceFunctor d [(x, Bool)]) x) x
sink-> x
-> Sink m (SinkFunctor (SourceFunctor d [(x, Bool)]) x) x
-> Coroutine (SinkFunctor (SourceFunctor d [(x, Bool)]) x) m x
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, MonoidNull x, AncestorFunctor a d) =>
x -> Sink m a x -> Coroutine d m x
putAll x
list Sink m (SinkFunctor (SourceFunctor d [(x, Bool)]) x) x
sink Coroutine (SinkFunctor (SourceFunctor d [(x, Bool)]) x) m x
-> Coroutine
     (SinkFunctor (SourceFunctor d [(x, Bool)]) x) m (Seq (x, Bool))
-> Coroutine
     (SinkFunctor (SourceFunctor d [(x, Bool)]) x) m (Seq (x, Bool))
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Seq (x, Bool)
-> Sink m (SinkFunctor (SourceFunctor d [(x, Bool)]) x) x
-> Coroutine
     (SinkFunctor (SourceFunctor d [(x, Bool)]) x) m (Seq (x, Bool))
get7 Seq (x, Bool)
q' Sink m (SinkFunctor (SourceFunctor d [(x, Bool)]) x) x
sink) (Seq x
-> Source m (SourceFunctor (SourceFunctor d [(x, Bool)]) x) x
-> Coroutine
     (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m (Maybe Int)
test Seq x
q)
                          case Maybe Int
mn of Maybe Int
Nothing -> Seq x -> Sink m d x -> Coroutine (SourceFunctor d [(x, Bool)]) m x
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, MonoidNull x, AncestorFunctor a d) =>
Seq x -> Sink m a x -> Coroutine d m x
putQueue Seq x
q Sink m d x
false Coroutine (SourceFunctor d [(x, Bool)]) m x
-> Coroutine (SourceFunctor d [(x, Bool)]) m ()
-> Coroutine (SourceFunctor d [(x, Bool)]) m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Seq (x, Bool) -> Coroutine (SourceFunctor d [(x, Bool)]) m ()
get0 Seq (x, Bool)
q''
                                     Just Int
0 -> Seq (x, Bool) -> Coroutine (SourceFunctor d [(x, Bool)]) m ()
get0 Seq (x, Bool)
q''
                                     Just Int
n -> Bool
-> Int
-> Seq (x, Bool)
-> Coroutine (SourceFunctor d [(x, Bool)]) m ()
get8 Bool
True Int
n Seq (x, Bool)
q''
           get7 :: Seq (x, Bool)
-> Sink m (SinkFunctor (SourceFunctor d [(x, Bool)]) x) x
-> Coroutine
     (SinkFunctor (SourceFunctor d [(x, Bool)]) x) m (Seq (x, Bool))
get7 Seq (x, Bool)
q Sink m (SinkFunctor (SourceFunctor d [(x, Bool)]) x) x
sink = do [(x, Bool)]
list <- ([(x, Bool)] -> Bool)
-> Source m (SourceFunctor d [(x, Bool)]) [(x, Bool)]
-> Coroutine
     (SinkFunctor (SourceFunctor d [(x, Bool)]) x) m [(x, Bool)]
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, FactorialMonoid x, AncestorFunctor a d) =>
(x -> Bool) -> Source m a x -> Coroutine d m x
getWhile (Bool -> (x, Bool) -> Bool
forall a b. a -> b -> a
const Bool
True ((x, Bool) -> Bool)
-> ([(x, Bool)] -> (x, Bool)) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(x, Bool)] -> (x, Bool)
forall a. [a] -> a
head) Source m (SourceFunctor d [(x, Bool)]) [(x, Bool)]
source'
                            x
rest <- x
-> Sink m (SinkFunctor (SourceFunctor d [(x, Bool)]) x) x
-> Coroutine (SinkFunctor (SourceFunctor d [(x, Bool)]) x) m x
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, MonoidNull x, AncestorFunctor a d) =>
x -> Sink m a x -> Coroutine d m x
putAll ([x] -> x
forall a. Monoid a => [a] -> a
mconcat ([x] -> x) -> [x] -> x
forall a b. (a -> b) -> a -> b
$ ((x, Bool) -> x) -> [(x, Bool)] -> [x]
forall a b. (a -> b) -> [a] -> [b]
List.map (\(x
x, Bool
_)-> x
x) [(x, Bool)]
list) Sink m (SinkFunctor (SourceFunctor d [(x, Bool)]) x) x
sink
                            let q' :: Seq (x, Bool)
q' = Seq (x, Bool)
q Seq (x, Bool) -> Seq (x, Bool) -> Seq (x, Bool)
forall a. Seq a -> Seq a -> Seq a
>< [(x, Bool)] -> Seq (x, Bool)
forall a. [a] -> Seq a
Seq.fromList [(x, Bool)]
list
                            if x -> Bool
forall m. MonoidNull m => m -> Bool
null x
rest
                               then Source m (SourceFunctor d [(x, Bool)]) [(x, Bool)]
-> Coroutine
     (SinkFunctor (SourceFunctor d [(x, Bool)]) x) m (Maybe (x, Bool))
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, AncestorFunctor a d) =>
Source m a [x] -> Coroutine d m (Maybe x)
get Source m (SourceFunctor d [(x, Bool)]) [(x, Bool)]
source' Coroutine
  (SinkFunctor (SourceFunctor d [(x, Bool)]) x) m (Maybe (x, Bool))
-> (Maybe (x, Bool)
    -> Coroutine
         (SinkFunctor (SourceFunctor d [(x, Bool)]) x) m (Seq (x, Bool)))
-> Coroutine
     (SinkFunctor (SourceFunctor d [(x, Bool)]) x) m (Seq (x, Bool))
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Coroutine
  (SinkFunctor (SourceFunctor d [(x, Bool)]) x) m (Seq (x, Bool))
-> ((x, Bool)
    -> Coroutine
         (SinkFunctor (SourceFunctor d [(x, Bool)]) x) m (Seq (x, Bool)))
-> Maybe (x, Bool)
-> Coroutine
     (SinkFunctor (SourceFunctor d [(x, Bool)]) x) m (Seq (x, Bool))
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Seq (x, Bool)
-> Coroutine
     (SinkFunctor (SourceFunctor d [(x, Bool)]) x) m (Seq (x, Bool))
forall (m :: * -> *) a. Monad m => a -> m a
return Seq (x, Bool)
q') (\(x, Bool)
x-> Seq (x, Bool)
-> Sink m (SinkFunctor (SourceFunctor d [(x, Bool)]) x) x
-> Coroutine
     (SinkFunctor (SourceFunctor d [(x, Bool)]) x) m (Seq (x, Bool))
get7 (Seq (x, Bool)
q' Seq (x, Bool) -> (x, Bool) -> Seq (x, Bool)
forall a. Seq a -> a -> Seq a
|> (x, Bool)
x) Sink m (SinkFunctor (SourceFunctor d [(x, Bool)]) x) x
sink)
                               else Seq (x, Bool)
-> Coroutine
     (SinkFunctor (SourceFunctor d [(x, Bool)]) x) m (Seq (x, Bool))
forall (m :: * -> *) a. Monad m => a -> m a
return Seq (x, Bool)
q'
           testEnd :: Seq x -> Coroutine (SourceFunctor d [(x, Bool)]) m ()
testEnd Seq x
q = do ((), Maybe Int
n) <- (Sink m (SinkFunctor (SourceFunctor d [(x, Bool)]) x) x
 -> Coroutine (SinkFunctor (SourceFunctor d [(x, Bool)]) x) m ())
-> (Source m (SourceFunctor (SourceFunctor d [(x, Bool)]) x) x
    -> Coroutine
         (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m (Maybe Int))
-> Coroutine (SourceFunctor d [(x, Bool)]) m ((), Maybe Int)
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
(Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2) -> Coroutine a m (r1, r2)
pipe (Coroutine (SinkFunctor (SourceFunctor d [(x, Bool)]) x) m ()
-> Sink m (SinkFunctor (SourceFunctor d [(x, Bool)]) x) x
-> Coroutine (SinkFunctor (SourceFunctor d [(x, Bool)]) x) m ()
forall a b. a -> b -> a
const (Coroutine (SinkFunctor (SourceFunctor d [(x, Bool)]) x) m ()
 -> Sink m (SinkFunctor (SourceFunctor d [(x, Bool)]) x) x
 -> Coroutine (SinkFunctor (SourceFunctor d [(x, Bool)]) x) m ())
-> Coroutine (SinkFunctor (SourceFunctor d [(x, Bool)]) x) m ()
-> Sink m (SinkFunctor (SourceFunctor d [(x, Bool)]) x) x
-> Coroutine (SinkFunctor (SourceFunctor d [(x, Bool)]) x) m ()
forall a b. (a -> b) -> a -> b
$ () -> Coroutine (SinkFunctor (SourceFunctor d [(x, Bool)]) x) m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()) (Seq x
-> Source m (SourceFunctor (SourceFunctor d [(x, Bool)]) x) x
-> Coroutine
     (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m (Maybe Int)
test Seq x
q)
                          case Maybe Int
n of Maybe Int
Nothing -> Seq x -> Sink m d x -> Coroutine (SourceFunctor d [(x, Bool)]) m x
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, MonoidNull x, AncestorFunctor a d) =>
Seq x -> Sink m a x -> Coroutine d m x
putQueue Seq x
q Sink m d x
false Coroutine (SourceFunctor d [(x, Bool)]) m x
-> Coroutine (SourceFunctor d [(x, Bool)]) m ()
-> Coroutine (SourceFunctor d [(x, Bool)]) m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> Coroutine (SourceFunctor d [(x, Bool)]) m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
                                    Maybe Int
_ -> () -> Coroutine (SourceFunctor d [(x, Bool)]) m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
           test :: Seq x
-> Source m (SourceFunctor (SourceFunctor d [(x, Bool)]) x) x
-> Coroutine
     (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m (Maybe Int)
test Seq x
q Source m (SourceFunctor (SourceFunctor d [(x, Bool)]) x) x
source'' = (((), Maybe Int) -> Maybe Int)
-> Coroutine
     (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m ((), Maybe Int)
-> Coroutine
     (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m (Maybe Int)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM ((), Maybe Int) -> Maybe Int
forall a b. (a, b) -> b
snd (Coroutine
   (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m ((), Maybe Int)
 -> Coroutine
      (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m (Maybe Int))
-> Coroutine
     (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m ((), Maybe Int)
-> Coroutine
     (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m (Maybe Int)
forall a b. (a -> b) -> a -> b
$
                             (Sink
   m
   (SinkFunctor
      (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
   [(x, Bool)]
 -> Coroutine
      (SinkFunctor
         (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
      m
      ())
-> (Source
      m
      (SourceFunctor
         (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
      [(x, Bool)]
    -> Coroutine
         (SourceFunctor
            (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
         m
         (Maybe Int))
-> Coroutine
     (SourceFunctor (SourceFunctor d [(x, Bool)]) x) m ((), Maybe Int)
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
(Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2) -> Coroutine a m (r1, r2)
pipe
                                (Transducer m x [(x, Bool)]
-> Source m (SourceFunctor (SourceFunctor d [(x, Bool)]) x) x
-> Sink
     m
     (SinkFunctor
        (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
     [(x, Bool)]
-> Coroutine
     (SinkFunctor
        (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
     m
     ()
forall (m :: * -> *) x y.
Transducer m x y
-> forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
   OpenTransducer m a1 a2 d x y ()
transduce (Splitter m x -> Transducer m x [(x, Bool)]
forall (m :: * -> *) x.
(Monad m, MonoidNull x) =>
Splitter m x -> Transducer m x [(x, Bool)]
splitterToMarker Splitter m x
s2) Source m (SourceFunctor (SourceFunctor d [(x, Bool)]) x) x
source'')
                                (\Source
  m
  (SourceFunctor
     (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
  [(x, Bool)]
source'''-> 
                                  let test0 :: (x, Bool)
-> Coroutine
     (SourceFunctor
        (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
     m
     (Maybe Int)
test0 (x
x, Bool
False) = Source
  m
  (SourceFunctor
     (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
  [(x, Bool)]
-> Coroutine
     (SourceFunctor
        (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
     m
     [(x, Bool)]
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, FactorialMonoid x, AncestorFunctor a d) =>
Source m a x -> Coroutine d m x
getPrime Source
  m
  (SourceFunctor
     (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
  [(x, Bool)]
source'''
                                                         Coroutine
  (SourceFunctor
     (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
  m
  [(x, Bool)]
-> Coroutine
     (SourceFunctor
        (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
     m
     (Maybe Int)
-> Coroutine
     (SourceFunctor
        (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
     m
     (Maybe Int)
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> if x -> Bool
forall m. MonoidNull m => m -> Bool
null x
x then Coroutine
  (SourceFunctor
     (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
  m
  (Maybe Int)
try0 else Maybe Int
-> Coroutine
     (SourceFunctor
        (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
     m
     (Maybe Int)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Int
forall a. Maybe a
Nothing
                                      test0 (x
_, Bool
True) = Coroutine
  (SourceFunctor
     (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
  m
  (Maybe Int)
test1
                                      test1 :: Coroutine
  (SourceFunctor
     (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
  m
  (Maybe Int)
test1 = do Seq x
-> Sink m d x
-> Coroutine
     (SourceFunctor
        (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
     m
     x
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, MonoidNull x, AncestorFunctor a d) =>
Seq x -> Sink m a x -> Coroutine d m x
putQueue Seq x
q Sink m d x
true
                                                 [(x, Bool)]
list <- ([(x, Bool)] -> Bool)
-> Source
     m
     (SourceFunctor
        (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
     [(x, Bool)]
-> Coroutine
     (SourceFunctor
        (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
     m
     [(x, Bool)]
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, FactorialMonoid x, AncestorFunctor a d) =>
(x -> Bool) -> Source m a x -> Coroutine d m x
getWhile ((x, Bool) -> Bool
forall a b. (a, b) -> b
snd ((x, Bool) -> Bool)
-> ([(x, Bool)] -> (x, Bool)) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(x, Bool)] -> (x, Bool)
forall a. [a] -> a
head) Source
  m
  (SourceFunctor
     (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
  [(x, Bool)]
source'''
                                                 let chunk :: x
chunk = [x] -> x
forall a. Monoid a => [a] -> a
mconcat (((x, Bool) -> x) -> [(x, Bool)] -> [x]
forall a b. (a -> b) -> [a] -> [b]
List.map (x, Bool) -> x
forall a b. (a, b) -> a
fst [(x, Bool)]
list)
                                                 Sink m d x
-> x
-> Coroutine
     (SourceFunctor
        (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
     m
     x
forall (m :: * -> *) (a :: * -> *) x.
Sink m a x
-> forall (d :: * -> *).
   AncestorFunctor a d =>
   x -> Coroutine d m x
putChunk Sink m d x
true x
chunk
                                                 Source
  m
  (SourceFunctor
     (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
  [(x, Bool)]
-> Coroutine
     (SourceFunctor
        (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
     m
     [(x, Bool)]
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, FactorialMonoid x, AncestorFunctor a d) =>
Source m a x -> Coroutine d m x
getPrime Source
  m
  (SourceFunctor
     (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
  [(x, Bool)]
source'''
                                                 Maybe Int
-> Coroutine
     (SourceFunctor
        (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
     m
     (Maybe Int)
forall (m :: * -> *) a. Monad m => a -> m a
return (Int -> Maybe Int
forall a. a -> Maybe a
Just (Int -> Maybe Int) -> Int -> Maybe Int
forall a b. (a -> b) -> a -> b
$ x -> Int
forall m. Factorial m => m -> Int
length x
chunk)
                                      try0 :: Coroutine
  (SourceFunctor
     (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
  m
  (Maybe Int)
try0 = Source
  m
  (SourceFunctor
     (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
  [(x, Bool)]
-> Coroutine
     (SourceFunctor
        (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
     m
     (Maybe (x, Bool))
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, AncestorFunctor a d) =>
Source m a [x] -> Coroutine d m (Maybe x)
peek Source
  m
  (SourceFunctor
     (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
  [(x, Bool)]
source''' Coroutine
  (SourceFunctor
     (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
  m
  (Maybe (x, Bool))
-> (Maybe (x, Bool)
    -> Coroutine
         (SourceFunctor
            (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
         m
         (Maybe Int))
-> Coroutine
     (SourceFunctor
        (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
     m
     (Maybe Int)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Coroutine
  (SourceFunctor
     (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
  m
  (Maybe Int)
-> ((x, Bool)
    -> Coroutine
         (SourceFunctor
            (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
         m
         (Maybe Int))
-> Maybe (x, Bool)
-> Coroutine
     (SourceFunctor
        (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
     m
     (Maybe Int)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Maybe Int
-> Coroutine
     (SourceFunctor
        (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
     m
     (Maybe Int)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Int
forall a. Maybe a
Nothing) (x, Bool)
-> Coroutine
     (SourceFunctor
        (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
     m
     (Maybe Int)
test0
                                  in Coroutine
  (SourceFunctor
     (SourceFunctor (SourceFunctor d [(x, Bool)]) x) [(x, Bool)])
  m
  (Maybe Int)
try0)
           get8 :: Bool
-> Int
-> Seq (x, Bool)
-> Coroutine (SourceFunctor d [(x, Bool)]) m ()
get8 Bool
False Int
0 Seq (x, Bool)
q = Seq (x, Bool) -> Coroutine (SourceFunctor d [(x, Bool)]) m ()
get0 Seq (x, Bool)
q
           get8 Bool
True Int
0 Seq (x, Bool)
q = Seq x
-> Seq (x, Bool) -> Coroutine (SourceFunctor d [(x, Bool)]) m ()
get2 Seq x
forall a. Seq a
Seq.empty Seq (x, Bool)
q
           get8 Bool
_ Int
n Seq (x, Bool)
q | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 =
              case Seq (x, Bool) -> ViewL (x, Bool)
forall a. Seq a -> ViewL a
Seq.viewl Seq (x, Bool)
q
              of (x
x, Bool
False) :< Seq (x, Bool)
rest | x -> Int
forall m. Factorial m => m -> Int
length x
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
n -> Seq (x, Bool) -> Coroutine (SourceFunctor d [(x, Bool)]) m ()
get0 ((Int -> x -> x
forall m. FactorialMonoid m => Int -> m -> m
drop Int
n x
x, Bool
False) (x, Bool) -> Seq (x, Bool) -> Seq (x, Bool)
forall a. a -> Seq a -> Seq a
<| Seq (x, Bool)
rest)
                                    | Bool
otherwise -> Bool
-> Int
-> Seq (x, Bool)
-> Coroutine (SourceFunctor d [(x, Bool)]) m ()
get8 Bool
False (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- x -> Int
forall m. Factorial m => m -> Int
length x
x) Seq (x, Bool)
rest
                 (x
x, Bool
True) :< Seq (x, Bool)
rest | x -> Int
forall m. Factorial m => m -> Int
length x
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
n -> Seq x
-> Seq (x, Bool) -> Coroutine (SourceFunctor d [(x, Bool)]) m ()
get2 Seq x
forall a. Seq a
Seq.empty ((Int -> x -> x
forall m. FactorialMonoid m => Int -> m -> m
drop Int
n x
x, Bool
True) (x, Bool) -> Seq (x, Bool) -> Seq (x, Bool)
forall a. a -> Seq a -> Seq a
<| Seq (x, Bool)
rest)
                                   | Bool
otherwise -> Bool
-> Int
-> Seq (x, Bool)
-> Coroutine (SourceFunctor d [(x, Bool)]) m ()
get8 Bool
True (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- x -> Int
forall m. Factorial m => m -> Int
length x
x) Seq (x, Bool)
rest
                 ViewL (x, Bool)
EmptyL -> [Char] -> Coroutine (SourceFunctor d [(x, Bool)]) m ()
forall a. HasCallStack => [Char] -> a
error [Char]
"Expecting a non-empty queue!"
       in Coroutine (SourceFunctor d [(x, Bool)]) m ()
split0)
      Coroutine d m ((), ()) -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

-- | Combinator 'between' 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.
between :: forall m x. (Monad m, FactorialMonoid x) => PairBinder m -> Splitter m x -> Splitter m x -> Splitter m x
between :: PairBinder m -> Splitter m x -> Splitter m x -> Splitter m x
between PairBinder m
binder Splitter m x
s1 Splitter m x
s2 = (forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
-> Splitter m x
forall (m :: * -> *) x b.
(Monad m, Monoid x) =>
(forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
-> Splitter m x
isolateSplitter ((forall (d :: * -> *).
  Functor d =>
  Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
 -> Splitter m x)
-> (forall (d :: * -> *).
    Functor d =>
    Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
-> Splitter m x
forall a b. (a -> b) -> a -> b
$
                       \ Source m d x
source Sink m d x
true Sink m d x
false ->
                       PairBinder m
-> (Sink m (SinkFunctor d [(x, Bool, Bool)]) [(x, Bool, Bool)]
    -> Coroutine (SinkFunctor d [(x, Bool, Bool)]) m ())
-> (Source m (SourceFunctor d [(x, Bool, Bool)]) [(x, Bool, Bool)]
    -> Coroutine (SourceFunctor d [(x, Bool, Bool)]) m ())
-> Coroutine d m ((), ())
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
PairBinder m
-> (Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2)
-> Coroutine a m (r1, r2)
pipeG PairBinder m
binder
                          (Transducer m x [(x, Bool, Bool)]
-> Source m d x
-> Sink m (SinkFunctor d [(x, Bool, Bool)]) [(x, Bool, Bool)]
-> Coroutine (SinkFunctor d [(x, Bool, Bool)]) m ()
forall (m :: * -> *) x y.
Transducer m x y
-> forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
   OpenTransducer m a1 a2 d x y ()
transduce (PairBinder m
-> Splitter m x -> Splitter m x -> Transducer m x [(x, Bool, Bool)]
forall (m :: * -> *) x.
(Monad m, FactorialMonoid x) =>
PairBinder m
-> Splitter m x -> Splitter m x -> Transducer m x [(x, Bool, Bool)]
splittersToPairMarker PairBinder m
binder Splitter m x
s1 Splitter m x
s2) Source m d x
source)
                          (let pass :: Int -> x -> Coroutine (SourceFunctor d [(x, Bool, Bool)]) m Int
pass Int
n x
x = (if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 then Sink m d x
-> x -> Coroutine (SourceFunctor d [(x, Bool, Bool)]) m x
forall (m :: * -> *) (a :: * -> *) x.
Sink m a x
-> forall (d :: * -> *).
   AncestorFunctor a d =>
   x -> Coroutine d m x
putChunk Sink m d x
true x
x else Sink m d x
-> x -> Coroutine (SourceFunctor d [(x, Bool, Bool)]) m x
forall (m :: * -> *) (a :: * -> *) x.
Sink m a x
-> forall (d :: * -> *).
   AncestorFunctor a d =>
   x -> Coroutine d m x
putChunk Sink m d x
false x
x)
                                          Coroutine (SourceFunctor d [(x, Bool, Bool)]) m x
-> Coroutine (SourceFunctor d [(x, Bool, Bool)]) m Int
-> Coroutine (SourceFunctor d [(x, Bool, Bool)]) m Int
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> Coroutine (SourceFunctor d [(x, Bool, Bool)]) m Int
forall (m :: * -> *) a. Monad m => a -> m a
return Int
n
                               pass' :: Int -> x -> Coroutine (SourceFunctor d [(x, Bool, Bool)]) m Int
pass' Int
n x
x = (if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 then Sink m d x
-> x -> Coroutine (SourceFunctor d [(x, Bool, Bool)]) m x
forall (m :: * -> *) (a :: * -> *) x.
Sink m a x
-> forall (d :: * -> *).
   AncestorFunctor a d =>
   x -> Coroutine d m x
putChunk Sink m d x
true x
x else Sink m d x
-> x -> Coroutine (SourceFunctor d [(x, Bool, Bool)]) m x
forall (m :: * -> *) (a :: * -> *) x.
Sink m a x
-> forall (d :: * -> *).
   AncestorFunctor a d =>
   x -> Coroutine d m x
putChunk Sink m d x
false x
x)
                                           Coroutine (SourceFunctor d [(x, Bool, Bool)]) m x
-> Coroutine (SourceFunctor d [(x, Bool, Bool)]) m Int
-> Coroutine (SourceFunctor d [(x, Bool, Bool)]) m Int
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> Coroutine (SourceFunctor d [(x, Bool, Bool)]) m Int
forall (m :: * -> *) a. Monad m => a -> m a
return Int
n
                               state :: Int
-> (x, Bool, Bool)
-> Coroutine (SourceFunctor d [(x, Bool, Bool)]) m Int
state Int
n (x
x, Bool
True, Bool
False) = Int -> x -> Coroutine (SourceFunctor d [(x, Bool, Bool)]) m Int
pass (Int -> Int
forall a. Enum a => a -> a
succ Int
n) x
x
                               state Int
n (x
x, Bool
False, Bool
True) = Int -> x -> Coroutine (SourceFunctor d [(x, Bool, Bool)]) m Int
pass' (Int -> Int
forall a. Enum a => a -> a
pred Int
n) x
x
                               state Int
n (x
x, Bool
True, Bool
True) = Int -> x -> Coroutine (SourceFunctor d [(x, Bool, Bool)]) m Int
pass' Int
n x
x
                               state Int
n (x
x, Bool
False, Bool
False) = Int -> x -> Coroutine (SourceFunctor d [(x, Bool, Bool)]) m Int
pass Int
n x
x
                           in (Int
 -> (x, Bool, Bool)
 -> Coroutine (SourceFunctor d [(x, Bool, Bool)]) m Int)
-> Int
-> Source m (SourceFunctor d [(x, Bool, Bool)]) [(x, Bool, Bool)]
-> Coroutine (SourceFunctor d [(x, Bool, Bool)]) m ()
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x acc.
(Monad m, AncestorFunctor a d) =>
(acc -> x -> Coroutine d m acc)
-> acc -> Source m a [x] -> Coroutine d m ()
foldMStream_ Int
-> (x, Bool, Bool)
-> Coroutine (SourceFunctor d [(x, Bool, Bool)]) m Int
state (Int
0 :: Int))
                          Coroutine d m ((), ()) -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

-- Helper functions

wrapMarkedSplitter ::
   forall m x. (Monad m, MonoidNull x) =>
   Splitter m x
   -> (forall a1 a2 a3 d. (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
                           AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
                           AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
       Source m a1 [(x, Bool)] -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
   -> Splitter m x
wrapMarkedSplitter :: Splitter m x
-> (forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
           (d :: * -> *).
    (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
     AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
     AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
    Source m a1 [(x, Bool)]
    -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ())
-> Splitter m x
wrapMarkedSplitter Splitter m x
splitter forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *) (d :: * -> *).
(AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
 AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
 AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
Source m a1 [(x, Bool)]
-> Sink m a2 x -> Sink m a3 x -> Coroutine d m ()
splitMarked = (forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
-> Splitter m x
forall (m :: * -> *) x b.
(Monad m, Monoid x) =>
(forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
-> Splitter m x
isolateSplitter ((forall (d :: * -> *).
  Functor d =>
  Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
 -> Splitter m x)
-> (forall (d :: * -> *).
    Functor d =>
    Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
-> Splitter m x
forall a b. (a -> b) -> a -> b
$ 
                                          \ Source m d x
source Sink m d x
true Sink m d x
false ->
                                          (Sink m (SinkFunctor d [(x, Bool)]) [(x, Bool)]
 -> Coroutine (SinkFunctor d [(x, Bool)]) m ())
-> (Source m (SourceFunctor d [(x, Bool)]) [(x, Bool)]
    -> Coroutine (SourceFunctor d [(x, Bool)]) m ())
-> Coroutine d m ((), ())
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
(Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2) -> Coroutine a m (r1, r2)
pipe
                                             (Transducer m x [(x, Bool)]
-> Source m d x
-> Sink m (SinkFunctor d [(x, Bool)]) [(x, Bool)]
-> Coroutine (SinkFunctor d [(x, Bool)]) m ()
forall (m :: * -> *) x y.
Transducer m x y
-> forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
   OpenTransducer m a1 a2 d x y ()
transduce (Splitter m x -> Transducer m x [(x, Bool)]
forall (m :: * -> *) x.
(Monad m, MonoidNull x) =>
Splitter m x -> Transducer m x [(x, Bool)]
splitterToMarker Splitter m x
splitter) Source m d x
source)
                                             (\Source m (SourceFunctor d [(x, Bool)]) [(x, Bool)]
source'-> Source m (SourceFunctor d [(x, Bool)]) [(x, Bool)]
-> Sink m d x
-> Sink m d x
-> Coroutine (SourceFunctor d [(x, Bool)]) m ()
forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *) (d :: * -> *).
(AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
 AncestorFunctor a1 (SinkFunctor d [(x, Bool)]),
 AncestorFunctor a2 (SourceFunctor d [(x, Bool)])) =>
Source m a1 [(x, Bool)]
-> Sink m a2 x -> Sink m a3 x -> Coroutine d m ()
splitMarked Source m (SourceFunctor d [(x, Bool)]) [(x, Bool)]
source' Sink m d x
true Sink m d x
false)
                                          Coroutine d m ((), ()) -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

splitterToMarker :: forall m x. (Monad m, MonoidNull x) => Splitter m x -> Transducer m x [(x, Bool)]
splitterToMarker :: Splitter m x -> Transducer m x [(x, Bool)]
splitterToMarker Splitter m x
s = (forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d [(x, Bool)] -> Coroutine d m ())
-> Transducer m x [(x, Bool)]
forall (m :: * -> *) x y.
(Monad m, Monoid x) =>
(forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d y -> Coroutine d m ())
-> Transducer m x y
isolateTransducer forall (d :: * -> *).
Functor d =>
Source m d x -> Sink m d [(x, Bool)] -> Coroutine d m ()
mark
   where mark :: forall d. Functor d => Source m d x -> Sink m d [(x, Bool)] -> Coroutine d m ()
         mark :: Source m d x -> Sink m d [(x, Bool)] -> Coroutine d m ()
mark Source m d x
source Sink m d [(x, Bool)]
sink = Splitter m x
-> Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ()
forall (m :: * -> *) x.
Splitter m x
-> forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
          (d :: * -> *).
   (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
    Monoid x) =>
   Source m a1 x -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ()
split Splitter m x
s Source m d x
source (Bool -> Sink m d [(x, Bool)] -> Sink m d x
forall (m :: * -> *) (a :: * -> *) x mark.
(Monad m, Monoid x) =>
mark -> Sink m a [(x, mark)] -> Sink m a x
markUpWith Bool
True Sink m d [(x, Bool)]
sink) (Bool -> Sink m d [(x, Bool)] -> Sink m d x
forall (m :: * -> *) (a :: * -> *) x mark.
(Monad m, Monoid x) =>
mark -> Sink m a [(x, mark)] -> Sink m a x
markUpWith Bool
False Sink m d [(x, Bool)]
sink)

parserToSplitter :: forall m x b. (Monad m, Monoid x) => Parser m x b -> Splitter m x
parserToSplitter :: Parser m x b -> Splitter m x
parserToSplitter Parser m x b
t = (forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
-> Splitter m x
forall (m :: * -> *) x b.
(Monad m, Monoid x) =>
(forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
-> Splitter m x
isolateSplitter ((forall (d :: * -> *).
  Functor d =>
  Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
 -> Splitter m x)
-> (forall (d :: * -> *).
    Functor d =>
    Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
-> Splitter m x
forall a b. (a -> b) -> a -> b
$ \ Source m d x
source Sink m d x
true Sink m d x
false ->
                     (Sink m (SinkFunctor d [Markup b x]) [Markup b x]
 -> Coroutine (SinkFunctor d [Markup b x]) m ())
-> (Source m (SourceFunctor d [Markup b x]) [Markup b x]
    -> Coroutine (SourceFunctor d [Markup b x]) m (((), ()), ()))
-> Coroutine d m ((), (((), ()), ()))
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
(Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2) -> Coroutine a m (r1, r2)
pipe
                        (Parser m x b
-> Source m d x
-> Sink m (SinkFunctor d [Markup b x]) [Markup b x]
-> Coroutine (SinkFunctor d [Markup b x]) m ()
forall (m :: * -> *) x y.
Transducer m x y
-> forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
   OpenTransducer m a1 a2 d x y ()
transduce Parser m x b
t Source m d x
source)
                        (\Source m (SourceFunctor d [Markup b x]) [Markup b x]
source-> 
                          (Sink
   m
   (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
   [Markup b x]
 -> Coroutine
      (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
      m
      ((), ()))
-> (Source
      m
      (SourceFunctor (SourceFunctor d [Markup b x]) [Markup b x])
      [Markup b x]
    -> Coroutine
         (SourceFunctor (SourceFunctor d [Markup b x]) [Markup b x]) m ())
-> Coroutine (SourceFunctor d [Markup b x]) m (((), ()), ())
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
(Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2) -> Coroutine a m (r1, r2)
pipe (\Sink
  m
  (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
  [Markup b x]
true'->
                                 (Sink
   m
   (SinkFunctor
      (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
      [Markup b x])
   [Markup b x]
 -> Coroutine
      (SinkFunctor
         (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
         [Markup b x])
      m
      ())
-> (Source
      m
      (SourceFunctor
         (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
         [Markup b x])
      [Markup b x]
    -> Coroutine
         (SourceFunctor
            (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
            [Markup b x])
         m
         ())
-> Coroutine
     (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
     m
     ((), ())
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
(Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2) -> Coroutine a m (r1, r2)
pipe (\Sink
  m
  (SinkFunctor
     (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
     [Markup b x])
  [Markup b x]
false'->
                                        let topLevel :: Coroutine
  (SinkFunctor
     (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
     [Markup b x])
  m
  ()
topLevel = ([Markup b x] -> Bool)
-> Source m (SourceFunctor d [Markup b x]) [Markup b x]
-> Sink
     m
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     [Markup b x]
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     ()
forall (m :: * -> *) (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *) x.
(Monad m, FactorialMonoid x, AncestorFunctor a1 d,
 AncestorFunctor a2 d) =>
(x -> Bool) -> Source m a1 x -> Sink m a2 x -> Coroutine d m ()
pourWhile [Markup b x] -> Bool
forall y x. [Markup y x] -> Bool
isContent Source m (SourceFunctor d [Markup b x]) [Markup b x]
source Sink
  m
  (SinkFunctor
     (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
     [Markup b x])
  [Markup b x]
false'
                                                       Coroutine
  (SinkFunctor
     (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
     [Markup b x])
  m
  ()
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     (Maybe (Markup b x))
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     (Maybe (Markup b x))
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Source m (SourceFunctor d [Markup b x]) [Markup b x]
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     (Maybe (Markup b x))
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, AncestorFunctor a d) =>
Source m a [x] -> Coroutine d m (Maybe x)
get Source m (SourceFunctor d [Markup b x]) [Markup b x]
source 
                                                       Coroutine
  (SinkFunctor
     (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
     [Markup b x])
  m
  (Maybe (Markup b x))
-> (Maybe (Markup b x)
    -> Coroutine
         (SinkFunctor
            (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
            [Markup b x])
         m
         ())
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Coroutine
  (SinkFunctor
     (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
     [Markup b x])
  m
  ()
-> (Markup b x
    -> Coroutine
         (SinkFunctor
            (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
            [Markup b x])
         m
         ())
-> Maybe (Markup b x)
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     ()
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (()
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()) (\Markup b x
x-> Markup b x
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     Bool
handleMarkup Markup b x
x Coroutine
  (SinkFunctor
     (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
     [Markup b x])
  m
  Bool
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     ()
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Coroutine
  (SinkFunctor
     (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
     [Markup b x])
  m
  ()
topLevel)
                                            handleMarkup :: Markup b x
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     Bool
handleMarkup (Markup p :: Boundary b
p@Point{}) = Sink m d x
-> x
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     x
forall (m :: * -> *) (a :: * -> *) x.
Sink m a x
-> forall (d :: * -> *).
   AncestorFunctor a d =>
   x -> Coroutine d m x
putChunk Sink m d x
true x
forall a. Monoid a => a
mempty Coroutine
  (SinkFunctor
     (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
     [Markup b x])
  m
  x
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     Bool
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     Bool
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Bool
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
                                            handleMarkup (Markup s :: Boundary b
s@Start{}) = Sink m d x
-> x
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     x
forall (m :: * -> *) (a :: * -> *) x.
Sink m a x
-> forall (d :: * -> *).
   AncestorFunctor a d =>
   x -> Coroutine d m x
putChunk Sink m d x
true x
forall a. Monoid a => a
mempty Coroutine
  (SinkFunctor
     (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
     [Markup b x])
  m
  x
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     ()
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Coroutine
  (SinkFunctor
     (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
     [Markup b x])
  m
  ()
handleRegion Coroutine
  (SinkFunctor
     (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
     [Markup b x])
  m
  ()
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     Bool
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     Bool
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Bool
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
                                            handleMarkup (Markup e :: Boundary b
e@End{}) = Sink m d x
-> x
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     x
forall (m :: * -> *) (a :: * -> *) x.
Sink m a x
-> forall (d :: * -> *).
   AncestorFunctor a d =>
   x -> Coroutine d m x
putChunk Sink m d x
false x
forall a. Monoid a => a
mempty Coroutine
  (SinkFunctor
     (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
     [Markup b x])
  m
  x
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     Bool
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     Bool
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Bool
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
                                            handleRegion :: Coroutine
  (SinkFunctor
     (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
     [Markup b x])
  m
  ()
handleRegion = ([Markup b x] -> Bool)
-> Source m (SourceFunctor d [Markup b x]) [Markup b x]
-> Sink
     m
     (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
     [Markup b x]
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     ()
forall (m :: * -> *) (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *) x.
(Monad m, FactorialMonoid x, AncestorFunctor a1 d,
 AncestorFunctor a2 d) =>
(x -> Bool) -> Source m a1 x -> Sink m a2 x -> Coroutine d m ()
pourWhile [Markup b x] -> Bool
forall y x. [Markup y x] -> Bool
isContent Source m (SourceFunctor d [Markup b x]) [Markup b x]
source Sink
  m
  (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
  [Markup b x]
true'
                                                           Coroutine
  (SinkFunctor
     (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
     [Markup b x])
  m
  ()
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     (Maybe (Markup b x))
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     (Maybe (Markup b x))
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Source m (SourceFunctor d [Markup b x]) [Markup b x]
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     (Maybe (Markup b x))
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, AncestorFunctor a d) =>
Source m a [x] -> Coroutine d m (Maybe x)
get Source m (SourceFunctor d [Markup b x]) [Markup b x]
source
                                                           Coroutine
  (SinkFunctor
     (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
     [Markup b x])
  m
  (Maybe (Markup b x))
-> (Maybe (Markup b x)
    -> Coroutine
         (SinkFunctor
            (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
            [Markup b x])
         m
         ())
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Coroutine
  (SinkFunctor
     (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
     [Markup b x])
  m
  ()
-> (Markup b x
    -> Coroutine
         (SinkFunctor
            (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
            [Markup b x])
         m
         ())
-> Maybe (Markup b x)
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     ()
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (()
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()) (\Markup b x
x -> Markup b x
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     Bool
handleMarkup Markup b x
x 
                                                                                        Coroutine
  (SinkFunctor
     (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
     [Markup b x])
  m
  Bool
-> (Bool
    -> Coroutine
         (SinkFunctor
            (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
            [Markup b x])
         m
         ())
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Bool
 -> Coroutine
      (SinkFunctor
         (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
         [Markup b x])
      m
      ()
 -> Coroutine
      (SinkFunctor
         (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
         [Markup b x])
      m
      ())
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     ()
-> Bool
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip Bool
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     ()
-> Coroutine
     (SinkFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Coroutine
  (SinkFunctor
     (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
     [Markup b x])
  m
  ()
handleRegion)
                                        in Coroutine
  (SinkFunctor
     (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
     [Markup b x])
  m
  ()
topLevel)
                                      (\Source
  m
  (SourceFunctor
     (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
     [Markup b x])
  [Markup b x]
src-> (Markup b x -> x)
-> Source
     m
     (SourceFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     [Markup b x]
-> Sink m d x
-> Coroutine
     (SourceFunctor
        (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
        [Markup b x])
     m
     ()
forall (m :: * -> *) (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *) x
       y.
(Monad m, Monoid y, AncestorFunctor a1 d, AncestorFunctor a2 d) =>
(x -> y) -> Source m a1 [x] -> Sink m a2 y -> Coroutine d m ()
concatMapStream (\(Content x
x)-> x
x) Source
  m
  (SourceFunctor
     (SinkFunctor (SourceFunctor d [Markup b x]) [Markup b x])
     [Markup b x])
  [Markup b x]
src Sink m d x
false))
                               (\Source
  m
  (SourceFunctor (SourceFunctor d [Markup b x]) [Markup b x])
  [Markup b x]
src-> (Markup b x -> x)
-> Source
     m
     (SourceFunctor (SourceFunctor d [Markup b x]) [Markup b x])
     [Markup b x]
-> Sink m d x
-> Coroutine
     (SourceFunctor (SourceFunctor d [Markup b x]) [Markup b x]) m ()
forall (m :: * -> *) (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *) x
       y.
(Monad m, Monoid y, AncestorFunctor a1 d, AncestorFunctor a2 d) =>
(x -> y) -> Source m a1 [x] -> Sink m a2 y -> Coroutine d m ()
concatMapStream (\(Content x
x)-> x
x) Source
  m
  (SourceFunctor (SourceFunctor d [Markup b x]) [Markup b x])
  [Markup b x]
src Sink m d x
true))
                                                           
                        Coroutine d m ((), (((), ()), ()))
-> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
   where isContent :: [Markup y x] -> Bool
isContent [Markup{}] = Bool
False
         isContent [Content{}] = Bool
True
         fromContent :: Markup y x -> x
fromContent (Content x
x) = x
x

splittersToPairMarker :: forall m x. (Monad m, FactorialMonoid x) => PairBinder m -> Splitter m x -> Splitter m x ->
                         Transducer m x [(x, Bool, Bool)]
splittersToPairMarker :: PairBinder m
-> Splitter m x -> Splitter m x -> Transducer m x [(x, Bool, Bool)]
splittersToPairMarker PairBinder m
binder Splitter m x
s1 Splitter m x
s2 =
   let synchronizeMarks :: forall a1 a2 d. (AncestorFunctor a1 d, AncestorFunctor a2 d) =>
                           Sink m a1 [(x, Bool, Bool)]
                        -> Source m a2 [((x, Bool), Bool)]
                        -> Coroutine d m (Maybe (Seq (x, Bool), Bool))
       synchronizeMarks :: Sink m a1 [(x, Bool, Bool)]
-> Source m a2 [((x, Bool), Bool)]
-> Coroutine d m (Maybe (Seq (x, Bool), Bool))
synchronizeMarks Sink m a1 [(x, Bool, Bool)]
sink Source m a2 [((x, Bool), Bool)]
source = (Maybe (Seq (x, Bool), Bool)
 -> ((x, Bool), Bool)
 -> Coroutine d m (Maybe (Seq (x, Bool), Bool)))
-> Maybe (Seq (x, Bool), Bool)
-> Source m a2 [((x, Bool), Bool)]
-> Coroutine d m (Maybe (Seq (x, Bool), Bool))
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x acc.
(Monad m, AncestorFunctor a d) =>
(acc -> x -> Coroutine d m acc)
-> acc -> Source m a [x] -> Coroutine d m acc
foldMStream Maybe (Seq (x, Bool), Bool)
-> ((x, Bool), Bool) -> Coroutine d m (Maybe (Seq (x, Bool), Bool))
handleMark Maybe (Seq (x, Bool), Bool)
forall a. Maybe a
Nothing Source m a2 [((x, Bool), Bool)]
source where
          handleMark :: Maybe (Seq (x, Bool), Bool)
-> ((x, Bool), Bool) -> Coroutine d m (Maybe (Seq (x, Bool), Bool))
handleMark Maybe (Seq (x, Bool), Bool)
Nothing (p :: (x, Bool)
p@(x
x, Bool
_), Bool
b) = Maybe (Seq (x, Bool), Bool)
-> Coroutine d m (Maybe (Seq (x, Bool), Bool))
forall (m :: * -> *) a. Monad m => a -> m a
return ((Seq (x, Bool), Bool) -> Maybe (Seq (x, Bool), Bool)
forall a. a -> Maybe a
Just ((x, Bool) -> Seq (x, Bool)
forall a. a -> Seq a
Seq.singleton (x, Bool)
p, Bool
b))
          handleMark (Just (Seq (x, Bool)
q, Bool
b)) mark :: ((x, Bool), Bool)
mark@(p :: (x, Bool)
p@(x
x, Bool
t), Bool
b')
             | Bool
b Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Bool
b' = Maybe (Seq (x, Bool), Bool)
-> Coroutine d m (Maybe (Seq (x, Bool), Bool))
forall (m :: * -> *) a. Monad m => a -> m a
return ((Seq (x, Bool), Bool) -> Maybe (Seq (x, Bool), Bool)
forall a. a -> Maybe a
Just (Seq (x, Bool)
q Seq (x, Bool) -> (x, Bool) -> Seq (x, Bool)
forall a. Seq a -> a -> Seq a
|> (x, Bool)
p, Bool
b))
             | Bool
otherwise = case Seq (x, Bool) -> ViewL (x, Bool)
forall a. Seq a -> ViewL a
Seq.viewl Seq (x, Bool)
q
                           of ViewL (x, Bool)
Seq.EmptyL -> Maybe (Seq (x, Bool), Bool)
-> ((x, Bool), Bool) -> Coroutine d m (Maybe (Seq (x, Bool), Bool))
handleMark Maybe (Seq (x, Bool), Bool)
forall a. Maybe a
Nothing ((x, Bool), Bool)
mark
                              (x
y, Bool
t') :< Seq (x, Bool)
rest -> Sink m a1 [(x, Bool, Bool)] -> (x, Bool, Bool) -> Coroutine d m ()
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, AncestorFunctor a d) =>
Sink m a [x] -> x -> Coroutine d m ()
put Sink m a1 [(x, Bool, Bool)]
sink (if Bool
b then (x
common, Bool
t', Bool
t) else (x
common, Bool
t, Bool
t'))
                                                 Coroutine d m ()
-> Coroutine d m (Maybe (Seq (x, Bool), Bool))
-> Coroutine d m (Maybe (Seq (x, Bool), Bool))
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> if Int
lx Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ly
                                                    then Maybe (Seq (x, Bool), Bool)
-> Coroutine d m (Maybe (Seq (x, Bool), Bool))
forall (m :: * -> *) a. Monad m => a -> m a
return (if Seq (x, Bool) -> Bool
forall a. Seq a -> Bool
Seq.null Seq (x, Bool)
rest then Maybe (Seq (x, Bool), Bool)
forall a. Maybe a
Nothing else (Seq (x, Bool), Bool) -> Maybe (Seq (x, Bool), Bool)
forall a. a -> Maybe a
Just (Seq (x, Bool)
rest, Bool
b))
                                                    else if Int
lx Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
ly 
                                                         then Maybe (Seq (x, Bool), Bool)
-> Coroutine d m (Maybe (Seq (x, Bool), Bool))
forall (m :: * -> *) a. Monad m => a -> m a
return ((Seq (x, Bool), Bool) -> Maybe (Seq (x, Bool), Bool)
forall a. a -> Maybe a
Just ((x
leftover, Bool
t') (x, Bool) -> Seq (x, Bool) -> Seq (x, Bool)
forall a. a -> Seq a -> Seq a
<| Seq (x, Bool)
rest, Bool
b))
                                                         else Maybe (Seq (x, Bool), Bool)
-> ((x, Bool), Bool) -> Coroutine d m (Maybe (Seq (x, Bool), Bool))
handleMark (if Seq (x, Bool) -> Bool
forall a. Seq a -> Bool
Seq.null Seq (x, Bool)
rest then Maybe (Seq (x, Bool), Bool)
forall a. Maybe a
Nothing 
                                                                          else (Seq (x, Bool), Bool) -> Maybe (Seq (x, Bool), Bool)
forall a. a -> Maybe a
Just (Seq (x, Bool)
rest, Bool
b)) 
                                                                         ((x
leftover, Bool
t), Bool
b')
                                 where lx :: Int
lx = x -> Int
forall m. Factorial m => m -> Int
length x
x
                                       ly :: Int
ly = x -> Int
forall m. Factorial m => m -> Int
length x
y
                                       (x
common, x
leftover) = if Int
lx Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
ly then (x
x, Int -> x -> x
forall m. FactorialMonoid m => Int -> m -> m
drop Int
lx x
y) else (x
y, Int -> x -> x
forall m. FactorialMonoid m => Int -> m -> m
drop Int
ly x
x)
   in (forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d [(x, Bool, Bool)] -> Coroutine d m ())
-> Transducer m x [(x, Bool, Bool)]
forall (m :: * -> *) x y.
(Monad m, Monoid x) =>
(forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d y -> Coroutine d m ())
-> Transducer m x y
isolateTransducer ((forall (d :: * -> *).
  Functor d =>
  Source m d x -> Sink m d [(x, Bool, Bool)] -> Coroutine d m ())
 -> Transducer m x [(x, Bool, Bool)])
-> (forall (d :: * -> *).
    Functor d =>
    Source m d x -> Sink m d [(x, Bool, Bool)] -> Coroutine d m ())
-> Transducer m x [(x, Bool, Bool)]
forall a b. (a -> b) -> a -> b
$
      \Source m d x
source Sink m d [(x, Bool, Bool)]
sink->
      (Sink m (SinkFunctor d [((x, Bool), Bool)]) [((x, Bool), Bool)]
 -> Coroutine (SinkFunctor d [((x, Bool), Bool)]) m ((), ()))
-> (Source
      m (SourceFunctor d [((x, Bool), Bool)]) [((x, Bool), Bool)]
    -> Coroutine
         (SourceFunctor d [((x, Bool), Bool)])
         m
         (Maybe (Seq (x, Bool), Bool)))
-> Coroutine d m (((), ()), Maybe (Seq (x, Bool), Bool))
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
(Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2) -> Coroutine a m (r1, r2)
pipe
         (\Sink m (SinkFunctor d [((x, Bool), Bool)]) [((x, Bool), Bool)]
sync-> PairBinder m
-> (forall (a' :: * -> *).
    OpenConsumer
      m
      a'
      (SourceFunctor
         (SinkFunctor (SinkFunctor d [((x, Bool), Bool)]) x) x)
      x
      ())
-> (forall (a' :: * -> *).
    OpenConsumer
      m a' (SourceFunctor (SinkFunctor d [((x, Bool), Bool)]) x) x ())
-> Source m d x
-> Coroutine (SinkFunctor d [((x, Bool), Bool)]) m ((), ())
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x r1 r2.
Monad m =>
PairBinder m
-> (forall (a' :: * -> *).
    OpenConsumer m a' (SourceFunctor (SinkFunctor d x) x) x r1)
-> (forall (a' :: * -> *).
    OpenConsumer m a' (SourceFunctor d x) x r2)
-> OpenConsumer m a d x (r1, r2)
teeConsumers PairBinder m
binder
                     (\Source m a' x
source1-> Transducer m x [(x, Bool)]
-> Source m a' x
-> Sink m (SinkFunctor d [((x, Bool), Bool)]) [(x, Bool)]
-> Coroutine
     (SourceFunctor
        (SinkFunctor (SinkFunctor d [((x, Bool), Bool)]) x) x)
     m
     ()
forall (m :: * -> *) x y.
Transducer m x y
-> forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
   OpenTransducer m a1 a2 d x y ()
transduce (Splitter m x -> Transducer m x [(x, Bool)]
forall (m :: * -> *) x.
(Monad m, MonoidNull x) =>
Splitter m x -> Transducer m x [(x, Bool)]
splitterToMarker Splitter m x
s1) Source m a' x
source1 (((x, Bool) -> ((x, Bool), Bool))
-> Sink m (SinkFunctor d [((x, Bool), Bool)]) [((x, Bool), Bool)]
-> Sink m (SinkFunctor d [((x, Bool), Bool)]) [(x, Bool)]
forall (m :: * -> *) (a :: * -> *) x y.
Monad m =>
(x -> y) -> Sink m a [y] -> Sink m a [x]
mapSink (\(x, Bool)
x-> ((x, Bool)
x, Bool
True)) Sink m (SinkFunctor d [((x, Bool), Bool)]) [((x, Bool), Bool)]
sync))
                     (\Source m a' x
source2-> Transducer m x [(x, Bool)]
-> Source m a' x
-> Sink m (SinkFunctor d [((x, Bool), Bool)]) [(x, Bool)]
-> Coroutine
     (SourceFunctor (SinkFunctor d [((x, Bool), Bool)]) x) m ()
forall (m :: * -> *) x y.
Transducer m x y
-> forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
   OpenTransducer m a1 a2 d x y ()
transduce (Splitter m x -> Transducer m x [(x, Bool)]
forall (m :: * -> *) x.
(Monad m, MonoidNull x) =>
Splitter m x -> Transducer m x [(x, Bool)]
splitterToMarker Splitter m x
s2) Source m a' x
source2 (((x, Bool) -> ((x, Bool), Bool))
-> Sink m (SinkFunctor d [((x, Bool), Bool)]) [((x, Bool), Bool)]
-> Sink m (SinkFunctor d [((x, Bool), Bool)]) [(x, Bool)]
forall (m :: * -> *) (a :: * -> *) x y.
Monad m =>
(x -> y) -> Sink m a [y] -> Sink m a [x]
mapSink (\(x, Bool)
x-> ((x, Bool)
x, Bool
False)) Sink m (SinkFunctor d [((x, Bool), Bool)]) [((x, Bool), Bool)]
sync))
                     Source m d x
source)
         (Sink m d [(x, Bool, Bool)]
-> Source
     m (SourceFunctor d [((x, Bool), Bool)]) [((x, Bool), Bool)]
-> Coroutine
     (SourceFunctor d [((x, Bool), Bool)])
     m
     (Maybe (Seq (x, Bool), Bool))
forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
(AncestorFunctor a1 d, AncestorFunctor a2 d) =>
Sink m a1 [(x, Bool, Bool)]
-> Source m a2 [((x, Bool), Bool)]
-> Coroutine d m (Maybe (Seq (x, Bool), Bool))
synchronizeMarks Sink m d [(x, Bool, Bool)]
sink)
      Coroutine d m (((), ()), Maybe (Seq (x, Bool), Bool))
-> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

zipSplittersWith :: forall m x. (Monad m, FactorialMonoid x) =>
                    (Bool -> Bool -> Bool) -> PairBinder m -> Splitter m x -> Splitter m x -> Splitter m x
zipSplittersWith :: (Bool -> Bool -> Bool)
-> PairBinder m -> Splitter m x -> Splitter m x -> Splitter m x
zipSplittersWith Bool -> Bool -> Bool
f PairBinder m
binder Splitter m x
s1 Splitter m x
s2
   = (forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
-> Splitter m x
forall (m :: * -> *) x b.
(Monad m, Monoid x) =>
(forall (d :: * -> *).
 Functor d =>
 Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
-> Splitter m x
isolateSplitter ((forall (d :: * -> *).
  Functor d =>
  Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
 -> Splitter m x)
-> (forall (d :: * -> *).
    Functor d =>
    Source m d x -> Sink m d x -> Sink m d x -> Coroutine d m ())
-> Splitter m x
forall a b. (a -> b) -> a -> b
$ \ Source m d x
source Sink m d x
true Sink m d x
false ->
     PairBinder m
-> (Sink m (SinkFunctor d [(x, Bool, Bool)]) [(x, Bool, Bool)]
    -> Coroutine (SinkFunctor d [(x, Bool, Bool)]) m ())
-> (Source m (SourceFunctor d [(x, Bool, Bool)]) [(x, Bool, Bool)]
    -> Coroutine (SourceFunctor d [(x, Bool, Bool)]) m ())
-> Coroutine d m ((), ())
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
PairBinder m
-> (Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2)
-> Coroutine a m (r1, r2)
pipeG PairBinder m
binder
        (Transducer m x [(x, Bool, Bool)]
-> Source m d x
-> Sink m (SinkFunctor d [(x, Bool, Bool)]) [(x, Bool, Bool)]
-> Coroutine (SinkFunctor d [(x, Bool, Bool)]) m ()
forall (m :: * -> *) x y.
Transducer m x y
-> forall (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *).
   OpenTransducer m a1 a2 d x y ()
transduce (PairBinder m
-> Splitter m x -> Splitter m x -> Transducer m x [(x, Bool, Bool)]
forall (m :: * -> *) x.
(Monad m, FactorialMonoid x) =>
PairBinder m
-> Splitter m x -> Splitter m x -> Transducer m x [(x, Bool, Bool)]
splittersToPairMarker PairBinder m
binder Splitter m x
s1 Splitter m x
s2) Source m d x
source)
        (([(x, Bool, Bool)]
 -> Coroutine (SourceFunctor d [(x, Bool, Bool)]) m x)
-> Source m (SourceFunctor d [(x, Bool, Bool)]) [(x, Bool, Bool)]
-> Coroutine (SourceFunctor d [(x, Bool, Bool)]) m ()
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x r.
(Monad m, FactorialMonoid x, AncestorFunctor a d) =>
(x -> Coroutine d m r) -> Source m a x -> Coroutine d m ()
mapMStream_ (\[(x
x, Bool
t1, Bool
t2)]-> if Bool -> Bool -> Bool
f Bool
t1 Bool
t2 then Sink m d x
-> x -> Coroutine (SourceFunctor d [(x, Bool, Bool)]) m x
forall (m :: * -> *) (a :: * -> *) x.
Sink m a x
-> forall (d :: * -> *).
   AncestorFunctor a d =>
   x -> Coroutine d m x
putChunk Sink m d x
true x
x else Sink m d x
-> x -> Coroutine (SourceFunctor d [(x, Bool, Bool)]) m x
forall (m :: * -> *) (a :: * -> *) x.
Sink m a x
-> forall (d :: * -> *).
   AncestorFunctor a d =>
   x -> Coroutine d m x
putChunk Sink m d x
false x
x))
     Coroutine d m ((), ()) -> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

-- | 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 :: (Monad m, MonoidNull x, AncestorFunctor a d, AncestorFunctor a (SinkFunctor d x), 
               AncestorFunctor a (SinkFunctor (SinkFunctor d x) [(x, Bool)])) =>
              Source m a [(x, Bool)] ->
              (Bool -> Source m (SourceFunctor d x) x -> Coroutine (SourceFunctor d x) m r) ->
              Coroutine d m ()
groupMarks :: Source m a [(x, Bool)]
-> (Bool
    -> Source m (SourceFunctor d x) x
    -> Coroutine (SourceFunctor d x) m r)
-> Coroutine d m ()
groupMarks Source m a [(x, Bool)]
source Bool
-> Source m (SourceFunctor d x) x
-> Coroutine (SourceFunctor d x) m r
getConsumer = Source m a [(x, Bool)] -> Coroutine d m (Maybe (x, Bool))
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, AncestorFunctor a d) =>
Source m a [x] -> Coroutine d m (Maybe x)
peek Source m a [(x, Bool)]
source Coroutine d m (Maybe (x, Bool))
-> (Maybe (x, Bool) -> Coroutine d m ()) -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Maybe (x, Bool) -> Coroutine d m ()
loop
   where loop :: Maybe (x, Bool) -> Coroutine d m ()
loop = Coroutine d m ()
-> ((x, Bool) -> Coroutine d m ())
-> Maybe (x, Bool)
-> Coroutine d m ()
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (() -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()) ((Coroutine d m (Maybe (x, Bool), r)
-> ((Maybe (x, Bool), r) -> Coroutine d m ()) -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Maybe (x, Bool) -> Coroutine d m ()
loop (Maybe (x, Bool) -> Coroutine d m ())
-> ((Maybe (x, Bool), r) -> Maybe (x, Bool))
-> (Maybe (x, Bool), r)
-> Coroutine d m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe (x, Bool), r) -> Maybe (x, Bool)
forall a b. (a, b) -> a
fst) (Coroutine d m (Maybe (x, Bool), r) -> Coroutine d m ())
-> ((x, Bool) -> Coroutine d m (Maybe (x, Bool), r))
-> (x, Bool)
-> Coroutine d m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (x, Bool) -> Coroutine d m (Maybe (x, Bool), r)
startContent)
         startContent :: (x, Bool) -> Coroutine d m (Maybe (x, Bool), r)
startContent (x
_, Bool
False) = (Sink m (SinkFunctor d x) x
 -> Coroutine (SinkFunctor d x) m (Maybe (x, Bool)))
-> (Source m (SourceFunctor d x) x
    -> Coroutine (SourceFunctor d x) m r)
-> Coroutine d m (Maybe (x, Bool), r)
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
(Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2) -> Coroutine a m (r1, r2)
pipe (Bool
-> Sink m (SinkFunctor d x) x
-> Coroutine (SinkFunctor d x) m (Maybe (x, Bool))
next Bool
False) (Bool
-> Source m (SourceFunctor d x) x
-> Coroutine (SourceFunctor d x) m r
getConsumer Bool
False)
         startContent (x
_, Bool
True) = (Sink m (SinkFunctor d x) x
 -> Coroutine (SinkFunctor d x) m (Maybe (x, Bool)))
-> (Source m (SourceFunctor d x) x
    -> Coroutine (SourceFunctor d x) m r)
-> Coroutine d m (Maybe (x, Bool), r)
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
(Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2) -> Coroutine a m (r1, r2)
pipe (Bool
-> Sink m (SinkFunctor d x) x
-> Coroutine (SinkFunctor d x) m (Maybe (x, Bool))
next Bool
True) (Bool
-> Source m (SourceFunctor d x) x
-> Coroutine (SourceFunctor d x) m r
getConsumer Bool
True)
         next :: Bool
-> Sink m (SinkFunctor d x) x
-> Coroutine (SinkFunctor d x) m (Maybe (x, Bool))
next Bool
t Sink m (SinkFunctor d x) x
sink = (Maybe [(x, Bool)] -> Maybe (x, Bool))
-> Coroutine (SinkFunctor d x) m (Maybe [(x, Bool)])
-> Coroutine (SinkFunctor d x) m (Maybe (x, Bool))
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (([(x, Bool)] -> (x, Bool)) -> Maybe [(x, Bool)] -> Maybe (x, Bool)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [(x, Bool)] -> (x, Bool)
forall a. [a] -> a
head) (Coroutine (SinkFunctor d x) m (Maybe [(x, Bool)])
 -> Coroutine (SinkFunctor d x) m (Maybe (x, Bool)))
-> Coroutine (SinkFunctor d x) m (Maybe [(x, Bool)])
-> Coroutine (SinkFunctor d x) m (Maybe (x, Bool))
forall a b. (a -> b) -> a -> b
$
                       ([(x, Bool)] -> Bool)
-> Source m a [(x, Bool)]
-> Sink m (SinkFunctor d x) [(x, Bool)]
-> Coroutine (SinkFunctor d x) m (Maybe [(x, Bool)])
forall (m :: * -> *) (a1 :: * -> *) (a2 :: * -> *) (d :: * -> *) x.
(Monad m, FactorialMonoid x, AncestorFunctor a1 d,
 AncestorFunctor a2 d) =>
(x -> Bool)
-> Source m a1 x -> Sink m a2 x -> Coroutine d m (Maybe x)
pourUntil ((\(x
_, Bool
t')-> Bool
t Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
/= Bool
t') ((x, Bool) -> Bool)
-> ([(x, Bool)] -> (x, Bool)) -> [(x, Bool)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(x, Bool)] -> (x, Bool)
forall a. [a] -> a
head) Source m a [(x, Bool)]
source (Sink m (SinkFunctor d x) x -> Sink m (SinkFunctor d x) [(x, Bool)]
forall (m :: * -> *) (a :: * -> *) x mark.
(Monad m, MonoidNull x) =>
Sink m a x -> Sink m a [(x, mark)]
markDown Sink m (SinkFunctor d x) x
sink)

splitInput :: forall m a1 a2 a3 d x. (Monad m, Monoid x, 
                                      AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d) =>
              Splitter m x -> Source m a1 x -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ()
splitInput :: Splitter m x
-> Source m a1 x -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ()
splitInput Splitter m x
splitter Source m a1 x
source Sink m a2 x
true Sink m a3 x
false = Splitter m x
-> Source m a1 x -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ()
forall (m :: * -> *) x.
Splitter m x
-> forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
          (d :: * -> *).
   (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
    Monoid x) =>
   Source m a1 x -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ()
split Splitter m x
splitter Source m a1 x
source Sink m a2 x
true Sink m a3 x
false

findsTrueIn :: forall m a d x. (Monad m, MonoidNull x, AncestorFunctor a d)
               => Splitter m x -> Source m a x -> Coroutine d m Bool
findsTrueIn :: Splitter m x -> Source m a x -> Coroutine d m Bool
findsTrueIn Splitter m x
splitter Source m a x
source = (Sink m (SinkFunctor d x) x -> Coroutine (SinkFunctor d x) m ())
-> (Source m (SourceFunctor d x) x
    -> Coroutine (SourceFunctor d x) m Bool)
-> Coroutine d m ((), Bool)
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
(Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2) -> Coroutine a m (r1, r2)
pipe
                                 (\Sink m (SinkFunctor d x) x
testTrue-> Splitter m x
-> Source m d x
-> Sink m (SinkFunctor d x) x
-> Sink m d x
-> Coroutine (SinkFunctor d x) m ()
forall (m :: * -> *) x.
Splitter m x
-> forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
          (d :: * -> *).
   (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
    Monoid x) =>
   Source m a1 x -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ()
split Splitter m x
splitter (Source m a x -> Source m d x
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, AncestorFunctor a d) =>
Source m a x -> Source m d x
liftSource Source m a x
source :: Source m d x)
                                                 Sink m (SinkFunctor d x) x
testTrue
                                                 (Sink m d x
forall (m :: * -> *) (a :: * -> *) x.
(Monad m, Monoid x) =>
Sink m a x
nullSink :: Sink m d x))
                                 (Reader x (Bool -> Bool) Bool
-> Source m (SourceFunctor d x) x
-> Coroutine (SourceFunctor d x) m Bool
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x y.
(Monad m, Monoid x, AncestorFunctor a d) =>
Reader x (y -> y) y -> Source m a x -> Coroutine d m y
getRead Reader x (Bool -> Bool) Bool
forall x. MonoidNull x => Reader x (Bool -> Bool) Bool
readEof)
                              Coroutine d m ((), Bool)
-> (((), Bool) -> Coroutine d m Bool) -> Coroutine d m Bool
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \((), Bool
eof)-> Bool -> Coroutine d m Bool
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> Coroutine d m Bool) -> Bool -> Coroutine d m Bool
forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not Bool
eof

findsFalseIn :: forall m a d x. (Monad m, MonoidNull x, AncestorFunctor a d) =>
                Splitter m x -> Source m a x -> Coroutine d m Bool
findsFalseIn :: Splitter m x -> Source m a x -> Coroutine d m Bool
findsFalseIn Splitter m x
splitter Source m a x
source = (Sink m (SinkFunctor d x) x -> Coroutine (SinkFunctor d x) m ())
-> (Source m (SourceFunctor d x) x
    -> Coroutine (SourceFunctor d x) m Bool)
-> Coroutine d m ((), Bool)
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
(Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2) -> Coroutine a m (r1, r2)
pipe
                                  (\Sink m (SinkFunctor d x) x
testFalse-> Splitter m x
-> Source m d x
-> Sink m d x
-> Sink m (SinkFunctor d x) x
-> Coroutine (SinkFunctor d x) m ()
forall (m :: * -> *) x.
Splitter m x
-> forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
          (d :: * -> *).
   (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
    Monoid x) =>
   Source m a1 x -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ()
split Splitter m x
splitter (Source m a x -> Source m d x
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, AncestorFunctor a d) =>
Source m a x -> Source m d x
liftSource Source m a x
source :: Source m d x)
                                                   (Sink m d x
forall (m :: * -> *) (a :: * -> *) x.
(Monad m, Monoid x) =>
Sink m a x
nullSink :: Sink m d x)
                                                   Sink m (SinkFunctor d x) x
testFalse)
                                  (Reader x (Bool -> Bool) Bool
-> Source m (SourceFunctor d x) x
-> Coroutine (SourceFunctor d x) m Bool
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x y.
(Monad m, Monoid x, AncestorFunctor a d) =>
Reader x (y -> y) y -> Source m a x -> Coroutine d m y
getRead Reader x (Bool -> Bool) Bool
forall x. MonoidNull x => Reader x (Bool -> Bool) Bool
readEof)
                               Coroutine d m ((), Bool)
-> (((), Bool) -> Coroutine d m Bool) -> Coroutine d m Bool
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \((), Bool
eof)-> Bool -> Coroutine d m Bool
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> Coroutine d m Bool) -> Bool -> Coroutine d m Bool
forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not Bool
eof

readEof :: forall x. MonoidNull x => Reader x (Bool -> Bool) Bool
readEof :: Reader x (Bool -> Bool) Bool
readEof x
x | x -> Bool
forall m. MonoidNull m => m -> Bool
null x
x = Reader x (Bool -> Bool) Bool
-> Bool -> Reading x (Bool -> Bool) Bool
forall x py y. Reader x py y -> y -> Reading x py y
Deferred Reader x (Bool -> Bool) Bool
forall x. MonoidNull x => Reader x (Bool -> Bool) Bool
readEof Bool
True
          | Bool
otherwise = x -> Bool -> Reading x (Bool -> Bool) Bool
forall x py y. x -> y -> Reading x py y
Final x
x Bool
False

teeConsumers :: forall m a d x r1 r2. Monad m => 
                PairBinder m 
                -> (forall a'. OpenConsumer m a' (SourceFunctor (SinkFunctor d x) x) x r1)
                -> (forall a'. OpenConsumer m a' (SourceFunctor d x) x r2)
                -> OpenConsumer m a d x (r1, r2)
teeConsumers :: PairBinder m
-> (forall (a' :: * -> *).
    OpenConsumer m a' (SourceFunctor (SinkFunctor d x) x) x r1)
-> (forall (a' :: * -> *).
    OpenConsumer m a' (SourceFunctor d x) x r2)
-> OpenConsumer m a d x (r1, r2)
teeConsumers PairBinder m
binder forall (a' :: * -> *).
OpenConsumer m a' (SourceFunctor (SinkFunctor d x) x) x r1
c1 forall (a' :: * -> *). OpenConsumer m a' (SourceFunctor d x) x r2
c2 Source m a x
source = PairBinder m
-> (Sink m (SinkFunctor d x) x -> Coroutine (SinkFunctor d x) m r1)
-> (Source m (SourceFunctor d x) x
    -> Coroutine (SourceFunctor d x) m r2)
-> Coroutine d m (r1, r2)
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
PairBinder m
-> (Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2)
-> Coroutine a m (r1, r2)
pipeG PairBinder m
binder Sink m (SinkFunctor d x) x -> Coroutine (SinkFunctor d x) m r1
consume1 Source m (SourceFunctor d x) x
-> Coroutine (SourceFunctor d x) m r2
forall (a' :: * -> *). OpenConsumer m a' (SourceFunctor d x) x r2
c2
   where consume1 :: Sink m (SinkFunctor d x) x -> Coroutine (SinkFunctor d x) m r1
consume1 Sink m (SinkFunctor d x) x
sink = (((), r1) -> r1)
-> Coroutine (SinkFunctor d x) m ((), r1)
-> Coroutine (SinkFunctor d x) m r1
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM ((), r1) -> r1
forall a b. (a, b) -> b
snd (Coroutine (SinkFunctor d x) m ((), r1)
 -> Coroutine (SinkFunctor d x) m r1)
-> Coroutine (SinkFunctor d x) m ((), r1)
-> Coroutine (SinkFunctor d x) m r1
forall a b. (a -> b) -> a -> b
$ (Sink m (SinkFunctor (SinkFunctor d x) x) x
 -> Coroutine (SinkFunctor (SinkFunctor d x) x) m ())
-> (Source m (SourceFunctor (SinkFunctor d x) x) x
    -> Coroutine (SourceFunctor (SinkFunctor d x) x) m r1)
-> Coroutine (SinkFunctor d x) m ((), r1)
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
(Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2) -> Coroutine a m (r1, r2)
pipe (Source m d x
-> Sink m (SinkFunctor d x) x
-> Sink m (SinkFunctor (SinkFunctor d x) x) x
-> Coroutine (SinkFunctor (SinkFunctor d x) x) m ()
forall (m :: * -> *) (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
       (d :: * -> *) x.
(Monad m, Monoid x, AncestorFunctor a1 d, AncestorFunctor a2 d,
 AncestorFunctor a3 d) =>
Source m a1 x -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ()
tee Source m d x
source' Sink m (SinkFunctor d x) x
sink) Source m (SourceFunctor (SinkFunctor d x) x) x
-> Coroutine (SourceFunctor (SinkFunctor d x) x) m r1
forall (a' :: * -> *).
OpenConsumer m a' (SourceFunctor (SinkFunctor d x) x) x r1
c1
         source' :: Source m d x
         source' :: Source m d x
source' = Source m a x -> Source m d x
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, AncestorFunctor a d) =>
Source m a x -> Source m d x
liftSource Source m a x
source

-- | 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 :: forall m a d d1 x. (Monad m, Monoid x, d1 ~ SinkFunctor d x, AncestorFunctor a d) =>
                         PairBinder m -> Splitter m x -> Source m a x ->
                         (Source m (SourceFunctor d1 x) x -> Coroutine (SourceFunctor d1 x) m ()) ->
                         (Source m (SourceFunctor d x) x -> Coroutine (SourceFunctor d x) m ()) ->
                         Coroutine d m ()
splitInputToConsumers :: PairBinder m
-> Splitter m x
-> Source m a x
-> (Source m (SourceFunctor d1 x) x
    -> Coroutine (SourceFunctor d1 x) m ())
-> (Source m (SourceFunctor d x) x
    -> Coroutine (SourceFunctor d x) m ())
-> Coroutine d m ()
splitInputToConsumers PairBinder m
binder Splitter m x
s Source m a x
source Source m (SourceFunctor d1 x) x
-> Coroutine (SourceFunctor d1 x) m ()
trueConsumer Source m (SourceFunctor d x) x
-> Coroutine (SourceFunctor d x) m ()
falseConsumer
   = PairBinder m
-> (Sink m (SinkFunctor d x) x
    -> Coroutine (SinkFunctor d x) m ((), ()))
-> (Source m (SourceFunctor d x) x
    -> Coroutine (SourceFunctor d x) m ())
-> Coroutine d m (((), ()), ())
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
PairBinder m
-> (Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2)
-> Coroutine a m (r1, r2)
pipeG PairBinder m
binder
        (\Sink m (SinkFunctor d x) x
false-> PairBinder m
-> (Sink m (SinkFunctor (SinkFunctor d x) x) x
    -> Coroutine (SinkFunctor (SinkFunctor d x) x) m ())
-> (Source m (SourceFunctor d1 x) x
    -> Coroutine (SourceFunctor d1 x) m ())
-> Coroutine (SinkFunctor d x) m ((), ())
forall (m :: * -> *) (a :: * -> *) (a1 :: * -> *) (a2 :: * -> *) x
       r1 r2.
(Monad m, Monoid x, Functor a, a1 ~ SinkFunctor a x,
 a2 ~ SourceFunctor a x) =>
PairBinder m
-> (Sink m a1 x -> Coroutine a1 m r1)
-> (Source m a2 x -> Coroutine a2 m r2)
-> Coroutine a m (r1, r2)
pipeG PairBinder m
binder
                     (\Sink m (SinkFunctor (SinkFunctor d x) x) x
true-> Splitter m x
-> Source m d x
-> Sink m (SinkFunctor (SinkFunctor d x) x) x
-> Sink m (SinkFunctor d x) x
-> Coroutine (SinkFunctor (SinkFunctor d x) x) m ()
forall (m :: * -> *) x.
Splitter m x
-> forall (a1 :: * -> *) (a2 :: * -> *) (a3 :: * -> *)
          (d :: * -> *).
   (AncestorFunctor a1 d, AncestorFunctor a2 d, AncestorFunctor a3 d,
    Monoid x) =>
   Source m a1 x -> Sink m a2 x -> Sink m a3 x -> Coroutine d m ()
split Splitter m x
s Source m d x
source' Sink m (SinkFunctor (SinkFunctor d x) x) x
true Sink m (SinkFunctor d x) x
false)
                     Source m (SourceFunctor d1 x) x
-> Coroutine (SourceFunctor d1 x) m ()
trueConsumer)
        Source m (SourceFunctor d x) x
-> Coroutine (SourceFunctor d x) m ()
falseConsumer
     Coroutine d m (((), ()), ())
-> Coroutine d m () -> Coroutine d m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> Coroutine d m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
   where source' :: Source m d x
         source' :: Source m d x
source' = Source m a x -> Source m d x
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, AncestorFunctor a d) =>
Source m a x -> Source m d x
liftSource Source m a x
source

-- | Like 'putAll', except it puts the contents of the given 'Data.Sequence.Seq' into the sink.
putQueue :: forall m a d x. (Monad m, MonoidNull x, AncestorFunctor a d) => Seq x -> Sink m a x -> Coroutine d m x
putQueue :: Seq x -> Sink m a x -> Coroutine d m x
putQueue Seq x
q Sink m a x
sink = x -> Sink m a x -> Coroutine d m x
forall (m :: * -> *) (a :: * -> *) (d :: * -> *) x.
(Monad m, MonoidNull x, AncestorFunctor a d) =>
x -> Sink m a x -> Coroutine d m x
putAll ([x] -> x
forall a. Monoid a => [a] -> a
mconcat ([x] -> x) -> [x] -> x
forall a b. (a -> b) -> a -> b
$ ViewL x -> [x]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Foldable.toList (ViewL x -> [x]) -> ViewL x -> [x]
forall a b. (a -> b) -> a -> b
$ Seq x -> ViewL x
forall a. Seq a -> ViewL a
Seq.viewl Seq x
q) Sink m a x
sink