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.
Hi! may you consider adding
manyEndingWith(name subject to change)? The code would be like:This is particulary usefull when parsing the
eof. For example inmegaparsecthis code will hang foreverIdeally 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 asI know
manyTill_exists but, It returnsm ([a], end), forcing you to appendendat the end of the list (ifa ~ end), which is inefficient for linked lists.