我正在尝试自学 Haskell。作为一个示例程序,我正在编写一个蜘蛛纸牌播放器。
我正在尝试使用System.Console.GetOpt
. 我知道有更简单的方法可以对该程序进行参数解析,但我想学习如何使用该GetOpt
模块,因为我预计稍后在我将编写的其他程序中需要它的复杂性。
我正在尝试添加一个“--help”选项,它只打印一条使用消息然后退出。如果“--games”选项或“--suits”选项的任何一个参数不是有效整数(游戏> = 1和<= 1000,西装== 1、2,或 4)。我会将生成的Options
数据类型传递给程序的其他部分。
我也收到一个progName
不在范围内的错误。case
语句不是在块parseArgs
的范围内吗?do
这是我的代码,由“Real World Haskell”和Haskell wiki中的示例拼凑而成:
module Main (main) where
import System.Console.GetOpt
import System.Environment(getArgs, getProgName)
data Options = Options {
optGames :: Int
, optSuits :: Int
, optVerbose :: Bool
} deriving Show
defaultOptions = Options {
optGames = 1
, optSuits = 4
, optVerbose = False
}
options :: [OptDescr (Options -> Options)]
options =
[ Option ['g'] ["games"]
(ReqArg (\g opts -> opts { optGames = (read g) }) "GAMES")
"number of games"
, Option ['s'] ["suits"]
(ReqArg (\s opts -> opts { optSuits = (read s) }) "SUITS")
"number of suits"
, Option ['v'] ["verbose"]
(NoArg (\opts -> opts { optVerbose = True }))
"verbose output"
]
parseArgs :: IO Options
parseArgs = do
argv <- getArgs
progName <- getProgName
case getOpt RequireOrder options argv of
(opts, [], []) -> return (foldl (flip id) defaultOptions opts)
(_, _, errs) -> ioError (userError (concat errs ++ helpMessage))
where
header = "Usage: " ++ progName ++ " [OPTION...]"
helpMessage = usageInfo header options
main :: IO ()
main = do
options <- parseArgs
putStrLn $ show options