optparse-applicative:解析对的列表

时间:2015-07-20 17:34:03

标签: haskell command-line-arguments applicative optparse-applicative

我试图使用optparse-applicative解析对的列表。解析一对可行,但使用player = document.getElementById('movie_player'); 组合子任意解析很多都会失败。

many

输出:

import           Options.Applicative

pairParser = (,) <$> argument str (metavar "s1")
                 <*> argument str (metavar "s2")

testParser p = getParseResult . execParserPure (prefs idm)
  (info (helper <*> p) fullDesc)

main = do
  print $ testParser pairParser ["one", "two"]
  print $ testParser (many pairParser) []
  print $ testParser (many pairParser) ["one", "two"]
  print $ testParser (many pairParser) ["one", "two", "three", "four"]

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

免责声明:我没有使用高级optparse-applicative技巧的经验,所以我可能会遗漏一些明显的东西。读者:如果是这样,请指出。

你的问题是many做的是(用手写波形描述)将解析器应用于输入的每个块,在这种情况下块由单个参数组成,然后收集结果。因此many pairParserpairParser应用于["one"],然后应用于["two"],并且两个解析均失败。既然如此,您可以将execParserPure替换为以适当的方式对参数进行分块的函数,并相应地调整程序的其余部分,或者(我怀疑是更容易的选择)放弃pairParser和只需对已解析的参数进行后处理,如:

pairArgs :: [a] -> [(a, a)]
pairArgs = noLeftover . foldr pairNext (Nothing, [])
    where
    noLeftover (m, ps) = case m of
        Nothing -> ps
        _       -> []
    pairNext x (m, ps) = case m of
        Just y  -> (Nothing, (x, y) : ps)
        Nothing -> (Just x, ps)

manyPairsParser :: Parser [(String, String)]
manyPairsParser = pairArgs <$> many (argument str (metavar "s1 s2.."))
GHCi> testParser manyPairsParser []
Just []
GHCi> testParser manyPairsParser ["foo"]
Just []
GHCi> testParser manyPairsParser ["foo","bar"]
Just [("foo","bar")]
GHCi> testParser manyPairsParser ["foo","bar","baz"]
Just []
GHCi> testParser manyPairsParser ["foo","bar","baz","quux"]
Just [("foo","bar"),("baz","quux")]

(请注意,在上面的演示中,我通过返回一个空列表对来处理失败,并考虑到奇数个参数应该导致失败。如果你需要做一些调整想要一个不同的行为。)

答案 1 :(得分:1)

许多人和一些人在旧版本的optparse中过于渴望,并且在允许进一步选项之前需要整个构造在单个选项之后成功。

我为许多人改变了逻辑,所以他们在如何消费多种选择方面更加懒散。您可以看到更改和逻辑here