[Haskell-cafe] Re: Abstraction leak
apfelmus
apfelmus at quantentunnel.de
Sun Jul 1 09:12:56 EDT 2007
Andrew Coppin wrote:
> OK, well I don't know the Parsec types and function names off the top of
> my head, but suppose I have the following:
>
> runParser :: Parser a b -> [a] -> Either ParseError b
>
> parseHuffmanTable :: [x] -> Parser Word8 (HuffmanTable x)
>
> parseHuffmanPayload :: HuffmanTable x -> Parser Word8 [x]
>
> parseRLE :: Parser Word8 [Word8]
>
> Now, if I want to just do without the RLE bit, I can do
>
> parseHuffman :: [x] -> Parser Word8 x
> parseHuffman xs = do
> table <- parseHuffmanTable xs
> parseHuffmanPayload table
>
> But if I want to add an RLE layer to just the Huffman table... erm...
> 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)
Regards,
apfelmus
More information about the Haskell-Cafe
mailing list