Я пытаюсь научить себя Haskell. В качестве примера программы я пишу пасьянс «Паук».
Я пытаюсь написать парсер командной строки, используя System.Console.GetOpt
. Я знаю, что есть более простые способы разбора аргументов для этой программы, но я хочу узнать, как использовать модуль GetOpt
, потому что я предполагаю, что его сложность понадобится позже в других программах, которые я буду писать.
Я пытаюсь добавить опцию «--help», которая просто печатает сообщение об использовании, а затем завершает работу. Я также хотел бы печатать сообщения об использовании, если какой-либо из аргументов опции «—games» или опции «—suits» не является допустимым целым числом (игры >= 1 и ‹= 1000, костюмы == 1, 2, или 4). Я буду передавать полученный тип данных Options
в другие части моей программы.
Я также получаю сообщение об ошибке, что progName
не входит в область действия. Разве оператор case
в parseArgs
не входит в область действия блока do
?
Вот мой код, собранный из примеров в "Real World Haskell" и Вики Haskell:
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
не входит в область действия (оно связано в блоке выполнения). Если вы сделаете отступwhere
немного больше, он прикрепится кcase
, иprogName
окажется в области видимости. - person Daniel Fischer   schedule 28.05.2012where
clause до тех пор, пока он не стал на один уровень отступа больше, чем во втором case ((_, _, errs)
), и это сработало, но тогда я предполагаю, что значенияheader
иhelpMessage
не будут входить в область действия первого case case. Вместо этого я переместил их, чтобы они былиlet
значениями блокаdo
, и удалилwhere
. - person Ralph   schedule 29.05.2012