1
votes

I think I'm misunderstanding <|> in parsec - I have an input stream that contains either a bunch of as in one representation or a bunch of as 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.

1
In the first example, it does many $ try $ a1, then does many $ try $ a2, both always execute. In the second, it does many $ try $ a1, then if that fails it executes many $ try $ a2. - bheklilr

1 Answers

2
votes

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.