getOpt return record of type a rather than [a]

The current version of System.Console.GetOpt.getOpt returns a list of values, where the element type has usually one constructor per option. data Flag = Verbose | Version | Input String | Output String | LibDir String What I more like to receive is a record consisting of one constructor and many fields, where optional options are of type Maybe, options with multiple occurrence are of type list. data Flag = Flag { verbose :: Bool, version :: Bool, input :: Maybe FilePath, output :: Maybe FilePath, libdir :: FilePath } Then we would need data ArgDescr a = NoArg (a -> a) ReqArg (String -> a -> a) String OptArg (String -> a -> a) String e.g. OptArg (\path flags -> flags {input = Just path}) "FILE" I feel this approach is so natural, that someone must have implemented it already.

On Tue, Dec 18, 2007 at 11:10:58PM +0100, Henning Thielemann wrote:
The current version of System.Console.GetOpt.getOpt returns a list of values, where the element type has usually one constructor per option. data Flag = Verbose | Version | Input String | Output String | LibDir String
What I more like to receive is a record consisting of one constructor and many fields, where optional options are of type Maybe, options with multiple occurrence are of type list.
data Flag = Flag { verbose :: Bool, version :: Bool, input :: Maybe FilePath, output :: Maybe FilePath, libdir :: FilePath }
Then we would need
data ArgDescr a = NoArg (a -> a) ReqArg (String -> a -> a) String OptArg (String -> a -> a) String
e.g.
OptArg (\path flags -> flags {input = Just path}) "FILE"
I feel this approach is so natural, that someone must have implemented it already.
The approach you describe is quite possible with the current GetOpt, just apply (foldr ($) initialValue) to the return value, and allow a to be instantiated with a function type. Stefan

On Tue, 18 Dec 2007, Stefan O'Rear wrote:
The approach you describe is quite possible with the current GetOpt, just apply (foldr ($) initialValue) to the return value, and allow a to be instantiated with a function type.
Great idea! One should add this as example to the docs of GetOpt, because the example given there works the way I didn't like.

On Tue, 18 Dec 2007, Stefan O'Rear wrote:
The approach you describe is quite possible with the current GetOpt, just apply (foldr ($) initialValue) to the return value, and allow a to be instantiated with a function type.
I thought this must be a good article for Category:Idioms, and what do I find there ... http://www.haskell.org/haskellwiki/High-level_option_handling_with_GetOpt

On Dec 18, 2007 11:10 PM, Henning Thielemann
The current version of System.Console.GetOpt.getOpt returns a list of values, where the element type has usually one constructor per option. data Flag = Verbose | Version | Input String | Output String | LibDir String
What I more like to receive is a record consisting of one constructor and many fields, where optional options are of type Maybe, options with multiple occurrence are of type list.
data Flag = Flag { verbose :: Bool, version :: Bool, input :: Maybe FilePath, output :: Maybe FilePath, libdir :: FilePath }
Then we would need
data ArgDescr a = NoArg (a -> a) ReqArg (String -> a -> a) String OptArg (String -> a -> a) String
e.g.
OptArg (\path flags -> flags {input = Just path}) "FILE"
I feel this approach is so natural, that someone must have implemented it already.
Indeed, we to this in HAppS, for instance. Folding the resulting list makes the current GetOpt implementation more than adequate. -- Cheers, Lemmih

Hello Lemmih, Wednesday, December 19, 2007, 1:22:43 AM, you wrote:
Indeed, we to this in HAppS, for instance. Folding the resulting list makes the current GetOpt implementation more than adequate.
this is problem important for me too - i have >50 options. can you please give us a small example of such approach? -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

On Dec 18, 2007 11:28 PM, Bulat Ziganshin
Hello Lemmih,
Wednesday, December 19, 2007, 1:22:43 AM, you wrote:
Indeed, we to this in HAppS, for instance. Folding the resulting list makes the current GetOpt implementation more than adequate.
this is problem important for me too - i have >50 options. can you please give us a small example of such approach?
Henning posted the specialized structure: data ArgDescr a = NoArg (a -> a) ReqArg (String -> a -> a) String OptArg (String -> a -> a) String which is a same as: type DirectArgDescr a = ArgDescr (a -> a) The "flags" can be combined using: foldr ($) emptyConfig flags. -- Cheers, Lemmih

On Tue, 2007-12-18 at 23:10 +0100, Henning Thielemann wrote:
The current version of System.Console.GetOpt.getOpt returns a list of values, where the element type has usually one constructor per option. data Flag = Verbose | Version | Input String | Output String | LibDir String
What I more like to receive is a record consisting of one constructor and many fields, where optional options are of type Maybe, options with multiple occurrence are of type list.
data Flag = Flag { verbose :: Bool, version :: Bool, input :: Maybe FilePath, output :: Maybe FilePath, libdir :: FilePath }
OptArg (\path flags -> flags {input = Just path}) "FILE"
I feel this approach is so natural, that someone must have implemented it already.
Yes it's implemented in Cabal which has commands with loads and loads of flags. As Lemmih says, it can be layered on top of GetOpt quite easily. Indeed Cabal goes one step further and makes the conversion two way so that one can take a value of a type like your Flag above and convert it back into [String]. This is pretty useful when calling the program. Another interesting thing is that all flag types are Monoids: http://haskell.org/pipermail/cabal-devel/2007-December/001509.html Cabal now implements this idea in the modules: http://darcs.haskell.org/cabal/Distribution/Simple/Command.hs http://darcs.haskell.org/cabal/Distribution/Simple/Setup.hs Duncan
participants (5)
-
Bulat Ziganshin
-
Duncan Coutts
-
Henning Thielemann
-
Lemmih
-
Stefan O'Rear