calmm-js / partial.lenses

Partial lenses is a comprehensive, high-performance optics library for JavaScript
MIT License
915 stars 36 forks source link

Index isomorphism #180

Closed shtanton closed 6 years ago

shtanton commented 6 years ago

Not sure if this has been suggested before or even if it is already implemented (neither as far as I can tell), but I think a useful function could take an array as a parameter, and return an isomorphism that goes between a value and its index in that array.

Obviously there would need to be some logic dictating what to do if the value isn't in the array or if the index is invalid.

If this is a good idea I would be happy to have a go at creating a PR for it

Thanks

polytypic commented 6 years ago

Hmm... Do you mean something like this?

shtanton commented 6 years ago

Yep, pretty much exactly that, that's almost identical to what I've been using, but I figured it seemed useful enough that it could be included

shtanton commented 6 years ago

Another idea I had is to have a contains lens that could work like this. Not sure if this is general enough to be in the library and I appreciate that obviously not every lens can be in the core library.

Thanks

polytypic commented 6 years ago

Another idea I had is to have a contains lens that could work like this.

Indeed, that kind of lens is fairly commonly useful. There is an example of such a lens in the documentation.

Not sure if this is general enough to be in the library and I appreciate that obviously not every lens can be in the core library.

Thanks to dead-code elimination I'm not super vary of adding new combinators to the library. On the other hand, one problem with optics is that they are such a general abstraction that it is easy to come up with countless number of potentially useful combinators.

Sometimes I add new combinators to the library because they improve upon or support a theoretically interesting or important aspect that is not previously supported well by the library. For example, that is partly the motivation for the cross lens/iso combinator combinator, which is basically a kind of cross product combinator for lenses and/or isomorphisms on arrays. It is inspired by the cross combinator from this paper. I'm pretty sure there will be actual use cases for cross, and I recall wanting something like that a few times, but I don't have an application where I'd be using it immediately.

However, most of time when I add combinators to the library I have an actual use case in mind. In such a case, instead of adding a combinator that covers exactly the use case, I try to find more generalized combinators that have useful mathematical properties and cover more use cases than just the immediate one I had in mind.

Hmm... Both of your suggestions seem reasonable although somewhat specific.

Do you have an actual use case in mind for the index isomorphism? I'd like to understand the context better.

I'm not super fond of the name containsLens (nor the name flag used in documentation). On the other hand, contains would be a plausible name for a fold:

const contains = I.curryN(3, R.o(L.any, R.equals))

What could be another name for containsLens?

Also, I'd suggest joining the Gitter channel to discuss lenses.

shtanton commented 6 years ago

Thanks for the detailed response, I hadn't thought of composing find and is to produce the same result as the contains lens, because it can be so easily produced from existing lenses, it's probably not worth adding it as its own lens.

My use case for the index isomorphism was to show a list of items, and have elsewhere a form that involves selecting using the index of the list item. It doesn't really require the use of lenses but I thought it would be more fun this way. I expect that most of the time, it is better to store the index as state instead of the item itself as indexOf might be quite slow for large arrays, which I think would limit its usefulness.