
Evan Laforge wrote:
I consider that a strength of the lens approach. If I say 'set (a.b.c.d) 42 record', 'a', 'b' etc. don't have to be record fields, I can swap them out for other lenses later on.
I can also easily precompose, e.g. 'setThis = a . b; setThat = b . c' and encourage people to use the composed ones (or require via export lists). This corresponds to "asking" in that it introduces a point of abstraction where I can change all access / modification in one place, or a module can retain control by only exporting the composed version.
The same is true with SEC functions:
personsSalary' :: (Salary -> Salary) -> Person -> Person personsSalary' = job' . salary'
Here I've created a new updater that is composed of 2 that are generated for me (from the examples given in the original email). I can export whichever of these functions I like, generated or otherwise, and keep as much abstraction as I like! The nice part about the SEC functions is that they compose as regular functions. Lenses are super powerful in that they form a category. Unfortunately using categories other than functions feels a tad unwieldy because you have to hide something from prelude and then import Category. (A bit like exceptions, currently). If you like the look of "set" with lenses, you could define a helper function to use with SEC updaters.
set :: ((b -> a) -> c) -> a -> c set sec = sec . const
--and then use it like so: setPersonsSalary :: Salary -> Person -> Person setPersonsSalary salary = set personsSalary' salary
With it you can use an updater as a setter. I'd like to reiterate one of finer points of the original proposal.
The compiler could disallow using old-style update syntax for fields whose SEC update function is not in scope, giving us fine-grained control over access and update. On the other hand we currently have to create new functions to achieve this (exporting the getter means exporting the ability to update [using update syntax] as well, currently).
And now back to lenses:
it is really convenient how lenses let you compose the getter and setter together.
I don't recall too many cases where having the getter and setter and modifier all in one place was terribly useful. Could anyone give me an example? But again, where that is useful, a lens can be created from a getter and a SEC updater. Thoughts? --Jonathan