在Haskell中解析命令行参数

kuw*_*wze 3 haskell

我目前正在一个需要解析命令行参数的项目中。到目前为止,我一直在关注本教程该教程非常有用,但是我不知道如何在参数中返回变量(--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)
Run Code Online (Sandbox Code Playgroud)

leh*_*ins 5

要跟进@ 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
Run Code Online (Sandbox Code Playgroud)

和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
Run Code Online (Sandbox Code Playgroud)