[Haskell-cafe] Cmdargs and common flags

2011-01-24 Thread Magnus Therning
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

-- 
Magnus Therning                      OpenPGP: 0xAB4DFBA4
email: mag...@therning.org   jabber: mag...@therning.org
twitter: magthe               http://therning.org/magnus

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Cmdargs and common flags

2011-01-24 Thread Kevin Quick

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  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


Re: [Haskell-cafe] Cmdargs and common flags

2011-01-24 Thread Neil Mitchell
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  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 
> 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


Re: [Haskell-cafe] Cmdargs and common flags

2011-02-14 Thread Neil Mitchell
Hi Magnus,

> 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

I've added more details in:
http://hackage.haskell.org/packages/archive/cmdargs/0.6.8/doc/html/System-Console-CmdArgs-Annotate.html
http://hackage.haskell.org/packages/archive/cmdargs/0.6.8/doc/html/System-Console-CmdArgs-Implicit.html

The first link includes comparisons for pure/impure, and the second
gives a set of equivalences for converting between the two forms.

Thanks, Neil

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Cmdargs and common flags

2011-03-12 Thread Magnus Therning
On Mon, Feb 14, 2011 at 19:11, Neil Mitchell  wrote:
> Hi Magnus,
>
>> 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
>
> I've added more details in:
> http://hackage.haskell.org/packages/archive/cmdargs/0.6.8/doc/html/System-Console-CmdArgs-Annotate.html
> http://hackage.haskell.org/packages/archive/cmdargs/0.6.8/doc/html/System-Console-CmdArgs-Implicit.html
>
> The first link includes comparisons for pure/impure, and the second
> gives a set of equivalences for converting between the two forms.
>
> Thanks, Neil

I noticed that the form "record Ctor {} [...]" leads to a warning that
Ctor isn't initialised.  The obvious way to remove the warning is to
call the constructor with all the arguments, but is there a more
convenient/terse way of achieving the same?

/M

-- 
Magnus Therning                      OpenPGP: 0xAB4DFBA4
email: mag...@therning.org   jabber: mag...@therning.org
twitter: magthe               http://therning.org/magnus

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Cmdargs and common flags

2011-03-12 Thread Neil Mitchell
{-# OPTIONS_GHC -fno-warn-missing-fields #-}

That's what I did in my CmdArgs test suite - if you have all your
CmdArgs bit in a separate file then missing this warning will be fine.
I don't know of any way to rewrite the code to indicate to GHC that
you know what you are doing.

Thanks, Neil


On Sat, Mar 12, 2011 at 8:02 AM, Magnus Therning  wrote:
> On Mon, Feb 14, 2011 at 19:11, Neil Mitchell  wrote:
>> Hi Magnus,
>>
>>> 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
>>
>> I've added more details in:
>> http://hackage.haskell.org/packages/archive/cmdargs/0.6.8/doc/html/System-Console-CmdArgs-Annotate.html
>> http://hackage.haskell.org/packages/archive/cmdargs/0.6.8/doc/html/System-Console-CmdArgs-Implicit.html
>>
>> The first link includes comparisons for pure/impure, and the second
>> gives a set of equivalences for converting between the two forms.
>>
>> Thanks, Neil
>
> I noticed that the form "record Ctor {} [...]" leads to a warning that
> Ctor isn't initialised.  The obvious way to remove the warning is to
> call the constructor with all the arguments, but is there a more
> convenient/terse way of achieving the same?
>
> /M
>
> --
> Magnus Therning                      OpenPGP: 0xAB4DFBA4
> email: mag...@therning.org   jabber: mag...@therning.org
> twitter: magthe               http://therning.org/magnus
>

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe