I need to manipulate and modify deeply nested immutable collections (maps and lists), and I\'d like to better understand the different approaches. These two libraries solve more
assoc-in
can be more versatile than lens
in some cases, because it can create levels in the structure if they don't exist.
lens
offers Folds
, that tear down the structure and return a summary of the contained values, and Traversals
that modify elements in the structure (possibly targeting several elements at once, possibly doing nothing if the targeted element(s) are not present) while maintaining the structure's overall "shape". But I think it would be difficult to create intermediate levels using lens
.
Another difference I see with the assoc-in
-like functions in Clojure is that these seem to be only concerned with getting and setting values, while the very definition of a lens supports "doing something with the value", that something possibly involving side-effects.
For example, suppose we have a tuple (1,Right "ab")
. The second component is a sum type that can contain a string. We want to change the first character of the string by reading it from console. This can be done with lenses as follows:
(_2._Right._Cons._1) (\_ -> getChar) (1,Right "ab")
-- reads char from console and returns the updated structure
If the string is not present, or is empty, nothing is done:
(_2._Right._Cons._1) (\_ -> getChar) (1,Left 5)
-- nothing read
(_2._Right._Cons._1) (\_ -> getChar) (1,Right "")
-- nothing read