[Haskell-cafe] Re: A parsec question

Ben Franksen ben.franksen at online.de
Wed Sep 29 13:10:22 EDT 2010


Ben Franksen wrote:
>> import Control.Applicative ((*>),(<*))
>> import Text.Parsec
>> import Text.Parsec.Char
>> block p = char '{' *> p <* char '}'
>> parser = block (many digit)
>> main = parseTest parser "{123a}"
> 
> gives the output
> 
>   parse error at (line 1, column 5):
>   unexpected "a"
>   expecting "}"
> 
> Note the last line mentions only '}'. I would rather like to see
> 
>   expecting "}" or digit
> 
> since the parser could very well accept another digit here.
> 
> (1) What is the reason for this behaviour?
> (2) Is there another combinator that behaves as I would like?
> (3) Otherwise, how do I write one myself?

I just saw that Christian Maeder answered a similar question recently. I
tried his suggestion of using manyTill and bingo:

> {-# LANGUAGE NoMonomorphismRestriction #-}
> import Control.Applicative ((*>),(<*))
> import Text.Parsec
> block p = char '{' *> p <* char '}'
> parser = block (manyTill digit (char '}'))
> main = parseTest parser "{123a}"

gives

  parse error at (line 1, column 5):
  unexpected "a"
  expecting "}" or digit

So far so good. I wonder whether this parser is as efficient as the original
one. Also, this style is less modular, as I have to mention the terminator
in two places. Is there a non-greedy variant of 'many' so that modularity
gets restored and efficiency is not lost?

Cheers
Ben



More information about the Haskell-Cafe mailing list