简体   繁体   English

haskell optparse-applicative:解析具有多个字段的记录列表

[英]haskell optparse-applicative: parsing a list of records that have multiple fields

If I have the following types and parser: 如果我具有以下类型和解析器:

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")

and I build a parser in the following way: 然后按以下方式构建解析器:

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

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

then I can successfully parse my-exe Thing1 --mode Mode1 Thing2 --mode Mode2 but this is only useful if I want exactly two Things . 那么我就可以成功解析my-exe Thing1 --mode Mode1 Thing2 --mode Mode2但这仅在我要两个Things才有用。 I'm running into problems when trying to change the Config to support n Thing s, ie: 尝试更改Config以支持n Thing时遇到问题,即:

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

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

but I can now no longer parse my-exe Thing1 --mode Mode1 Thing2 --mode Mode2 , giving me the error Invalid argument 'Thing1' 但我现在无法再解析my-exe Thing1 --mode Mode1 Thing2 --mode Mode2 ,给我错误Invalid argument 'Thing1'

Interestingly, this works if the ThingINeedMulitpleOf only contains one field. 有趣的是,如果ThingINeedMulitpleOf仅包含一个字段,则此方法有效。

If you use a subparser with the Alternative typeclass's some function, you can get the effect you're looking for, admittedly with a slightly different command line syntax. 如果您使用带有Alternative类型类的some函数的子解析器,则可以得到想要的效果,但请注意,命令行语法会稍有不同。

thingSubparser :: Parser ThingINeedMulitpleOf
thingSubparser = subparser $ command "thing" (info thingParser mempty)

loadConfig :: IO Config
loadConfig = execParser $ info (Config <$> some thingSubparser) fullDesc

With this you can write command lines like: 这样,您可以编写以下命令行:

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

which yield the Config object: 产生Config对象:

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

I'm not quite sure why you need the subparser and can't just use some against the thingParser , but if I had to guess it'd be because the command gives the parser a delimiter (the "thing" argument/command name). 我不明白为什么你需要的子分析器,不能只使用somethingParser ,但如果要我猜它会是因为该命令给解析器的分隔符(“一事一议”的说法/命令名称) 。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM