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 <lo...@pan.me> 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 haskell-pipe...@googlegroups.com.
>>> To post to this group, send email to haskel...@googlegroups.com.
>>>
>>>
>>>

-- 
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 haskell-pipes+unsubscr...@googlegroups.com.
To post to this group, send email to haskell-pipes@googlegroups.com.

Reply via email to