Lenses in Haskell are truly easy. The hardest part around them is the tooling. They'd be much better if GHC could generate them for you. When I go back to imperative languages, like Rust, C++, or Javascript, I find myself missing the easy traversals and folds one can do with lenses. It's like being able to have a Graph QL database for all your data structures instantaneously. When it works, it is truly glorious.
The intuition is easy. The fundamental thing is a getter and a setter. Getters can get multiple things, but always produce one answer. So, in order to take multiple things and combine them, you have to fold them. Thus, a getter of multiple things is a fold. A setter can also set / modify multiple things. To take multiple things and produce multiple things is a traversal. Due to the way Haskell works, all traversals are also folds (the math checks out).
Everything else is just a specialization of folds and traversals. And honestly, you can view folds as a particular type of traversal (the identity traversal with an effect). Thus, really traversals are fundamental.
For example, prisms are just traversals that can target zero or one (but not >1 element). A 'getter' (lens's terminology) is a fold with only one element. A lens is a getter and a traversal. Thus it can only set one element.