My code doesn't stream properly - it forces consumption of the original 
producer before outputting anything. :(

On Wednesday, 24 August 2016 04:24:03 UTC+10, Louis Pan wrote:
>
> I managed to convert between `P.Producer (ZipList a) m r` and `ZipList 
> (P.Producer a m ()` using the StateT trick used in Pipes.Parse
>
> Does the following code make sense? Am I breaking any laws?
>
> import Control.Applicative
> import Control.Monad.Trans.Class
> import Control.Monad.Trans.State.Strict
> import qualified Pipes as P
> import qualified Pipes.Lift as PL
>
> -- ZipList Traversable is only in 4.9.0.0
> sequenceAZipList :: Applicative f => ZipList (f a) -> f (ZipList a)
> sequenceAZipList xs = ZipList <$> sequenceA (getZipList xs)
>
> -- | Similar to Pipes.Parse.Parser, except it stores a ZipList of 
> Producers.
> type ZipParser a m r = forall x . StateT (ZipList (P.Producer a m x)) m r
>
> -- | Draw one element from each underlying Producer, returning 'Nothing' 
> if any of the producers are empty
> drawZ :: Monad m => ZipParser a m (Maybe (ZipList a))
> drawZ = do
>   ps <- get
>   rs <- lift (sequenceAZipList (P.next <$> ps))
>   case sequenceAZipList rs of
>     Left _ -> pure Nothing
>     Right rs' -> do
>       put $ snd <$> rs'
>       pure . Just $ fst <$> rs'
>
> -- | Push back a Ziplist element onto the underlying ZipList of Producers
> unDrawZ :: Monad m => ZipList a -> ZipParser a m ()
> unDrawZ as = modify (\ps -> appendA <$> ps <*> as)
>  where
>   appendA p a = do
>     r <- p
>     P.yield a
>     pure r
>
> toZipList :: Monad m => P.Producer (ZipList a) m r -> m (ZipList 
> (P.Producer a m ()))
> toZipList p = execStateT (toZipParser p) (pure (pure ()))
>  where
>   toZipParser :: Monad m => P.Producer (ZipList a) m r -> ZipParser a m r
>   toZipParser p' = do
>     r <- lift $ P.next p'
>
>
> On Tuesday, 23 August 2016 15:01:54 UTC+10, Louis Pan wrote:
>>
>> Sorry, could you please elaborate? I'm a bit slow.
>>
>> How do I use Control.Foldl.Fold to convert `Pipes a b m r` into `Pipes 
>> (ZipList a) (ZipList b) m r` ?
>>
>>
>> On Tuesday, 23 August 2016 13:20:24 UTC+10, Gabriel Gonzalez wrote:
>>>
>>> I would do what you're already doing with `Control.Foldl.Fold`.  That's 
>>> the approach I usually recommend for this.
>>>
>>> On Aug 22, 2016, at 6:45 PM, Louis Pan <[email protected]> wrote:
>>>
>>> One approach I can think of is the use Pipes.Concurrent to manually 
>>> split the ZipList and then combine then results. Is there a nicer way?
>>>
>>> On Tuesday, 23 August 2016 11:35:50 UTC+10, Louis Pan wrote:
>>>>
>>>> Say I have a `Pipes a b m r` called 'p'.
>>>>
>>>> How do I convert it to a `Pipes (ZipList a) (ZipList b) m r`?
>>>> That is, I want to apply the pipe 'p' and apply zip-wise to an input 
>>>> ziplist, without losing the state of each pipe in the ziplist.
>>>>
>>>> The reason I want this, is that I want to run multiple attoparsec 
>>>> parsers in parallel in one pass of a file.
>>>>
>>>> My approach for this is to use Control.Foldl  to combine the attoparsec 
>>>> parsers into a `Control.Foldl.Fold ByteString [PartialParseResult]`, then 
>>>> convert it (using Control.Foldl.purely Pipes.Prelude.scan) to a `Pipe 
>>>> ByteString [PartialParseResult]`
>>>>
>>>> My other requirement is that I want to look at intermediate parser 
>>>> output (eg. each line of a file as it's parsed), in order to summarise 
>>>> each 
>>>> line, in a stateful way as I'm keeping track of the current line number.
>>>>
>>>> My approach for this is to use Control.Foldl.Fold for the summary 
>>>> logic, and then convert it to a pipe. I am able to create a `Pipe 
>>>> PartialParseResult AnalysisResult m r` for this.
>>>>
>>>> However, how do I connect a `Pipe ByteString [PartialParseResult] m r` 
>>>> to a `Pipe PartialParseResult AnalysisResult m r`?
>>>>
>>>> Regards,
>>>>
>>>> Louis
>>>>
>>>>
>>> -- 
>>> You received this message because you are subscribed to the Google 
>>> Groups "Haskell Pipes" group.
>>> To unsubscribe from this group and stop receiving emails from it, send 
>>> an email to [email protected].
>>> To post to this group, send email to [email protected].
>>>
>>>
>>>

-- 
You received this message because you are subscribed to the Google Groups 
"Haskell Pipes" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].

Reply via email to