A \"lens\" and a \"partial lens\" seem rather similar in name and in concept. How do they differ? In what circumstances do I need to use one or the other?
Tagging Scala
Below are the scaladocs for Scalaz's LensFamily
and PLensFamily
, with emphasis added on the diffs.
Lens:
A Lens Family, offering a purely functional means to access and retrieve a field transitioning from type
B1
to typeB2
in a record simultaneously transitioning from typeA1
to typeA2
.scalaz.Lens
is a convenient alias for whenA1 =:= A2
, andB1 =:= B2
.The term "field" should not be interpreted restrictively to mean a member of a class. For example, a lens family can address membership of a
Set
.
Partial lens:
Partial Lens Families, offering a purely functional means to access and retrieve an optional field transitioning from type
B1
to typeB2
in a record that is simultaneously transitioning from typeA1
to typeA2
.scalaz.PLens
is a convenient alias for whenA1 =:= A2
, andB1 =:= B2
.The term "field" should not be interpreted restrictively to mean a member of a class. For example, a partial lens family can address the nth element of a
List
.
For those unfamiliar with scalaz, we should point out the symbolic type aliases:
type @>[A, B] = Lens[A, B]
type @?>[A, B] = PLens[A, B]
In infix notation, this means the type of a lens that retrieves a field of type B
from a record of type A
is expressed as A @> B
, and a partial lens as A @?> B
.
Argonaut (a JSON library) provides a lot of examples of partial lenses, because the schemaless nature of JSON means that attempting to retrieve something from an arbitrary JSON value always has the possibility of failure. Here are a few examples of lens-constructing functions from Argonaut:
def jArrayPL: Json @?> JsonArray
— Retrieves a value only if the JSON value is an arraydef jStringPL: Json @?> JsonString
— Retrieves a value only if the JSON value is a stringdef jsonObjectPL(f: JsonField): JsonObject @?> Json
— Retrieves a value only if the JSON object has the field f
def jsonArrayPL(n: Int): JsonArray @?> Json
— Retrieves a value only if the JSON array has an element at index n