0

我有

type Month = Int

parseMonths :: OP.Parser (Month, Month)
parseMonths =
    liftA2 (,)
        (OP.option
            (OP.eitherReader $
             parseNumber "month" (\n -> 1<=n && n<=12) "month")
            (OP.metavar "MONTH" <>
             OP.long "from-month" <>
             OP.value 1))
        (OP.option
            (OP.eitherReader $
             parseNumber "month" (\n -> 1<=n && n<=12) "month")
            (OP.metavar "MONTH" <>
             OP.long "to-month" <>
             OP.value 12))

我想添加一张支票,第一个月不在第二个月之后。显然我不能在OP.ReadM. 我可以办理登机手续OP.Parser吗?或者我是否必须在解析后执行检查parserFailureOptparse-applicative: Continuous parsing (ReadM)

4

1 回答 1

0

我可以办理登机手续OP.Parser吗?

不。

Parser只是一个Applicative而不是一个Monad(因此包名称,optparse-applicative)。这是解析器函子的一个典型特征——因为Applicative实例收集了尽可能多的错误,所以没有可能的合法Monad实例。

如果没有 a Monad,就不可能编写Parser依赖于其他 s 结果的Parsers - 因为这是 monad 的定义特征。


但是,optparse-applicative确实提供了一个逃生舱,如果您真的需要一个:使用ParserM.

ParserM基本上是一个替代方案Parser-Monad以有时会丢失错误消息为代价。您可以使用 编写一元解析器ParserM,然后使用runParserM将其转回常规的Parser.

于 2021-09-17T10:43:22.980 回答