The*_*ten 4 haskell applicative optparse-applicative
是否可以使用optparse-applicative中的方法创建一个haskell表达式来解析这样的程序选项?
program [-a [-b]] ...
Run Code Online (Sandbox Code Playgroud)
-a和-b是选项标志(使用实现switch
),约束条件是-b选项仅在以前键入-a时有效.
谢谢
通过轻微的调整,这有两种不同的方式:
-b
如果你有-a
,但你不能再坚持的是-a
至上的,因为optparse,应用性的<*>
组合子不指定顺序.-b
选项后面的a
选项,但是您可以通过实现a
命令来实现,因此您将失去它-
的前面.对于这一点,Applicative肯定足够强大,因为不需要检查解析器返回的值来确定是否-b
允许,因此>>=
没有必要; 如果-a
有任何输出成功,-b
则允许.
我将使用数据类型来表示存在哪些参数,但实际上这些参数更有意义.
import Options.Applicative
data A = A (Maybe B) deriving Show
data B = B deriving Show
Run Code Online (Sandbox Code Playgroud)
所以我们程序的选项可能包含一个A,它可能有一个B,并且总是有一个字符串.
boption :: Parser (Maybe B)
boption = flag Nothing (Just B) (short 'b')
Run Code Online (Sandbox Code Playgroud)
-b
只能带-a
(任何订单)我将使用flag' () (short 'a')
它只是坚持-a
存在,但然后使用*>
而不是<*>
忽略返回值()
,只返回boption
解析器返回的任何内容,给出选项-a [-b]
.然后我会标记它,A :: Maybe B -> A
最后我将完成整个事情optional
,所以你有选择权[-a [-b]]
aoption :: Parser (Maybe A)
aoption = optional $ A <$> (flag' () (short 'a' ) *> boption)
main = execParser (info (helper <*> aoption)
(fullDesc <> progDesc "-b is only valid with -a"))
>>= print
Run Code Online (Sandbox Code Playgroud)
请注意,既然<*>
允许任何订单,我们可以放在-a
后面-b
(这不是你要求的,但工作正常,对某些应用程序有意义).
ghci> :main -a
Just (A Nothing)
ghci> :main -a -b
Just (A (Just B))
ghci> :main -b -a
Just (A (Just B))
ghci> :main -b
Usage: <interactive> [-a] [-b]
-b is only valid with -a
*** Exception: ExitFailure 1
Run Code Online (Sandbox Code Playgroud)
-b
只能跟随a
您可以使用command
一个subparser
仅在命令字符串存在时有效的.您可以使用它像阴谋做处理参数,因此cabal install
和cabal update
有完全不同的选择.由于command
接受了一个ParserInfo
参数,你可以execParser
使用任何你可以提供的解析器,所以你可以任意深入地嵌套命令.可悲的是,命令不能从头开始-
,所以它将program [a [-b]] ...
代替program [-a [-b]] ...
.
acommand :: Parser A
acommand = subparser $ command "a" (info (A <$> (helper <*> boption))
(progDesc "you can '-b' if you like with 'a'"))
main = execParser (info (helper <*> optional acommand) fullDesc) >>= print
Run Code Online (Sandbox Code Playgroud)
哪个运行如下:
ghci> :main
Nothing
ghci> :main a
Just (A Nothing)
ghci> :main a -b
Just (A (Just B))
ghci> :main -b a
Usage: <interactive> [COMMAND]
*** Exception: ExitFailure 1
Run Code Online (Sandbox Code Playgroud)
所以,你必须先-b
用a
.