[Haskell-cafe] Re: Parsec lookahead and <|>

Daniel Fischer daniel.is.fischer at web.de
Thu Aug 20 15:52:45 EDT 2009


Apologies to Christian for the double post, didn't look at the To-field.
Am Thursday 20 August 2009 20:21:30 schrieben Sie:
> Daniel Fischer wrote:
> > Am Donnerstag 20 August 2009 13:44:15 schrieb Martijn van Steenbergen:
> >> Goedemiddag café,
> >>
> >> Consider the following function, using parsec-3.0.0:
> >>> la :: Parsec String () (Maybe Char)
> >>> la = lookAhead (optionMaybe anyChar)
> >>
> >> *Lookahead> parseTest (char 'a' <|> char 'b') "a"
> >> 'a'
> >> *Lookahead> parseTest (char 'a' <|> char 'b') "b"
> >> 'b'
> >> *Lookahead> parseTest (la *> char 'a' <|> char 'b') "a"
> >> 'a'
> >> *Lookahead> parseTest (la *> char 'a' <|> char 'b') "b"
> >> parse error at (line 1, column 2):
> >> unexpected "b"
> >> expecting "a"
> >>
> >> The first three work fine and as expected, but the fourth example fails
> >> where I would expect success. I know <|> won't try the rhs if the lhs
> >> consumed input, but lookAhead's documentation promises not to consume
> >> any input. Is this a bug in Parsec or am I missing something?
> >
> > Bad bug in Parsec (from the beginning, the same happens in parsec-2), I'd
> > say.
>
> I'd say, its a feature. lookAhead returns whatever its argument returns.
>  So in this case it returns "Consumed" without consuming.

In that case, the comment

"lookAhead p parses p without consuming any input."

from the parsec-3 docs is highly misleading.

But lookAhead returning Consumed is not only counterintuitive, try

parseTest (many la) "a"

for a nice memory bomb.

>
> You can always wrap around a "try" to force the alternative:
>
>   parseTest (try (la >> char 'a') <|> char 'b') "b"
>
> Cheers Christian
>
> Maybe it should have been:
>
>   la >> (char 'a' <|> char 'b')
>
> in the first place.




More information about the Haskell-Cafe mailing list