我有复杂的命令行选项,如
data Arguments = Arguments Bool (Maybe SubArguments)
data SubArguments = SubArguments String String
我想用标志解析这些子参数:
programName --someflag --subarguments "a" "b"
programName --someflag
我已经
了subArgParser = SubArguments <$> argument str <*> argument str
mainParser = MainArgs <$> switch
(long "someflag"
<> help "Some argument flag")
<*> ???
(long "subarguments"
<> help "Sub arguments"
我需要在???
写什么答案 0 :(得分:2)
你的问题比你想象的要复杂得多。当前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
。
答案 1 :(得分:1)
这是不可能的,至少不是直接的。您可能会发现一些适合您的间接编码,但我不确定。选项采用参数,而不是subsparsers。你可以有subparser,但它们是由“命令”引入的,而不是一个选项(即没有前导--
)。