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].
