Dear guys,

Thanks! chainr and chainl are exactly what I was looking for. I did something along the lines of

andParser = ExpAnd <$> ((stringParser <|> andParser) <* "and") <*> (stringParser <|> andParser)

I can see now, why that wouldn't work!

Regards,
Hon

On 6 October 2016 at 01:05, Leonard Wörteler <leo@woerteler.de> wrote:


Am 05.10.2016 um 14:32 schrieb Lian Hung Hon:
Given

data Expression = ExpToken String | ExpAnd Expression Expression

How to write an attoparsec parser that parses this example:

"a" and "b" and "c"

into

ExpAnd (ExpToken "a") (ExpAnd (ExpToken "b") (ExpToken "c"))?

You can re-implement `chainr1` from Parsec as follows:

    chainr1 :: Parser a -> Parser (a -> a -> a) -> Parser a
    chainr1 p op = scan
      where
        scan   = p >>= rest
        rest x = op <*> pure x <*> scan <|> return x

Then you just plug in your parsers for variables and the `and` operator. Working example attached.

-- Leo