ingolemo / python-lenses

A python lens library for manipulating deeply nested immutable structures
GNU General Public License v3.0
310 stars 19 forks source link

Compose producing unexpected values #38

Open christopherjmblack opened 2 years ago

christopherjmblack commented 2 years ago

The following two snippets produce different results:

The following appears to me to be correct:

lens.Each().Parts().F(sum).get()([1,2,3]) # returns 6

Whereas I think this is a bug:

(lens.Each() & lens.Parts().F(sum)).get()([1,2,3]) # returns 1

I'm using python-lenses 1.1.0, running in python 3.9.13.

ingolemo commented 2 years ago

Just to narrow down the example; the difference is between lens.Each().Parts() and lens.Each() & lens.Parts().

This is really an unfortunate api by me. I tried to make lens.Parts work more or less the same way as the other methods so that you could just tack it onto the end of a method chain and it would do what you want, but as you can see this breaks composition. In the underlying implementation the first one is really doing something like parts(each()) & f(sum) while the second is roughly each() & parts(identity()) & f(sum).

Possible solutions:

  1. Change the syntax to be more representative of the underlying structure. lens.Parts would now take an argument which is the lens that you want it to apply to. The example would have to be written as lens.Parts(lens.Each()).F(sum).get()([1,2,3]). This would break existing code.
  2. Document the problem and tell people to be careful mixing lens.Parts with composition.