Search code examples
parsinghaskellparsec

Chain two parsers in Haskell (Parsec)


Parsec provides an operator to choose between two parsers:

(<|>)
  :: Text.Parsec.Prim.ParsecT s u m a
     -> Text.Parsec.Prim.ParsecT s u m a
     -> Text.Parsec.Prim.ParsecT s u m a

Is there a similar function to chain two parsers? I didn't find one with the same signature using Hoogle.


As an example, let's say I want to parse any word optionally followed by a single digit. My first idea was to use >> but it doesn't seem to work.

parser = many1 letter >> optional (fmap pure digit)

I used fmap pure in order to convert the digit to an actual string and thus match the parsed type of many1 letter. I don't know if it is useful.


Solution

  • Try this:

    parser = (++) <$> many1 letter <*> option "" (fmap pure digit)
    

    This is equivalent to:

    parser = pure (++) <*> many1 letter <*> option "" (fmap pure digit)
    

    option [] (fmap pure digit) return empty string if the parser digit have failed and a string from one digital char otherwise.

    You can also use do-notation for more readable code:

    parser = do
        s1 <- many1 letter
        s2 <- option "" (fmap pure digit)
        return (s1 ++ s2)