В недавнем моем проекте я использовал подход, основанный на «Data.Tree» узлов обработки опций. Конечно, я не выпустил этот код, поэтому он очень ограничен, но я думаю, что эта схема может быть полезна.
data OptHandle = Op { optSat :: String -> Bool
, opBuild :: [String] -> State Env [String]
}
Поля узла: проверьте, удовлетворен ли аргумент узлу; и постепенно наращивает начальную программную среду на основе оставшихся аргументов (возвращая неиспользуемые аргументы для обработки узлами ниже в дереве.)
Дерево обработки опций затем жестко закодировано, например, ниже.
pgmOptTree :: [Tree OptHandle]
pgmOptTree = [mainHelpT,pgmOptT,dbgT]
mainHelpT :: Tree OptHandle
mainHelpT = Node (Op sat bld) []
where
sat "--help" = True
sat _ = False
bld _ = do
mySetEnvShowHelp
return []
pgmOptT :: Tree OptHandle
pgmOptT = Node (Op sat bld) [dbgT]
where
sat = functionOn . someParse
bld ss = do
let (d,ss') = parsePgmOption ss
mySetEnvPgmOpt d
return ss'
Вам также понадобится функция, которая подает аргументы командной строки к дереву, проверка выполнимости каждого узла в лесу, выполняя opBuild и вызова subforests. После запуска обработчика в государственной монаде вам нужно вернуть начальную начальную среду, которая может использоваться для указания основных функций, которые вы хотите вызвать.
Обработчик опций, который я использовал, был на самом деле немного сложнее этого, так как моя программа общалась с Bash для выполнения вкладок и включала помощь для большинства основных опций. Я нашел преимущество в том, что я мог более легко синхронизировать три проблемы с командной строкой: включение вкладок, которые могли бы сообщить пользователям о следующих доступных командах; предоставление помощи для неполных команд; и фактически запускает программу для полных команд.
Поддержание дерева, как это хорошо, потому что вы можете повторно использовать узлы в разных точках и добавлять параметры, которые работают с другими довольно легко.
Если вы знаете перед всеми вариантами «ПРОГРАММА», это легко. В противном случае, я думаю, вы будете писать большую часть логики. –
Возможно, действительно, только если вы знаете заранее возможные значения «ПРОГРАММА»: https://wiki.haskell.org/Command_line_option_parsers – Alec
@ DanielWagner Нет. Я не знаю имен, они постоянно меняются. – jonaprieto