1

Now I'w working on my university homework and one of the tasks is to add string literals support in my Haskell parser of dummy programming language (named "Hi").

I solved this task with that code:

parseString = do
   res <- char '\"' *> manyTill charLiteral (char '\"')
   return (HiValueString (pack res))

But I don't understand how to solve this task using between? I want to make code of this parser shorter, like:

parseString = do
   res <- between '\"' '\"'
   return (HiValueString (pack res))
ppv
  • 21
  • 3

1 Answers1

2

between takes parsers, not characters, as arguments. You need two (trivial) parsers that each parse '"', as well as the parser for what you want between the quotes.

parseString = do
    let quoted = between (char '"') (char '"')
    res <- quoted (many charLiteral)
    return (HiValueString (pack res))

Not really any shorter (even ignoring the extra variable binding I introduce for readability), but it lets you separate more cleanly the quoting from the thing being quoted.

Regardless, you can use <$> to replace your >>= followed immediately by return.

parseString = (HiValueString . pack) <$> (char '"' *> manyTill charLiteral (char '"'))

or

parseString = (HiValueString . pack) <$> (between (char '"') (char '"') (many charLiteral))
chepner
  • 497,756
  • 71
  • 530
  • 681