我使用的是optparse-applicative,我希望能够解析命令行参数,例如:
$ ./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开关后面的参数。
那么我如何编写这个参数解析器呢?
发布于 2016-01-20 07:34:18
除了命令之外,optparse-applicative遵循getopts约定:命令行上的单个参数对应于单个选项参数。它甚至更严格一点,因为getopts将允许具有相同开关的多个选项:
./program-with-getopts -i input1 -i input2 -i input3所以没有“魔法”可以帮助你立即使用你的程序
./program-with-magic -a 1 2 3 -b foo bar crux因为编写Options.Applicative.Parser时没有考虑到这一点;它也与POSIX公约相矛盾,在这种情况下,选项可以是一个参数,也可以是零参数。
但是,您可以从两个方面解决这个问题:或者像在-a中那样多次使用getopts,或者告诉用户使用引号:
./program-as-above -a "1 2 3" -b "foo bar crux"
# works already with your program!要启用一个选项的多次使用,您必须使用many (如果它们是可选的)或some (如果不是)。您甚至可以组合这两种变体:
multiString desc = concat <$> some single
where single = option (str >>= parseStringList) desc
config :: Parser MyOptions
config = MyOptions
<$> multiString (short 'a' <> long "aFiles" <> help "Use quotes/multiple")
<*> multiString (short 'b' <> long "bFiles" <> help "Use quotes/multiple")它使您能够使用
./program-with-posix-style -a 1 -a "2 3" -b foo -b "foo bar"但是我所知道的任何解析库都不支持您建议的样式,因为自由参数的位置可能是不明确的。如果您真的想使用-a 1 2 3 -b foo bar crux,您必须自己解析参数。
https://stackoverflow.com/questions/34889516
复制相似问题