我使用Options.Applicative
来处理haskell命令行,我的选项记录类型如下:
data Options = Options { xml :: String
,eut :: String
} deriving (Show)
options :: Parser Options
options = Options
<$> strOption ( short 'x'
<> long "xml"
<> metavar "XMLFILE"
<> value []
<> help "GCCXML file for parsing" )
<*> strOption ( short 'e'
<> long "eut"
<> metavar "PATH_2_EUT"
<> value []
<> help "EUT Json filepath for parsing" )
然后在我的haskell主代码中,我有:
main :: IO ()
main = do
options <- execParser parseOpts
case options of
Options {xml = [], eut = []} -> putStrLn "use -h to print usage info"
-- xml option
Options {xml = _, eut = []} -> parseXML $ xml options
-- eut option
Options {xml = [], eut = _} -> genMeta $ eut options
-- no matching
_ -> putStrLn "use -h to print usage info"
where
parseOpts = info (helper <*> options)
( fullDesc
<> progDesc "Given GCCXML file, generate EUT json and test meta files"
<> header "map2meta - Generate test meta files" )
我的目的是为"-x"
或"-e"
进行处理。我通过使用模式Options {xml = _, eut = []}
来匹配命令行具有"-x"
但没有"-e"
的情况来实现此目的,而Options {xml = [], eut = _ }
则匹配命令行具有"-e"
的情况但没有"-x"
。但是,当我在没有任何选项的情况下运行程序时,似乎Options {xml = _ , eut = [] }
匹配。所以我添加了Options {xml = [], eut = []}
来拦截这种情况。我认为占位符'_'实际上可以用来匹配'[]',虽然我希望它只匹配'something'而不是空字符串。因此,我的第一个问题是如何创建一个匹配非空字符串的模式?
我的第二个问题是如何添加代码以打印出使用信息?现在,它只在我使用"-h"
时打印出来。我想在命令行中没有提供选项时打印它。
答案 0 :(得分:1)
由于String
只是[Char]
的类型同义词,因此您可以使用模式_:_
匹配非空字符串,即带有头元素的非空列表{{ 1}}(无论如何)和尾部列表_
(无论如何)。
所以你可以有三种情况:
_
:Options {xml = _:_, eut = []}
已设置,xml
未设置eut
:Options {xml = [], eut = _:_}
已设置,eut
未设置xml
:所有其余的(两者都未设置,或两者都是)或者,您可以选择multi-way if
:
_