>>12
"Forced use of monads" is a good thing because it forces you to be explicit about your effects. This is good for safety, correctness and compiler optimizations.
And if you're sick of changing the type of every function, there's Debug.Trace - an escape hatch just for such cases.
And updating fields with lenses is done with "+=", "-=" and the like - just like in imperative languages. Example:
zoom (units.traversed.position) $ do
x += 10
y += 10
See how we don't have to write
units.traversed.position.x += 10
units.traversed.position.y += 10
It's just an example of how lenses are first-class and can be composed around, zoomed, traversed, inverted and all sorts of funky shit the imperative languages don't let you do. That's because the imperative languages are "monkey see, monkey do" - they understand only direct fucking orders. Haskell is more intelligent because it allows you to manipulate everything the way you want to, and only executes things when it's necessary, or when you tell it to. Haskell understands abstraction while the imperative languages are numbskull working grunts.