【问题标题】:haskell optparse-applicative: parsing a list of records that have multiple fieldshaskell optparse-applicative:解析具有多个字段的记录列表
【发布时间】:2016-10-10 21:09:12
【问题描述】:

如果我有以下类型和解析器:

data Mode = 
     Mode1 
   | Mode2 
   deriving (Show, Eq, Read)

data ThingINeedMulitpleOf = 
   Thing { _name :: String, _mode :: Mode }
   deriving (Show, Eq)

thingParser :: Parser ThingINeedMulitpleOf
thingParser = Thing <$> strArgument (metavar "NAME")
                    <*> option auto (long "mode" <> metavar "MODE")

我通过以下方式构建解析器:

data Config = 
   Config ThingINeedMulitpleOf ThingINeedMulitpleOf
   deriving (Show, Eq)

loadConfig = execParser $ info (Config <$> thingParser <*> thingParser) fullDesc

然后我可以成功解析my-exe Thing1 --mode Mode1 Thing2 --mode Mode2,但这仅在我想要两个Things 时才有用。 我在尝试更改 Config 以支持 n Things 时遇到问题,即:

data Config = 
   Config [ThingINeedMulitpleOf]
   deriving (Show, Eq)

loadConfig = execParser $ info (Config <$> many thingParser) fullDesc

但我现在无法解析 my-exe Thing1 --mode Mode1 Thing2 --mode Mode2,给我错误 Invalid argument 'Thing1'

有趣的是,如果 ThingINeedMulitpleOf 仅包含一个字段,则此方法有效。

【问题讨论】:

    标签: parsing haskell applicative command-line-arguments


    【解决方案1】:

    如果您使用带有Alternative 类型类的some 函数的子解析器,您可以获得您正在寻找的效果,诚然,使用稍微不同的命令行语法。

    thingSubparser :: Parser ThingINeedMulitpleOf
    thingSubparser = subparser $ command "thing" (info thingParser mempty)
    
    loadConfig :: IO Config
    loadConfig = execParser $ info (Config <$> some thingSubparser) fullDesc
    

    有了这个,你可以编写如下命令行:

    my-exe thing test --mode Mode1 thing test2 --mode Mode2
    

    产生 Config 对象:

    Config [Thing {_name = "test", _mode = Mode1},Thing {_name = "test2", _mode = Mode2}]
    

    我不太清楚你为什么需要子解析器并且不能只使用some 来对抗thingParser,但如果我不得不猜测那是因为该命令为解析器提供了一个分隔符(“事物”参数/命令名称)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多