Ваш вопрос оказался более сложным, чем вы думаете. Текущий optparse-applicative
API не должен использоваться с такими случаями. Поэтому вы, вероятно, захотите изменить способ обработки аргументов CLI или перейти на другую библиотеку разбора CLI. Но я расскажу о наиболее близком пути достижения вашей цели.
Во-первых, вам нужно прочитать две другие SO вопросы:
1.How to parse Maybe with optparse-applicative
2.Is it possible to have a optparse-applicative option with several parameters?
С первого вопроса вы знаете, как разобрать необязательные аргументы с помощью функции optional
, Со второго вы узнаете некоторые проблемы с разбором нескольких аргументов. Поэтому я напишу несколько подходов, как вы можете решить эту проблему.
1. Наивный и некрасиво
Вы можете представить пару строк в качестве пары String
типа и использовать только наивные show
этой пары. Вот код:
mainParser :: Parser Arguments
mainParser = Arguments
<$> switch (long "someflag" <> help "Some argument flag")
<*> optional (uncurry SubArguments <$>
(option auto $ long "subarguments" <> help "some desc"))
getArguments :: IO Arguments
getArguments = do
(res,()) <- simpleOptions "main example" "" "desc" mainParser empty
return res
main :: IO()
main = getArguments >>= print
Вот результат ghci
:
ghci> :run main --someflag --subarguments "(\"a\",\"b\")"
Arguments True (Just (SubArguments "a" "b"))
2. Менее наивный
От ответа на второй вопрос, который вы должны узнать, как передать несколько аргументов внутри одной строки. Вот код для синтаксического анализа:
subArgParser :: ReadM SubArguments
subArgParser = do
input <- str
-- no error checking, don't actually do this
let [a,b] = words input
pure $ SubArguments a b
mainParser :: Parser Arguments
mainParser = Arguments
<$> switch (long "someflag" <> help "Some argument flag")
<*> optional (option subArgParser $ long "subarguments" <> help "some desc")
А вот ghci
выход:
ghci> :run main --someflag --subarguments "x yyy"
Arguments True (Just (SubArguments "x" "yyy"))
Единственная плохая вещь, во втором растворе, что проверка ошибок отсутствует. Таким образом, вы можете использовать другую библиотеку разбора общего назначения, например megaparsec
, а не только let [a,b] = words input
.
Я попросил автора библиотеки. Это невозможно (на данный момент). См. Андер Паоло Каприотти – Pieter