Optparse-applyative Backtracking

I am trying to use the optparse-applicative library in a program that should do a different action depending on the number of arguments.

For example, parsing arguments for a program that calculates perimeters:

module TestOpts where

import Options.Applicative

type Length = Double

data PerimeterCommand
    = GeneralQuadranglePerimeter Length Length Length Length
    | RectanglePerimeter Length Length

parsePerimeterCommand :: Parser PerimeterCommand
parsePerimeterCommand = parseQuadPerimeter <|> parseRectPerimeter

parseQuadPerimeter = GeneralQuadranglePerimeter <$>
                     parseLength "SIDE1" <*>
                     parseLength "SIDE2" <*>
                     parseLength "SIDE3" <*>
                     parseLength "SIDE4"

parseRectPerimeter = RectanglePerimeter <$>
                     parseLength "WIDTH" <*> parseLength "HEIGHT"

parseLength name = argument auto (metavar name)

      

Only the first argument <|>

will ever be successfully parsed. I think some argument derogation is required, similar to the Parsec combinator try

.

Any ideas on how to parse alternative sets of arguments when the first option might consume some of the arguments of the next alternative?

+3


source to share


1 answer


Please note: This answer was written by the optparse applicator author, Paolo Capriotti.



You cannot do this with optparse-applyative. The main feature of the optparse applicator is that the parameters can be analyzed in any order. If you want to work mostly with arguments (which are positional), you better have two levels of parsers: use many argument

in optparse-applyative, then pass the resulting array to a regular parser (say using Parsec). If you only have positional arguments then optparse-applyative won't buy you much, and you can just parse the arguments manually with Parsec.

+2


source







All Articles