parser-combinators
parser-combinators copied to clipboard
[Proposal] Add manyEndingWith
Hi! may you consider adding manyEndingWith
(name subject to change)? The code would be like:
-- copy paste from manyTill_. It takes a parser p and a finalizer end. It returns the list of
-- all parsed elements with p and(!) the element parsed with end
manyEndingWith :: MonadPlus m => m a -> m a -> m [a]
manyEndingWith p end = go id
where
go f = do
done <- optional end
case done of
Just done' -> return $ f [done']
Nothing -> do
x <- p
go (f . (x :))
This is particulary usefull when parsing the eof
. For example in megaparsec
this code will hang forever
-- This hangs forever. But I don't know why.
my_parser = (True <$ symbol ";") <|> (True <$ symbol "|") <|> (False <$ eof)
parse (many my_parser) "" ";|"
> hangs forever...
Ideally the last example could return Right [True, True, False]
, but I think it isn't possible with the current combinators. With the new combinator the above example could be rewritten as
my_parser = (True <$ symbol ";") <|> (True <$ symbol "|")
parse (manyEnding my_parser (False <$ eof)) "" ";|"
> Right [True, True, False]
I know manyTill_
exists but, It returns m ([a], end)
, forcing you to append end
at the end of the list (if a ~ end
), which is inefficient for linked lists.