Ich verwende optparse-applicative
und ich möchte in der Lage sein, um Kommandozeilenparameter wie zu analysieren:optparse-applicative Option mit mehreren Werten
$ ./program -a file1 file2 -b filea fileb
dh zwei Schalter, von denen beide mehrere Argumente annehmen kann .
So habe ich einen Datentyp für meine Optionen, die wie folgt aussieht:
data MyOptions = MyOptions {
aFiles :: [String]
, bFiles :: [String] }
Und dann ein Parser
wie folgt aus:
config :: Parser MyOptions
config = MyOptions
<$> option (str >>= parseStringList)
(short 'a' <> long "aFiles")
<*> option (str >>= parseStringList)
(short 'b' <> long "bFiles")
parseStringList :: Monad m => String -> m [String]
parseStringList = return . words
Dieser Ansatz scheitert, dass es das erwartete Ergebnis geben Wenn nur ein Argument für jeden Schalter bereitgestellt wird, aber wenn Sie ein zweites Argument angeben, erhalten Sie "Ungültiges Argument" für dieses zweite Argument.
Ich fragte mich, ob ich könnte kludge es durch vorgeben, dass ich vier Optionen wollte: ein boolescher Schalter (d. H.); eine Liste von Strings; ein anderer boolescher Schalter (d. h. -b
); und eine andere Liste von Strings. Also änderte ich meine Datentyp:
data MyOptions = MyOptions {
isA :: Bool
, aFiles :: [String]
, isB :: Bool
, bFiles :: [String] }
und modifiziert dann den Parser wie folgt aus:
config :: Parser MyOptions
config = MyOptions
<$> switch
(short 'a' <> long "aFiles")
<*> many (argument str (metavar "FILE"))
<*> switch
(short 'b' <> long "bFiles")
<*> many (argument str (metavar "FILE"))
Dieses Mal mit den many
und argument
combinators anstelle eines expliziten Parser für eine String-Liste.
Aber jetzt die erste many (argument str (metavar "FILE"))
verbraucht alle der Argumente, einschließlich der folgenden die -b
Schalter.
Also, wie kann ich diesen Argumenten Parser schreiben?
Die freien Argumente wären nicht mehrdeutig, wenn die Argumente für "-a" so eingeschränkt wären, dass sie nicht mit "-" beginnen würden. – rampion