Created
January 25, 2017 21:40
-
-
Save max630/5d64247eff2e1fc0a112d1008d8f134b to your computer and use it in GitHub Desktop.
optparse-applicative question
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
> {-# LANGUAGE TupleSections #-} | |
> import Control.Applicative | |
> import Data.List (isPrefixOf) | |
> import Options.Applicative | |
> prefixReader expect = eitherReader $ prefixReader' expect | |
> prefixReader' expect s = if expect `isPrefixOf` s | |
> then Right s | |
> else Left ("not(\"" ++ s ++ "\" `isPrefixOf` \"" ++ expect ++ "\")") | |
> notPrefixReader expect = eitherReader $ notPrefixReader' expect | |
> notPrefixReader' expect s = if not (expect `isPrefixOf` s) | |
> then Right s | |
> else Left ("\"" ++ s ++ "\" `isPrefixOf` \"" ++ expect ++ "\"") | |
> test o = execParserPure (prefs mempty) (info o mempty) | |
The needed syntax to parse is "program [A] [B]", so user can specify | |
either both A B, or only A, or only B, or none. "A" has some complicated | |
syntax which canot be mistaken with "B". It would seem that it is | |
straightforward: | |
> op = (,) | |
> <$> optional (argument (notPrefixReader "b") (metavar "A")) | |
> <*> optional (argument (prefixReader "b") (metavar "B")) | |
but here is an issue: I do not want blindly assume that any argument | |
which does not has correct "A" format is decided to be "B". Because it | |
can be just some mistype. I would rather accept it for A roughly and | |
then fail overall parsing if I cannot match it specifically. Apparently, | |
optparse-applicative doe not seem to allow me that - if I accepted | |
argument in reader it is returned succesfully. I can only check it again | |
after parsing is done, which makes me construct the failed parsing | |
manually if I want to print nice "Usage" | |
So I tried to do this: | |
> op2 = ((Nothing,) . Just) <$> argument (notPrefixReader "a") (metavar "B") | |
> <|> (,) | |
> <$> optional (argument (prefixReader "a") (metavar "A")) | |
> <*> optional (argument (prefixReader "b") (metavar "B")) | |
That is, I try to explicitly check the case of "prog B" with some rough | |
check and if it fails resort to the full case. But the failure of first | |
branch seems to fail the whole parsing. How could I treat the failure to | |
parse argument as "mempty" to try another branch? | |
Or, alternatively, how could I make "op" fail whole parsing if first | |
argument pass rough check 'notPrefixReader "b"' but fails correct check | |
'prefixReader "a"'? |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment