handling non-string command line arguments

I've been looking at choices for parsing command line arguments, including getOpt. The examples I can find focus on string arguments, whereas I am interested in numbers. In the application at hand, it is particularly important to issue clear error messages when arguments don't parse as numbers or are out of range. I could use getOpt as a first pass with string arguments and then turn the strings into validated numbers in a second pass, but that's a bit awkward. Alternately I could use the options records with Options -> IO Options functions. But both of these solutions treat type mismatches differently from other options errors. Has anyone found a cleaner solution? -- Johan Larson -- Toronto, Canada

I’d recommend taking a look at *optparse-applicative* http://hackage.haskell.org/package/optparse-applicative-0.9.0. The library is very flexible and designed well.

If you want to use getOpt, you could produce options of type 'OptDescr
(Either String (Options -> Options))', that is, for a command line
argument, either produce an error, or some modification of your
options.
It is my experience that sometimes you will need a second pass even if
you do this, because there are some errors that require the value of
multiple options to check.
Erik
On Sat, Jun 28, 2014 at 9:28 PM, Johan Larson
I've been looking at choices for parsing command line arguments, including getOpt. The examples I can find focus on string arguments, whereas I am interested in numbers. In the application at hand, it is particularly important to issue clear error messages when arguments don't parse as numbers or are out of range.
I could use getOpt as a first pass with string arguments and then turn the strings into validated numbers in a second pass, but that's a bit awkward. Alternately I could use the options records with Options -> IO Options functions. But both of these solutions treat type mismatches differently from other options errors.
Has anyone found a cleaner solution?
-- Johan Larson -- Toronto, Canada
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

What is the issue with other option errors and type matches being
treated differently? I mean, you can print the same error message. A
handy trick is to define a helper for building your options list that
passes the option names into your monadic option builder function so
it can print the name of the option that was given the wrong type in a
generic and pretty way. I generally use a Writer monad to collect
errors rather than an Error monad that cuts out early so all option
errors can be accumulated and printed together.
John
On Sat, Jun 28, 2014 at 12:28 PM, Johan Larson
I've been looking at choices for parsing command line arguments, including getOpt. The examples I can find focus on string arguments, whereas I am interested in numbers. In the application at hand, it is particularly important to issue clear error messages when arguments don't parse as numbers or are out of range.
I could use getOpt as a first pass with string arguments and then turn the strings into validated numbers in a second pass, but that's a bit awkward. Alternately I could use the options records with Options -> IO Options functions. But both of these solutions treat type mismatches differently from other options errors.
Has anyone found a cleaner solution?
-- Johan Larson -- Toronto, Canada
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- John Meacham - http://notanumber.net/

I mean getOpt has its own way of keeping track of errors and whatever
construction I use to collect typechecking errors will need another. If
only there were a way for the typechecking errors messages to be picked up
by getOpt itself, and returned with its own native error messages.
On Sat, Jun 28, 2014 at 5:30 PM, John Meacham
What is the issue with other option errors and type matches being treated differently? I mean, you can print the same error message. A handy trick is to define a helper for building your options list that passes the option names into your monadic option builder function so it can print the name of the option that was given the wrong type in a generic and pretty way. I generally use a Writer monad to collect errors rather than an Error monad that cuts out early so all option errors can be accumulated and printed together.
John
I've been looking at choices for parsing command line arguments, including getOpt. The examples I can find focus on string arguments, whereas I am interested in numbers. In the application at hand, it is particularly important to issue clear error messages when arguments don't parse as numbers or are out of range.
I could use getOpt as a first pass with string arguments and then turn
On Sat, Jun 28, 2014 at 12:28 PM, Johan Larson
wrote: the strings into validated numbers in a second pass, but that's a bit awkward. Alternately I could use the options records with Options -> IO Options functions. But both of these solutions treat type mismatches differently from other options errors.
Has anyone found a cleaner solution?
-- Johan Larson -- Toronto, Canada
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- John Meacham - http://notanumber.net/
-- Johan Larson -- Toronto, Canada

On 14-06-28 03:28 PM, Johan Larson wrote:
I've been looking at choices for parsing command line arguments, including getOpt. The examples I can find focus on string arguments, whereas I am interested in numbers. In the application at hand, it is particularly important to issue clear error messages when arguments don't parse as numbers or are out of range.
My https://github.com/treblacy/random-read has an example of realistic arguments using optparse-applicative. It goes as far as random-read --prob=2/3 file1 file2 file3... The 2/3 there has to be a rational number between 0 and 1 in the syntax "numerator/denominator". If you give "234" or "abc", you get one error message. If you give "30/7", you get a different error message.

You can use http://hackage.haskell.org/package/uu-options, designed to parser command line options. It even allows for combining various elements on the command line into a single option field.
See the second half of the paper mentioned on hackage for examples of its use.
Since the parsers make use of uu-parsinglib the user gets "autocorrection" and nice error messages for free.
Doaitse
On 28 Jun 2014, at 21:28 , Johan Larson
I've been looking at choices for parsing command line arguments, including getOpt. The examples I can find focus on string arguments, whereas I am interested in numbers. In the application at hand, it is particularly important to issue clear error messages when arguments don't parse as numbers or are out of range.
I could use getOpt as a first pass with string arguments and then turn the strings into validated numbers in a second pass, but that's a bit awkward. Alternately I could use the options records with Options -> IO Options functions. But both of these solutions treat type mismatches differently from other options errors.
Has anyone found a cleaner solution?
-- Johan Larson -- Toronto, Canada _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
participants (6)
-
Albert Y. C. Lai
-
Erik Hesselink
-
Johan Larson
-
John Meacham
-
Nikita Volkov
-
S. Doaitse Swierstra