你的问题比你想象的要复杂。当前optparse-applicative
的 API 不应该用于这种情况。因此,您可能想要更改处理 CLI 参数的方式或切换到另一个 CLI 解析库。但我将描述实现目标的最接近的方法。
首先,您需要阅读其他两个 SO 问题:
1. 如何使用 optparse-applicative 解析 Maybe
2. 是否可以有一个带有多个参数的 optparse-applicative 选项?
从第一个问题开始,您就知道如何使用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
.