如何在 haskell 选项中进行模式匹配.适用于记录类型



我使用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 = []}来拦截这个案子。我认为占位符"_"实际上可以用来匹配"[]",尽管我希望它只匹配"某物"而不是空字符串。因此,我的第一个问题是如何创建一个模式来匹配非空字符串?

我的第二个问题是如何添加代码以打印出使用信息?现在,它仅在我使用"-h"时打印它。我想在命令行中没有提供选项时打印它。

由于String只是[Char]的类型同义词,你可以在非空字符串上与模式_:_匹配,即一个非空列表,有一个 head 元素_(无论什么)和一个尾列表_(不管什么)。

因此,您可能有三种情况:

  • Options {xml = _:_, eut = []}xml已设置,eut未设置
  • Options {xml = [], eut = _:_}eut已设置,xml未设置
  • _ :其余的(要么都不设置,要么两者都设置)

或者,您可以使用多路if

Options{..} <- execParser ...
if | not (null xml) && null eot -> ...
   | not (null eot) && null xml -> ...
   | otherwise -> error ...

最新更新