由于消耗了部分输入,optparse-applicative 解析器失败
optparse-applicative parser fails due to partial input being consumed
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")
有关。是否有 (<|>)
的替代方案可以实现所需的行为?
此处的问题出在 (<|>)
运算符中。它只在第一个解析器不使用任何输入时尝试第二个解析器。但是在您的示例中确实如此。您可以通过以相反顺序指定参数来验证这一点。然后第一个解析器将不会消耗任何输入并失败,第二个解析器将 运行 成功结果。
您可以这样解决这个问题:
parser =
(\a -> maybe (example a) (example2 a))
<$> strOption (long "aaa")
<*> optional (strOption (long "bbb"))
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")
有关。是否有 (<|>)
的替代方案可以实现所需的行为?
此处的问题出在 (<|>)
运算符中。它只在第一个解析器不使用任何输入时尝试第二个解析器。但是在您的示例中确实如此。您可以通过以相反顺序指定参数来验证这一点。然后第一个解析器将不会消耗任何输入并失败,第二个解析器将 运行 成功结果。
您可以这样解决这个问题:
parser =
(\a -> maybe (example a) (example2 a))
<$> strOption (long "aaa")
<*> optional (strOption (long "bbb"))