Hi Oliver,
So lens abstracts the idea of a property in some structure, with a get and set operation to get and set that property value within the structure. The get and set can be derived from a doGet and doSet operation:
Lens[A, B] from (doGet: A => B, doSet: A => B => A)
In a PLens, the getter is optional. Some instances of A may have that property, others may not.
PLens[A, B] from (doGet: A => Option[B], doSet: A => B => A)
Obviously, if get is None, then when you come to set, you have nothing to work with, so set is not defined if get is not defined.
What I need is either:
OLens[A, B] from (doGet: A => B, doSet: A => Option[B => A])
or
POLens[A, B] from (doGet: A => Option[B], doSet: A => Option[B => A])
This generalises the idea of a property that may be read-only, or may be read-write. For an instance of A where the property is read-write, doSet returns Some[B => A]. For an instance where it is read-only, it returns None.
So a List[String] has a property size, which is read-only. This would have
OLens[List[String], Int] from (doGet = _.size, doSet = _ => None)
However, a field in a case-class is read-write. This would have
OLense[MyCc, F] from (doGet = _.aField, doSet = cc => Some((f: F) => cc.copy(aField = f)))
Does that help?
Matthew