Quoth Evan Laforge <qdunkan at gmail.com>,
...
> The non-composing non-abstract updates are what bug me, and
> make me scatter about tons of 'modifyThis' functions, both for
> composability and to protect from field renames.
So ... at the risk of stating the obvious, is it fair to say the root
of this problem is at least the lack of `first class' update syntax?
For example, in a better world you could write stuff like
modifyConfig :: (Config -> a) -> (a -> a) -> Config -> Config
modifyConfig fr fv a = a { fr = fv (fr a) }
upTempo config = modifyConfig tempo (+ 20) config
... but today you get "`fr' is not a (visible) constructor field name"
So you need a modifyConfigTempo, etc. - when even the above is
inconveniently specific, as we'd rather have
modifyRecord :: RecordType r => (r -> a) -> (a -> a) -> r -> r
I'm not saying "modifyRecord (+ 20) tempo config" would be the ideal
syntax for everyone who's been dreaming of records improvement, just
trying to get at the underlying problem with minimal syntactic
distractions. Nested structure doesn't look like a special problem -
modifyRecord innerRecord (modifyRecord inInField (+ 20)) outRecord
An operator with some infixing doesn't seem to buy a lot -
(innerRecord \{} (inInField \{} (+ 20))) outRecord
... but better might be possible without sacrificing composability.
Donn