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

标签 haskell optparse-applicative

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

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

其中 ROI = ROI Int Int Int Int

如果这很重要,它会嵌套在更高的解析器中

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

其中 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

关于haskell - 是否可以有一个带有多个参数的 optparse-applicative 选项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41185015/

相关文章:

haskell - 我将如何以可扩展的方式抽象命令/响应?

scala - 纯函数式编程中的 "value"是什么?

haskell - 如何将可选标志解析为 Maybe 值?

haskell - 使用 optparse-applicative 解析 "enum"选项

haskell - 键入带有包名称和版本前缀的名称

functional-programming - 了解 Haskell 中的惰性求值

haskell - 给定一个教堂编码数字作为 CEK 机器的闭包结果,如何取回该数字?

haskell - 如何使用 optparse-applicative 创建嵌套/条件选项?

haskell - optparse-applicative bash 自动补全如何工作?

haskell - 如何通过 Haskell 的 optparse-applicative 使用具有多个值的选项