Copy constructors

The first solution is to provide a new init method that copies the current instance. This approach is called a copy constructor. Let's add our new init method and leverage it:

init(products: [FunctionalProduct], lastModified: Date) { 

self.products = products
self.lastModified = lastModified
}

init(productTracker: FunctionalProductTracker,
products: [FunctionalProduct]? = nil,
lastModified: Date? = nil) {

self.products = products ?? productTracker.products
self.lastModified = lastModified ?? productTracker.lastModified
}

We added the default init as well because by adding a new init method to our struct, we lost the benefit of automatic init generation. We also need to change our addNewProduct to accommodate these following changes:

func addNewProduct(item: FunctionalProduct) -> FunctionalProductTracker { 

return FunctionalProductTracker(productTracker: self,
products: self.products + [item])
}

Whenever we need to modify our object partially, we will be able to do so easily using this technique.