Make classy lenses for Hledger options fields. This is intended to be
used with BalancingOpts, InputOpt, ReportOpts, ReportSpec, and
CliOpts. When run on X, it will create a typeclass named HasX (except
for ReportOpts, which will be named HasReportOptsNoUpdate) containing
all the lenses for that type. If the field name starts with an
underscore, the lens name will be created by stripping the underscore
from the front on the name. If the field name ends with an underscore,
the field name ends with an underscore, the lens name will be mostly
created by stripping the underscore, but a few names for which this
would create too many conflicts instead have a second underscore
appended. ReportOpts fields for which updating them requires updating
the query in ReportSpec are instead names by dropping the trailing
underscore and appending NoUpdate to the name, e.g. querystring_ ->
querystringNoUpdate.
There are a few reasons for the complicated rules. - We have some
legacy field names ending in an underscore (e.g. value_) which we want
to temporarily accommodate, before eventually switching to a more
modern style (e.g. _rsReportOpts) - Certain fields in ReportOpts need
to update the enclosing ReportSpec when they are updated, and it is a
common programming error to forget to do this. We append NoUpdate to
those lenses which will not update the enclosing field, and reserve
the shorter name for manually define lenses (or at least something
lens-like) which will update the ReportSpec. cf. the lengthy
discussion here and in surrounding comments:
https://github.com/simonmichael/hledger/pull/1545#issuecomment-881974554