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))
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))