Я использую optparse-applicative
, и я хотел бы, чтобы иметь возможность анализировать аргументы командной строки, такие как:optparse-аппликативен вариант с несколькими значениями
$ ./program -a file1 file2 -b filea fileb
т.е. два коммутаторов, оба из которых может принимать несколько аргументов ,
Так у меня есть тип данных для моих вариантов который выглядит следующим образом:
data MyOptions = MyOptions {
aFiles :: [String]
, bFiles :: [String] }
а затем Parser
так:
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
Этот подход не в том, что он даст ожидаемый результат когда для каждого коммутатора предоставляется только один аргумент, но если вы укажете второй аргумент, вы получите «Недопустимый аргумент» для этого второго аргумента.
Я задавался вопросом, могу ли я его убить, притворившись, что мне нужны четыре варианта: булевский переключатель (т. Е. -a
); список строк; другой логический переключатель (т. е. -b
); и еще один список строк. Таким образом, я изменил свой тип данных:
data MyOptions = MyOptions {
isA :: Bool
, aFiles :: [String]
, isB :: Bool
, bFiles :: [String] }
И затем изменил парсер так:
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"))
На этот раз с помощью many
и argument
комбинаторов вместо явного парсер для списка строк.
Но теперь первые many (argument str (metavar "FILE"))
потребляет всех аргументов, в том числе следующих после -b
.
Итак, как я могу написать этот парсер аргументов?
свободные аргументы не были бы двусмысленными, если бы аргументы '-a' были ограничены, чтобы не начинаться с' -'. – rampion