Hi Magnus, What you want is actually easier than you think!
To quote from http://hackage.haskell.org/packages/archive/cmdargs/0.6.7/doc/html/System-Console-CmdArgs-Implicit.html: "Missing Fields: If a field is shared by multiple modes, it may be omitted in subsequent modes, and will default to the previous value." Therefore you can just do: cmd1 = Cmd1 { foo = def &= help "..", ...} cmd2 = Cmd2 { ...} -- never mention foo in Cmd2 cmdArgs [cmd1,cmd2] And foo in Cmd2 will act exactly like you duplicated the definition from foo in Cmd1. I use this feature regularly - it's a big time saver. Alternatively, you can use the tricks described by Kevin. Finally, you can switch to the pure annotations. I will document them shortly and give an example in System.Console.CmdArgs.Implicit, but for now the details can be found at http://hackage.haskell.org/packages/archive/cmdargs/0.6.7/doc/html/System-Console-CmdArgs-Annotate.html To translate your cmd1/cmd2: cmd1 = record Cmd1{} [foo := def += help "..", ...] cmd2 = record Cmd2{} [foo := def += help "..", ...] And then call cmdArgs_ instead. Now you can do anything that equational reasoning supports without any danger: cmd1 = record Cmd1{} [myfoo, ...] cmd2 = record Cmd2{} [myfoo, ...] myfoo = foo := def += help ".." Even when using the pure annotations, you can still use missing fields: cmd1 = record Cmd1{} [foo := def += help "..", ...] cmd2 = record Cmd2{} [...] Thanks, Neil On Mon, Jan 24, 2011 at 8:50 PM, Kevin Quick <qu...@sparq.org> wrote: > Magnus, > > I used the following technique, but it was a couple of iterations of CmdArgs > ago: > > > data UIMode = Normal | Batch | Query deriving (Data,Typeable,Show,Eq) > > uimode_arg :: forall t. t -> UIMode > uimode_arg _ = enum Normal > [ Batch &= flag "B" & text "batch mode (no interaction)" & > group grp > , Query &= flag "Q" > & text "query mode (user verification solicited)" > & group grp > ] > where grp = "Operating Mode" > > > data Globalargs = CMD1 { ... , uimode :: UIMode , ... } > | CMD2 { ... , uimode :: UIMode , ... } > > > cmd1mode :: Mode Globalargs > cmd1mode = mode $ CMD1 { ... , uimode = uimode_arg "cmd1" } > &= text (usage "...") > > > cmd2mode :: Mode Globalargs > cmd2mode = mode $ CMD1 { ... , uimode = uimode_arg "cmd2" } > &= text (usage "...") > > modes :: [ Mode Globalargs ] > modes = [ cmd1mode, cmd2mode ] > > main = do cmdArgs progSummary modes > ... > > > I've cut and pasted from my usage and perhaps pasted too little, so let me > know if the above is unuseably brief. And again, cmdargs has changed > somewhat since this code was written and I haven't tried a recent > compilation. > > -KQ > > P.S. This often required {-# OPTIONS_GHC -fno-full-laziness -fno-strictness > #-} because GHC (6.12? 6.10?) would complain about my uimode_arg type > otherwise. > > > On Thu, 20 Jan 2011 01:48:35 -0700, Magnus Therning <mag...@therning.org> > wrote: > >> I'm looking for a good way of dealing with common flags in cmdargs. >> Currently what I do requires a bit of repetition that I'd really like >> to get rid of: >> >> 1. Data types >> >> data Modes = Cmd1 { foo :: String, ... } | Cmd2 { foo :: String, ... } >> >> 2. Mode specifications >> >> cmd1 = Cmd1 { foo = def &= help "..", ...} >> cmd2 = Cmd2 { foo = def &= help "..", ...} >> >> I have no idea how to deal with the repetition in the data types, so >> all suggestions are welcome. >> >> For the repetition in the mode specifications I attempted to factor >> the common bits into a "variable": >> >> flagFoo = "" &= help ".." >> >> but that resulted in only the first command getting the proper >> specification. I suppose this comes down to the impurity, but how do >> I work around that? (Especially, are there any good examples of using >> the pure part of the API?) >> >> /M >> > > > -- > -KQ > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe