What's the difference between a lens and a partial lens?

后端 未结 3 1425
南方客
南方客 2021-02-05 16:24

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

3条回答
  •  北海茫月
    2021-02-05 17:00

    Scalaz documentation

    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 type B2 in a record simultaneously transitioning from type A1 to type A2. scalaz.Lens is a convenient alias for when A1 =:= A2, and B1 =:= 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 type B2 in a record that is simultaneously transitioning from type A1 to type A2. scalaz.PLens is a convenient alias for when A1 =:= A2, and B1 =:= 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.

    Notation

    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

    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 array
    • def jStringPL: Json @?> JsonString — Retrieves a value only if the JSON value is a string
    • def 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

提交回复
热议问题