首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >optparse-applicative的(Sub)命令同义词

optparse-applicative的(Sub)命令同义词
EN

Stack Overflow用户
提问于 2021-11-21 17:38:34
回答 1查看 46关注 0票数 3

我想为我的Haskell命令行工具中的子命令添加同义词。例如,summarisesummarize应该产生相同的结果。当然,我可以只添加一个完全独立的命令summarize,它在--help的输出中显示为自己的元素。但也许有一种更优雅的方式。

下面是堆栈脚本opt_ex.hs中的一个自包含示例

代码语言:javascript
复制
#!/usr/bin/env stack
-- stack --resolver lts-18.17 script --package optparse-applicative

import Options.Applicative
import Data.Semigroup ((<>))

data Options = CmdGreet GreetArgs | CmdGroot GreetArgs

newtype GreetArgs = GreetArgs String

main :: IO ()
main = do
    cmdOpts <- customExecParser (prefs showHelpOnEmpty) (info optParser fullDesc)
    runCmd cmdOpts

optParser :: Parser Options
optParser = subparser (
    command "greet" (info (CmdGreet <$> sample) (progDesc "Print greeting 1")) <>
    command "groot" (info (CmdGroot <$> sample) (progDesc "Print greeting 2"))
    )

runCmd :: Options -> IO ()
runCmd o = case o of
    CmdGreet opts -> greet opts
    CmdGroot opts -> groot opts

greet :: GreetArgs -> IO ()
greet (GreetArgs h) = putStrLn $ "Hello, " ++ h ++ "!"

groot :: GreetArgs -> IO ()
groot (GreetArgs h) = putStrLn $ "Howdy, " ++ h ++ "!"

sample :: Parser GreetArgs
sample = GreetArgs <$> strArgument ( metavar "TARGET" )

您可以使用./opt_ex.hs greet John来获得Hello, John!,使用./opt_ex.hs groot John来获得Howdy, John!。运行./opt_ex.hs将给出以下概述:

代码语言:javascript
复制
Usage: opt_ex.hs COMMAND

Available commands:
  greet                    Print greeting 1
  groot                    Print greeting 2

在本例中添加命令gruut最优雅的方法是什么,它的行为与greet完全相同,但在代码和用户中产生的开销最少?

理想情况下,我希望./opt_ex.hs生成如下内容:

代码语言:javascript
复制
Usage: opt_ex.hs COMMAND

Available commands:
  greet|gruut              Print greeting 1
  groot                    Print greeting 2
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-11-21 20:12:59

我不认为你能做到这一点。它适用于选项,因为OptField的定义包含一个OptName列表,并在您使用(<>)时添加到该列表中。但是command返回的CommandFields的定义是

代码语言:javascript
复制
data CommandFields a = CommandFields
  { cmdCommands :: [(String, ParserInfo a)]
  , cmdGroup :: Maybe String }

因此,每个字符串名称都与不同的ParserInfo相关联。当然,您可以定义一个包含任何ParserInfo的变量,并在两个命令中重用它,这样就不必重复ParserInfo。但就optparse-applicative而言,这两个命令是不同的,因此它将在帮助文本中分别列出它们。对于您的示例,如下所示

代码语言:javascript
复制
optParser = let greeting1 = info (CmdGreet <$> sample) (progDesc "Print greeting 1")
            in subparser $
               command "greet" greeting1 <>
               command "gruut" greeting1 <>
               command "groot" (info (CmdGroot <$> sample) (progDesc "Print greeting 2"))

实际上,当运行时,我们可以看到列出了这两个命令:

代码语言:javascript
复制
Usage: optparse COMMAND

Available commands:
  greet                    Print greeting 1
  gruut                    Print greeting 1
  groot                    Print greeting 2
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70057060

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档