cmdargs
cmdargs copied to clipboard
Using enum to set mupltiple flags in a field causes runtime failure.
Attempting to run the following minimal example given in the documentation for enum:
{-#LANGUAGE DeriveDataTypeable#-}
import System.Console.CmdArgs
data State = On | Off deriving (Data, Show)
data Mode = Mode {state :: [State]} deriving (Show, Data)
main = print =<< cmdArgs Mode{state = enum [[] &= ignore, [On] &= help "Turn on", [Off] &= help "Turn off"]}
results in the error message:
System.Console.CmdArgs.Implicit, unexpected no available name: ? regardless of the flags passed to the executable.
I've only tested this with GHC 7.10.1
A slightly simpler example:
data State = On | Off deriving (Data, Show, Typeable)
data Mode = Mode {state :: [State]} deriving (Show, Data, Typeable)
main = print =<< cmdArgs Mode{state = enum [[On], [Off]]}
And the smallest change that can fix it:
main = print =<< cmdArgs Mode{state = enum [[On] &= name "on", [Off] &= name "off"]}
So the problem is that enum tries to guess at flag names based on the value in each of [On] and [Off]. It can guess the value from a constructor, but not a list. Since it can't guess the name it raises an exception. The ways round this are:
- Make it guess a name by peeking inside the list. That works for my revised example, and might work for your original example or not (not sure if it looks at
ignorefirst or not) - but it should be doable in this case. However, it's not going to be possible in all cases. - Improve the error message, so it's clear what went wrong and how to fix it.
Tested by adding name to the non-ignored flags in my example and it does work properly without needing to name an ignored argument.