haskell optparse-applicative:解析具有多个字段的记录列表
haskell optparse-applicative: parsing a list of records that have multiple fields
如果我有以下类型和解析器:
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 Thing
s 时遇到问题,即:
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
仅包含一个字段,则此方法有效。
如果您使用具有 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 [Thing {_name = "test", _mode = Mode1},Thing {_name = "test2", _mode = Mode2}]
我不太清楚为什么你需要子解析器并且不能只使用 some
来对抗 thingParser
,但如果我不得不猜测那是因为命令给出了解析器一个定界符("thing" argument/command 名称)。
如果我有以下类型和解析器:
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 Thing
s 时遇到问题,即:
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
仅包含一个字段,则此方法有效。
如果您使用具有 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 [Thing {_name = "test", _mode = Mode1},Thing {_name = "test2", _mode = Mode2}]
我不太清楚为什么你需要子解析器并且不能只使用 some
来对抗 thingParser
,但如果我不得不猜测那是因为命令给出了解析器一个定界符("thing" argument/command 名称)。