
brian wrote:
I want to use Parsec to parse NNTP data coming to me from a handle I get from connectTo. One unworkable approach I tried is to get a lazy String from the handle with hGetContents.
It seems there is another approach, which is neither unsafe nor imperative. It relies neither on lazy IO nor on Handles. The input data can come from a file or from an embedded (e.g., chunk-encoded or encrypted) stream; the depth of embedding is arbitrary. The approach is naturally incremental. It permits IO interleaving without any unsafe operations. The approach is algebraic and declarative. The approach is the topic of the DEFUN08 talk in the morning of September 27. The code is already available http://okmij.org/ftp/Haskell/Iteratee/ The file http://okmij.org/ftp/Haskell/Iteratee/README.dr describes the other files in that directory. The running example is reading lines (terminated by CR, LF or CRLF) from a file descriptor and then from the chunk-encoded body. The main example illustrates multiplexing across two file descriptors and the full IO interleaving. The same line parser is used to process data from the file descriptor stream and from the embedded chunk-encoded stream, which is incrementally decoded. The whole code is Haskell98. It is not optimized at all and has no GHC-specific pragmas and options. The code has been used for the Wc program demonstrated yesterday. Perhaps the code answers the questions posed yesterday by Don. Hopefully one can see several composition modes for the iteratees and enumerators; enumerators are just iteratee transformers and compose as such. Incidentally, the operator ==<< is flipped >>==. Just like =<< (which is flipped >>=), it is like a `call-by-value application'. When a call-by-value language evaluates the application (f e), the argument e and all of its effects are executed first. Because of this analogy, I'm tempted to rename <<== into something like $. or .$ (or perhaps <$>, although the latter is taken).