Optparse cannot parse value

While using optparse-applicative I’ve run into this:

option --key: cannot parse value `foobar'

It’s a bit mysterious, and doesn’t tell me a lot.

The code for the param is also pretty simple:

versionKey :: Parser (Maybe Text)
versionKey =
    option
        auto
        (long "key" <> short 'k' <> metavar "KEY" <>
         help "..." <>
         value "defaultvalue" <>
         showDefault)

I’ve spent some time to try different changes that make sense, but without much luck.

I’m guessing someone who has seen this generic error from optparse might know what I did wrong or am not understanding.

Thanks!

I believe option auto uses the Read instance, which wants text delimited by double quotes. There is strOption for text-like values.

2 Likes

ahah, yes… I will need to fiddle around with the functions I’m calling in there. That makes sense. Thank you!

I get a type error when trying to compile the code.

Expected type: Parser (Maybe Text)
  Actual type: Parser [Char]

so I wonder if maybe — for whatever reason — your ghc/i failed to reload it and you are working with an older version?

I’m getting this as a runtime error, and I’ve iterated through a dozen or so variations on this, getting compile-time errors when expected/reasonable, and compiling fine when I have the types lined up. I see the runtime error only when it’s compiled (the problem there, as I understand it, is that optparse-applicative lets you get through with the type that it can’t handle at runtime). I started with some option parsing code that works with an internal data type, but I need to do that parsing differently for a Text/String value. Lastly, there is the Text/String issue. I tried updating my code to use String for the Parser, but that’s a huge headache… however I did find optparse-text, which I’m exploring now.

This should indeed produce a compile-time error as written, because
value needs to be—in this case—of type Maybe Text and that’s not the
case.

What you probably want is something like

versionKey :: Parser (Maybe Text)
versionKey = optional $ strOption
  (  ...
  <> value "defaultvalue"
  <> ...
  )

Switching the parser to String should be as easy as changing the type
signature, as strOption only has an IsString constraint.

1 Like

Indeed I wonder if there is not something like fdefer-… afoot complicating the diagnosis.

The code isn’t public, so sharing that hasn’t been as easy for this (sorry). I have wanted to create a more minimal reproduction, I wasn’t able to do that earlier, but I would like to. I have seen enough weirdness around this I am suspecting a bug here, and a repro is needed to make that more obvious. ATM I guess it is either in optparse or GHC.

That is usually not the case, you then need to have at least one place where you do the “conversion” to the more proper internal types. I have found that especially true with optparse, where it’s harder to keep that conversion contained, and it ends up spilling out to the “command” functions you’ve created.

In my case, there were a bunch more type updates to make and then the conversion. Adding all that code to use String felt like backpeddling… I’d rather be removing code (while improving correctness and features), and not adding an unnecessary conversion.

I’m surprised everyone is so willing to use String, it’s got to go!