I think I'm misunderstanding <|>
in parsec - I have an input stream that contains either a bunch of a
s in one representation or a bunch of a
s in another representation. I would expect the following to functions to be equivalent (given that the input is the form I said, and I have verified that it is):
foo = do
...
a1s <- many $ try $ a1
a2s <- many $ try $ a2
return $ a1s ++ a2s
versus
foo = do
...
as <- (many $ try $ a1) <|> (many $ try $ a2)
return as
What could be going wrong? The first function works on my input, the second function fails, saying unexpected a2, expecting a1.
When you give a sequence of a2 to the latter parser, the first many
matches and returns an empty list, so it doesn't try to match against the second many
.
You can use many1
instead.
foo = do
...
as <- many1 a1 <|> many a2
return as
In this case, the many1
fails when you give a sequence of a2, and the many
matches against the input.