Skip to content

Conversation

@roberth
Copy link
Contributor

@roberth roberth commented Nov 13, 2025

Hi @HuwCampbell, it's been a while, but I think I've figured this one out, based loosely on your idea of changing ReadM.

My realisation was that both your concerns, breaking ReadM and users' ability to do crazy stuff with it, could be addressed by means of a tiered system of ConsumeM and the original ReadM.
This separates the concerns nicely and lets us hide the undesired operations that the ConsumeM would otherwise provide.

This way you can have a straightforward but powerful core, as well as a limited user interface that only exposes whatever we deem sensible argument handling strategies. For now that's statically fixed sets of 0, 1 or 2 arguments, where of course only the 2-argument case is truly new. The 0 and 1 just fall out of the design naturally, and could perhaps play a role in someone's code if they have a use for abstracting over their options' arity somewhat.

Anyway, this is now entirely "simple" Haskell if that's the right term for it. No new extensions.

My only worry in terms of code complexity is the extra indirections due to the Internal module. I suppose what we could do instead is inline that into the ConsumeA module, "hide" its symbols there and drop the tests for it. They're not too interesting anyway. Then we can get rid of some type parameters and type aliases.
I'd be happy to do that if you prefer.

Example:

  parser :: Parser (String, String)
  parser = consumeOption (consumePair str (metavar "KEY") str (metavar "VALUE"))
    (long "set" <> help "Set a configuration value")

->

     Available options:
       --set KEY VALUE          Set a configuration value

References

This takes into account the following considerations:

- Use a typical parser type; a very useful tool for implementing
  this functionality.
- Do not expose the full parser type, because we generally don't
  want programs to implement atypical CLIs.
- Leave ReadM as is. Instead, implement this new feature as an
  addition that clearly does not affect existing behavior, and
  creates a good separation of concerns.
As well as some other tweaks
Turns out CReader is not idiomatic, so more work is to be done.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Parsers that consume multiple arguments

1 participant