Re: [Haskell-cafe] Avoiding boilerplate retrieving GetOpt cmd line args
On Thu, Jul 26, 2007 at 10:25:06PM -0700, Dave Bayer wrote: Ok, I'm writing a command line tool, using System.Console.GetOpt to handle command line arguments. My Flags structure so far is data Flag = Filter String | DateFormat String | DocStart String | DocEnd String ... and I want to write accessor functions that return the strings if specified, otherwise returning a default. The best I've been able to do is I don't know if my reply is going to be helpful to you. This is what I would suggest: why don't you create a data type with label records, and than you store that data type in a IORef and update the IORef. At the end you just read the IORef with your updated data: data Config = { filter :: String , dateFormat :: String , etc ... } Then you create a new IOref with config, and, with getOpt, you update the IOref with modifyIORef. At the very end you read the modified IOref. This way you can have default options to be modified with command line options. I don't know if it is clear, but I adopted this approach in a program I'm writing. A program with 14 command line options. Have a look at this part here (starting from data Opts=): http://gorgias.mine.nu/repos/xmobar/Main.hs This way I can load a configuration file and change some of the options, configured in that file, with the given command line options. I hope this is going to help you. Andrea ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Avoiding boilerplate retrieving GetOpt cmd line args
Hi Why not: data Flag = Filter String | DateFormat String | DocStart String | DocEnd String Becomes: data Flag = Flag Key String data Key = Filter | DateFormat | DocStart | DocEnd getString :: Flag - Key - String getString (Flag x y) key = if key == x then y else You can easily extend this to defaults: defaults = [(DocStart,1)] then lookup, instead of just as the else clause. If you have to use Data/Typeable you will no longer be writing portable Haskell, and while they are great, they aren't the thing to use here. Thanks Neil ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Avoiding boilerplate retrieving GetOpt cmd line args
On Friday 27 July 2007, Dave Bayer wrote: Ok, I'm writing a command line tool, using System.Console.GetOpt to handle command line arguments. My Flags structure so far is data Flag = Filter String | DateFormat String | DocStart String | DocEnd String ... and I want to write accessor functions that return the strings if specified, otherwise returning a default. The best I've been able to do is this: getFilter = getString f Markdown.pl where f (Filter s) = Just s f _ = Nothing getDateFormat = getString f %B %e, %Y where f (DateFormat s) = Just s f _ = Nothing getDocStart = getString f ^{-$ where f (DocStart s) = Just s f _ = Nothing getDocEnd = getString f ^-}$ where f (DocEnd s) = Just s f _ = Nothing using a generic accessor function `getString`. There are eight (and growing) needless lines here, where what I really want to do is to pass the constructors `Filter`, `DateFormat`, `DocStart`, or `DocEnd` to the function `getString`. ghci types each of these as `String - Flag`, so one at least knows how to type such a `getString`, but using a constructor-passed-as-an-argument in a pattern match is of course a Parse error in pattern. (I expected as much, but I had to try... `String - Flag` is not enough information to make it clear we're passing a constructor, rather than some hairy arbitrary function, so such a pattern match would be undecidable in general.) So what's the right idiom for avoiding this boilerplate? What you want can (almost) be done as follows: {-# OPTIONS_GHC -fglasgow-exts #-} import Data.Generics import Data.Typeable data Flag = Filter String | DateFormat String | DocStart String | DocEnd String deriving (Typeable, Data) getString :: Flag - String - Flag - String getString c df f | toConstr c /= toConstr f = df getString c df (Filter s) = s getString c df (DateFormat s) = s getString c df (DocStart s) = s getString c df (DocEnd s) = s This version uses overlapping patterns, of course; it should be evident how to change that if you want. Call it as getString Filter{} Markdown.pl flag Jonathan Cast http://sourceforge.net/projects/fid-core http://sourceforge.net/projects/fid-emacs pgp7JvE0fRdTA.pgp Description: PGP signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Avoiding boilerplate retrieving GetOpt cmd line args
Ok, I'm writing a command line tool, using System.Console.GetOpt to handle command line arguments. My Flags structure so far is data Flag = Filter String | DateFormat String | DocStart String | DocEnd String ... and I want to write accessor functions that return the strings if specified, otherwise returning a default. The best I've been able to do is this: getFilter = getString f Markdown.pl where f (Filter s) = Just s f _ = Nothing getDateFormat = getString f %B %e, %Y where f (DateFormat s) = Just s f _ = Nothing getDocStart = getString f ^{-$ where f (DocStart s) = Just s f _ = Nothing getDocEnd = getString f ^-}$ where f (DocEnd s) = Just s f _ = Nothing using a generic accessor function `getString`. There are eight (and growing) needless lines here, where what I really want to do is to pass the constructors `Filter`, `DateFormat`, `DocStart`, or `DocEnd` to the function `getString`. ghci types each of these as `String - Flag`, so one at least knows how to type such a `getString`, but using a constructor-passed-as-an-argument in a pattern match is of course a Parse error in pattern. (I expected as much, but I had to try... `String - Flag` is not enough information to make it clear we're passing a constructor, rather than some hairy arbitrary function, so such a pattern match would be undecidable in general.) So what's the right idiom for avoiding this boilerplate? Thanks, Dave ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Avoiding boilerplate retrieving GetOpt cmd line args
Hi, Not sure if this will help avoid the boilerplate, but I've always liked the approach at http://leiffrenzel.de/papers/commandline-options-in-haskell.html (particularly the section Towards a higher level) for being able to specify defaults. It's the best resource I've found on command line options in Haskell so far. Levi Ok, I'm writing a command line tool, using System.Console.GetOpt to handle command line arguments. My Flags structure so far is data Flag = Filter String | DateFormat String | DocStart String | DocEnd String ... and I want to write accessor functions that return the strings if specified, otherwise returning a default. The best I've been able to do is this: getFilter = getString f Markdown.pl where f (Filter s) = Just s f _ = Nothing getDateFormat = getString f %B %e, %Y where f (DateFormat s) = Just s f _ = Nothing getDocStart = getString f ^{-$ where f (DocStart s) = Just s f _ = Nothing getDocEnd = getString f ^-}$ where f (DocEnd s) = Just s f _ = Nothing using a generic accessor function `getString`. There are eight (and growing) needless lines here, where what I really want to do is to pass the constructors `Filter`, `DateFormat`, `DocStart`, or `DocEnd` to the function `getString`. ghci types each of these as `String - Flag`, so one at least knows how to type such a `getString`, but using a constructor-passed-as-an-argument in a pattern match is of course a Parse error in pattern. (I expected as much, but I had to try... `String - Flag` is not enough information to make it clear we're passing a constructor, rather than some hairy arbitrary function, so such a pattern match would be undecidable in general.) So what's the right idiom for avoiding this boilerplate? Thanks, Dave ___ 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