I wrote a Conduit
that generates a stream of elements. These elements are of a custom type (say, Record
), and each of them contains some structured data. I am trying to write a downstream Conduit
that parses Record
-stream.
Interestingly, there are a lot of concepts in the parsec package in my application . For example, I sometimes expect to many
write that a satisfy
particular predicate is on a line, or maybe I expect that exactly one instance of a particular record will appear immediately after one other specific record. So I was looking for ways to override these functions for Conduit
, for example,
satisfy :: Monad m => (r -> Bool) -> ConduitM r a m rp
many :: Monad m => ConduitM r a m rp -> ConduitM r a m [rp]
sepBy :: Monad m => ConduitM r a m rp -> ConduitM r a m sep -> ConduitM r a m [rp]
which specializes in them in the above example
satisfy :: (Record -> Bool) -> ConduitM Record () IO Record
many :: ConduitM Record () IO Record -> ConduitM Record () IO [Record]
sepBy :: ConduitM Record () IO Record -> ConduitM Record () IO Record -> ConduitM Record a IO [Record]
so that I can write neat code, for example:
parserC :: Sink Record IO (Record, [Record], [Record])
parserC = do
red <- satisfy isRecordRed
blues <- many $ satisfy isRecordBlue
assorted <- anyRecord `sepBy` satisfy isRecordPurple
return (red, blues, assorted)
Now, looking at the parsec documentation, I found that these functions are actually defined for a very general class Stream
. Therefore, I think that connection to the package should be possible. However, one difficulty I came across is that the function parse
works with the whole thread s
. Is there a way to parse in a parsecT
streaming way?
source
share