I find the Monocle library does a good job of describing the motivation for type optics: <a href="http://julien-truffaut.github.io/Monocle/" rel="nofollow">http://julien-truffaut.github.io/Monocle/</a><p>Where I've used this in real code is via circe-optics (json parsing). An example: <a href="https://stackoverflow.com/questions/36724068/how-to-parse-a-json-scala-without-case-classes" rel="nofollow">https://stackoverflow.com/questions/36724068/how-to-parse-a-...</a>
I mainly program in low-level imperative languages (mostly C/C++), and occasionally dabbled in some functional languages (like Ocaml and Elm). But I don’t really understand why you would need such a convoluted system to get/mutate some values in a data structure in Scala. Doesn’t Scala allow mutability throughout its language already (unlike Haskell)?
Monocle also ships with the macro annotation <i>monocle.macros.Lenses</i> that cuts out even more of the boilerplate and works with intellij's autocomplete<p><pre><code> import monocle.macros.Lenses
@Lenses
case class Foo(bar: Int)
val x = Foo(1)
assert(Foo.bar.get(x) == 1)</code></pre>
<a href="https://arxiv.org/abs/1809.00738" rel="nofollow">https://arxiv.org/abs/1809.00738</a> is really nice for general context. Plus can implement some of these generalizations from what is already here.
I like working in Scala quite a bit, but always wince at the "instead of using threading primitives consider this 10x more exotic immutable approach" lead-in. Does anyone here really work that way?