Search code examples
haskellhandleparsec

Is there an instance Stream Handle IO Char for Text.Parsec.Stream?


I'm parsing a fairly large file, and I'd like to periodically update a progress bar to indicate how much of it I've parsed thus far.

The most direct way I can think to do this is use ParsecT as a monad transformer for IO so I can lift printing the progres bar updates, and use a Handle as a stream provider so I can check the progress using hFileSize and hTell.

So that means I need an instance Stream Handle IO Char. It shouldn't be hard to roll my own (using hGetChar) but I figured I'd see if one existed already, to handle any unforseen issues (like whether I'll need to insert some buffering for speed).


Solution

  • One hack would be to check the size of the file ahead of time. Then, as you're parsing, check the SourcePos that parsec makes available to see how far you've gotten. The downside to this is that if you want to track actual byte count (so that you can use the file system's knowledge of file size to avoid traversing the file twice), you will have to reimplement the base parsers by hand using tokenPrim. The parser combinators shouldn't need to be reimplemented, though.

    Alternately, you can traverse the file twice and use the line count (computing during the first traversal) as an estimate of how far you've gotten.