Skip to content

Instantly share code, notes, and snippets.

@fuzza
Created April 15, 2020 14:40
Show Gist options
  • Select an option

  • Save fuzza/d96252affb95ab9725690bd1a8aa71ce to your computer and use it in GitHub Desktop.

Select an option

Save fuzza/d96252affb95ab9725690bd1a8aa71ce to your computer and use it in GitHub Desktop.
Lenses
import Foundation
var model = Model(name: "Alex") // Model(name: "Alex")
model.name = "Hello" // error: cannot assign to property: 'name' setter is inaccessible
model[keyPath: \.name] = "Serge" // error: cannot assign through subscript: key path is read-only
let newModel = Model.lens.name.set("Serge")(model) // Model(name: "Serge")
import Foundation
public struct Lens<Whole, Part> {
public let get: (Whole) -> Part
public let set: (Part) -> (Whole) -> Whole
internal init(keyPath: WritableKeyPath<Whole, Part>) {
get = { $0[keyPath: keyPath] }
set = { part in
{
var new = $0
new[keyPath: keyPath] = part
return new
}
}
}
}
public struct Model {
fileprivate(set) public var name: String
public init(name: String) {
self.name = name
}
public enum lens {
static public var name: Lens<Model, String> { return Lens(keyPath: \Model.name) }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment