在Haskell中解析命令行参数

4
我目前正在做一个需要解析命令行参数的项目。到目前为止,我一直在遵循this tutorial,这非常有帮助,但是我无法弄清如何在参数中返回一个变量(--author=example)。我也不知道为什么parse [] = getContents会导致错误(我必须取消注释它)。
以下是我的代码:
module Main where

import qualified System.Environment as SE
import qualified System.Exit as E
import qualified Lib as Lib

main = do
  args <- SE.getArgs
  rem <- parse args
  Lib.someFunc
  putStrLn rem
  putStrLn "Hello"

tac  = unlines . reverse . lines

parse ["--help"]    = usage   >> exit
parse ["--version"] = version >> exit
parse ["--author=xyz"] = return "xyz"
-- parse ["--author=?"] = ?
{-
this is the code I am trying to figure out... how do I get parse the passed in variable name?
-}

-- parse []            = getContents
{-
the above line generates this error when I run 'main' in GHCi:

  *Main> <stdin>: hIsEOF: illegal operation (handle is semi-closed)
  Process intero exited abnormally with code 1

-}
parse fs            = concat `fmap` mapM readFile fs

usage   = putStrLn "Usage: gc2"
version = putStrLn "gc2 -- git-cal in Haskell2010 - 0.1"
exit    = E.exitWith E.ExitSuccess
die     = E.exitWith (E.ExitFailure 1)

1
getContents 获取所有输入,并要求在此之后不要从输入中读取任何内容。您是否满足该约定?例如,请检查 Lib.someFunc - chi
谢谢,那很有道理(看起来错误是因为我在Lib.someFunc中使用了System.Process)。 - kuwze
1
有一些参数解析库可供使用。不使用它们的原因是什么? - Thomas M. DuBuisson
@ThomasM.DuBuisson:我对这些不了解。你介意指引我一下吗? - kuwze
2
optparse-applicative 是许多开发人员首选的强大解析器。然而,对于简单的工作,我喜欢名副其实的 simple-get-opt - Thomas M. DuBuisson
@ThomasM.DuBuisson:谢谢! - kuwze
1个回答

7

为了跟进@ThomasM.DuBuisson的评论,optparse-applicative是一个用于cli和参数解析的优秀包。还有另一个包optparse-simple,它建立在前一个包的基础上,并提供了一些简化操作的帮助程序。

这里是一个使用optparse-applicative的示例实现,让您可以开始使用:

data Options = Options
  { author :: String
  }

main :: IO ()
main = do
  let ver = "gc2 -- git-cal in Haskell2010 - 0.1"
  args <-
    execParser $
    info
      (Options <$>
       strOption (long "author" <>
                  short 'a' <>
                  help "Name of the author.") <*
       infoOption ver (long "version" <>
                       short 'v' <>
                       help "Display version and exit.") <*
       abortOption ShowHelpText (long "help" <>
                                 short 'h' <>
                                 help "Display this message."))
      (progDesc "Very powerful tool." <> fullDesc)
  putStrLn $ author args

而且在GHCi中的使用示例:

λ> :main
Missing: (-a|--author ARG)

Usage: <interactive> (-a|--author ARG) [-v|--version] [-h|--help]
  Very powerful tool.
*** Exception: ExitFailure 1
λ> :main --version
gc2 -- git-cal in Haskell2010 - 0.1
*** Exception: ExitSuccess
λ> :main --help
Usage: <interactive> (-a|--author ARG) [-v|--version] [-h|--help]
  Very powerful tool.

Available options:
  -a,--author ARG          Name of the author.
  -v,--version             Display version and exit.
  -h,--help                Display this message.
*** Exception: ExitSuccess
λ> :main --author Me
Me

ShowHelpText 是什么? - przemo_li
@przemo_li 这是一种类型构造器,它将在解析cli参数失败并显示帮助文本(例如选项、描述等)时终止程序。 https://www.stackage.org/haddock/lts-12.5/optparse-applicative-0.14.2.0/Options-Applicative.html#t:ParseError - lehins

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接