The suggestion of parameterizing on a functor would be good, however there's another approach I've often seen (although it's not quite what you've asked for).  You can leave your config datatype alone, but instead of making it a monoid have your configuration parsers return functions with the type (Cfg -> Cfg).  You can wrap these functions in Endo to get a monoid, combine them together, and then apply that function to the default configuration.


On Wed, Jul 17, 2013 at 4:57 AM, Michael Orlitzky <michael@orlitzky.com> wrote:
I have a common pattern in my command-line programs; I start out with a
configuration data type, which over-simplified looks like:

  data Cfg = Cfg { verbose :: Bool }

Now, there's usually a default configuration,

  default :: Cfg
  default = Cfg False

The user can override the defaults one of two ways, either via a config
file, or from the command-line. If both are specified, the command-line
takes precedence. The way I do this is with,

  data OptionalCfg = OptionalCfg { verbose :: Maybe Bool }

And then I define I Monoid instance for OptionalCfg which lets me merge
two ofthem. Once the two OptionalCfgs are merged, I merge *that* with
the default Cfg.

This all works great, except that when there's 20 or so options, I
duplicate a ton of code in the definition of OptionalCfg. Is there some
pre-existing solution that will let me take a Cfg and create a new type
with Cfg's fields wrapped in Maybe?

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