Lenses

In the previous section, we covered copy constructors. Here, we will examine a functional structure called a lens. Simply put, lenses are functional getters and setters that are implemented for a whole object and its parts:

  • Getters: We can look through the lens at an immutable object to get its parts
  • Setters: We can use the lens to change a part of an immutable object

Let's implement a lens:

struct Lens<Whole, Part> { 
let get: (Whole) -> Part
let set: (Part, Whole) -> Whole
}

Let's use it to change our FunctionalProduct object to get and set the producer property:

let prodProducerLens: Lens<FunctionalProduct, Producer> = 
Lens(get: { $0.producer },
set: {
FunctionalProduct(name: $1.name,
price: $1.price,
quantity: $1.quantity,
producer: $0) })

Let's change the producer for mexBananas:

let mexBananas2 = prodProducerLens.set(Producer(name: "QAZ",
address: "Yucatan,
Mexico"), mexBananas)

Through our lens, we can change it as shown in the preceding code.

Let's examine another example. Suppose that we have a Producer object as follows:

let chineeseProducer = Producer(name: "KGJ", 
address: "Beijing, China")

We want to change the address:

let producerAddressLens: Lens<Producer, String> = 
Lens(get: {
$0.address },
set: {
Producer(name: $1.name,
address: $0) })

let chineeseProducer2 = producerAddressLens.set("Shanghai, China", chineeseProducer)

Suppose that we had mexBananas2 and needed to have a Chinese banana producer, then we could use:

let chineeseBananaProducer = prodProducerLens.set(producerAddressLens.set("Shanghai, China", chineeseProducer), mexBananas2) 

This syntax does not look very simple, and it seems that we did not gain much after all. In the next section, we will simplify it.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset