
apfelmus wrote:
Andrew Coppin wrote:
OK, I'm stuck now. :-S
1. How do I run the input through parseRLE and *then* through parseHuffmanTable?
2. How do I get parseHuffmanPayload to continue from where parseRLE left off? (How do I get parseRLE to not parse the entire input, for that matter...)
Well, there's no way to do that with a monolithic parseRLE since it will parse the input to the bitter end. But assuming that
parseRLE = concat `liftM` many parseRLEBlock
parseRLEBlock :: Parser Word8 [Word8]
you can write an RLE parser that repeatedly parses RLE blocks until it has read equal or more than n Word8s
parseRLEAmount n | n <= 0 = return [] | otherwise = do xs <- parseRLEBlock xss <- parseRLEAmount (n - length xs) return (xs ++ xss)
To parse a huffman table, run the actual parser on the result of parseRLEAmount:
parseHuffmanHeader = runParser parseHuffmanTable `liftM` parseRLEAmount (2^8)
The use of lifeM is *inspired* - I would never have thought of writing it infix! Still, while this does solve the issue at hand, I'm still left wondering whether there's any way to make this work for some arbitrary parser. parseHuffmanTable always uses exactly N bytes of input, but what if it didn't? What if it was impossible to tell how many bytes it should read without actually running it? How would you implement that? Nice a since general solution exist?