I have
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))
I want to add a check, that the first month is not after the second month. Obviously I cannot do that in OP.ReadM. Can I perform the check in OP.Parser? Or do I have to perform the check after parsing with parserFailure like here:
Optparse-applicative: consecutive parsing (ReadM)
?
                        
No.
Parseris only anApplicativeand not aMonad(hence the package name,optparse-applicative). This is a typical feature of parser functors - because theApplicativeinstance collects as many errors as possible, there is no possible lawfulMonadinstance.Without being a
Monad, it's impossible to writeParsers that depend on the result of otherParsers - since that's the defining feature of monads.However,
optparse-applicativedoes offer an escape hatch, if you really need one: useParserM.ParserMis basically an alternative toParserwhich is aMonad- at the cost of dropping error messages some of the time. You can write a monadic parser usingParserM, and then userunParserMto turn it back into a regularParser.