1
我想教自己的Haskell。作为示例程序,我正在写一个蜘蛛纸牌游戏。使用getOpt解析Haskell的命令行参数
我想写一个命令行解析器使用System.Console.GetOpt
。我知道有更简单的方法可以为此程序进行参数解析,但我想了解如何使用GetOpt
模块,因为我预计稍后将在其他将要编写的程序中使用它的复杂性。
我想添加一个“ - 帮助”选项,只是打印一个用法消息,然后退出。如果“--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
范围的事情是因为where子句附加到'parseArgs',其中'progName'不在作用域中(它被绑定在do-block中)。如果你多缩进'where',它将附加到'case',并且'progName'在范围内。 –
(如果除“为什么会出现此错误”之外还有其他问题,则应明确说明该问题。) –
谢谢。我缩进了'where'语句,直到它比第二个case('(_,_,errs)')多一个缩进级别并且它能够工作,但是我认为值'header'和'helpMessage'不会是在第一个案件条款的范围内。我将它们移动到'do'块的'let'值上,而不是'where'。 – Ralph