是否可以有一个带有多个参数的 optparse-applicative 选项?

2024-03-31

我刚刚发现我精心设计的解析器无法解析我扔给它的任何字符串:

roi :: Parser (Maybe ROI)
roi = optional $ option (ROI <$> auto <*> auto <*> auto <*> auto)
               $ long "roi" <> metavar "ROI" <> help "Only process selected region of interest"

where ROI = ROI Int Int Int Int

如果这很重要,则将其嵌套在更高的解析器中

options :: Parser Opts
options = Opts <$> input <*> output <*> roi <*> startT <*> endT  

where Opts是一个合适的 ADT。

现在我假设roi解析器将解析表达式,例如--roi 1 2 3 4但它失败了Invalid argument '128'并给我使用信息。

--roi 1相反,解析但返回Just (ROI 1 1 1 1)

有办法让这项工作发挥作用吗?


我不认为选项应该消耗多个参数。至少我不确定你会如何实施它。我建议简单地放弃这个想法,并将您的 ROI 选项放入单个参数中,使用如下语法--roi 1,2,3,4.

您只需为此实现一个自定义阅读器,以下是如何做到这一点的示例:

module Main where

import Options.Applicative

data ROI = ROI Int Int Int Int
  deriving Show

-- didn't remember what this function was called, don't use this
splitOn :: Eq a => a -> [a] -> [[a]]
splitOn sep (x:xs) | sep==x     = [] : splitOn sep xs
                   | otherwise = let (xs':xss) = splitOn sep xs in (x:xs'):xss
splitOn _ [] = [[]]

roiReader :: ReadM ROI
roiReader = do
  o <- str
  -- no error checking, don't actually do this
  let [a,b,c,d] = map read $ splitOn ',' o
  return $ ROI a b c d

roiParser :: Parser ROI
roiParser = option roiReader (long "roi")

main :: IO ()
main = execParser opts >>= print where
  opts = info (helper <*> roiParser) fullDesc
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

是否可以有一个带有多个参数的 optparse-applicative 选项? 的相关文章

随机推荐