ekmett/lens

Splitting Ixed/At/Contains into their own package

Opened this issue · 2 comments

Splitting out indexed-traversable has allowed packages to provide *WithIndex instances without depending on lens and all of its transitive deps. It would be great if we could do this for Ixed/At/Contains, because sometimes packages want to provide those instances and depending on lens is regrettable. I'm thinking of monoidal-containers in particular.

While icontains and iat use the IndexedLens machinery, those can remain in lens. The classes themselves could be defined in terms of things only in base and the various containers packages.

phadej commented

From sharing between optics and lens perspective, there isn't much to gain. Ixed in optics and lens look very different.

And that says that something is missing in the design. I don't know what.

For indexed-traversable I do use ifor_ and itraverse, and e.g. ialignWith which builds on top FunctorWithIndex; these classes are not lensy at all. But there's something not right about Ixed without lens or optics.

The peculiarity seems to come from the fact that optics is set up to be able to track the kind of optic ix actually returns. We could capture the "zero-or-one" nature with an operation like ix' :: Index m -> m -> Either m (IxValue m, IxValue m -> m). a Traversal written as an infinite sum of get/set pairs (either you get the structure back, or you get one value and a function that accepts one value, or you get two values and a function that accepts two values, or...), then this is like a "zero or one element unfolding" of that infinite sum.

But optics is able to say "ix gives you a lens if you index into a Naperian container", and this encoding doesn't.