Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Proposal] Add manyEndingWith #56

Open
lsmor opened this issue Jun 19, 2023 · 2 comments
Open

[Proposal] Add manyEndingWith #56

lsmor opened this issue Jun 19, 2023 · 2 comments

Comments

@lsmor
Copy link

lsmor commented Jun 19, 2023

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.

@lsmor
Copy link
Author

lsmor commented Feb 16, 2024

Hi there!!

Are you accepting PRs? from the conversation in #31 It seems that you prefer to keep the library smaller :).

@mrkkrp
Copy link
Owner

mrkkrp commented Feb 16, 2024

This case seems to be quite particular. I agree that adding an element to the end of the linked list in inefficient, but then there could be many ways to avoid building a list at all (e.g. by counting the number of symbols matched before eof instead of building a list), or to avoid eof being represented by an element in the list. All this seems to belong to the area of creativity that concerns the code of a particular parser, not a library of common combinators.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants