Created
April 15, 2020 14:40
-
-
Save fuzza/d96252affb95ab9725690bd1a8aa71ce to your computer and use it in GitHub Desktop.
Lenses
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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