【问题标题】:Perform checks that include multiple options执行包含多个选项的检查
【发布时间】:2021-09-17 10:05:06
【问题描述】:

我有

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 中进行检查吗?或者我是否必须在使用parserFailure 解析后执行检查,如下所示: Optparse-applicative: consecutive parsing (ReadM) ?

【问题讨论】:

    标签: haskell applicative optionparser optparse-applicative


    【解决方案1】:

    我可以检查OP.Parser吗?

    没有。

    Parser 只是Applicative 而不是Monad(因此包名称为optparse-applicative)。这是一个typical feature of parser functors - 因为Applicative 实例收集了尽可能多的错误,所以没有可能的合法Monad 实例。

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


    不过,optparse-applicative 确实提供了一个逃生舱口,如果您真的需要一个:请使用 ParserM

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

    【讨论】:

    • OP.ParserApplicative 而不是Monad 仅意味着您不能定义Monad 类的bindjoin。但是,原则上可以有一个像 checkMulti :: (a -&gt; Maybe String) -&gt; OP.Parser a -&gt; OP.Parser a 这样的自定义函数来提供我想要的功能。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-23
    • 1970-01-01
    • 2017-10-08
    • 1970-01-01
    • 2016-08-19
    • 2022-01-24
    相关资源
    最近更新 更多