0
module Main where

import Options.Applicative
import Control.Monad
import Control.Monad.State

main :: IO ()
main = join . customExecParser (prefs showHelpOnError) $
  info (helper <*> parser) fullDesc

parser =
  example <$> strOption (long "aaa")
  <|>
  example2 <$> strOption (long "aaa")
           <*> strOption (long "bbb")

example :: String -> IO ()
example x = do
  print "example..."
  print x

example2 :: String -> String -> IO ()
example2 x y = do
  print "example2..."
  print x
  print y

使用上面的代码和以下参数::set args --aaa test --bbb test2结果:

Invalid option `--bbb'

Usage: <interactive> (--aaa ARG | --aaa ARG --bbb ARG)

Available options:
  -h,--help                Show this help text
*** Exception: ExitFailure 1

我怎样才能成功解析第二种情况(关于example2)?

该问题似乎与strOption (long "aaa")两个解析器中都存在的解析器代码有关。是否有替代方案(<|>)可以实现所需的行为?

4

1 回答 1

1

这里的问题在于(<|>)操作员。当第一个解析器没有消耗任何输入时,它只尝试了第二个解析器。但在你的例子中,它确实如此。您可以通过以相反的顺序指定参数来验证这一点。然后第一个解析器不会消耗任何输入并失败,第二个解析器将运行成功结果。

你可以这样解决这个问题:

parser =                                                                                                                                                                                                
  (\a -> maybe (example a) (example2 a))                                        
  <$> strOption (long "aaa")                                                    
  <*> optional (strOption (long "bbb")) 
于 2020-02-05T14:17:42.083 回答