Unified implementation, now based on current Monocle 3 datatypes.
Adds NonEmptyTraverse, NonEmptyFold, and OptionalGetter implementation classes.
Moved all Optic extension methods into direct methods on Optic, with evidence parameters if necessary.
Rewrote the constructors to have a form like Optic.thatCan.edit[Desk, Pen](...), which emphasises what the user would like to do with the created optic.
Tucked the capability flags into an object OpticCan which is slightly less convenient to use, but seemed like the right thing to do.
Discussion:
I really hate the direct methods with evidence parameters; they are "advanced Scala", whereas extension methods are a popular feature found in many languages. The evidence parameters are also really ugly and hard to read. Wrestling with +/- variance is a big pain, whereas we can ignore it in extension methods.
I should introduce the OpticCan capability flags to the impl classes too. Even though it is not strictly needed, as a matter of good engineering the "what methods may the user call?" and "what methods are actually supported on this implementation?" questions should both be answered in the same place.
Putting aside the new constructor syntax, note the almost complete lack of change in the example and test code, even though the backend implementation was completely ripped out and rewritten. Lots of the code I've added was verbatim cut and paste from Monocle 3.
I really like the Optic.thatCan constructor syntax, it feels really nice to write, it's easy to read and of course easily IDE-discoverable. Note that this effectively deprecates "Lens", "Iso", "Prism", "Traversal", "Fold", etc as user-facing language to implementation-language.
NonEmptyTraverse
,NonEmptyFold
, andOptionalGetter
implementation classes.Optic
, with evidence parameters if necessary.Optic.thatCan.edit[Desk, Pen](...)
, which emphasises what the user would like to do with the created optic.object OpticCan
which is slightly less convenient to use, but seemed like the right thing to do.Discussion:
Optic.thatCan
constructor syntax, it feels really nice to write, it's easy to read and of course easily IDE-discoverable. Note that this effectively deprecates "Lens", "Iso", "Prism", "Traversal", "Fold", etc as user-facing language to implementation-language.