a Lens library
Inspired by Scala julien-truffaut/Monocle.
- Swift 4.0 or later
- Xcode 9.0 or later
- Insert
github "to4iki/Monocle"to your Cartfile. - Run
carthage update. - Link your app with
Monocle.frameworkinCarthage/Checkouts.
This swift struct already provides getters and setters, but modifying nested object is verbose which makes code difficult to understand and reason about. Some examples:
struct Street { let name: String }
struct Address { let street: Street }
struct Company { let address: Address }
struct Employee { let company: Company }Need to set the first character of company street name address in upper case
let employee: Employee = ...
Employee(company:
Company(address:
Address(street:
Street(name: employee.company.address.street.name.capitalizedString)
)
)
)Use lens:
let _name: Lens<Street, String> = Lens(get: { $0.name }, set: { Street(name: $1) })
let _street: Lens<Address, Street> = Lens(get: { $0.street }, set: { Address(street: $1) })
let _address: Lens<Company, Address> = Lens(get: { $0.address }, set: { Company(address: $1) })
let _company: Lens<Employee, Company> = Lens(get: { $0.company }, set: { Employee(company: $1) })
(_company.compose(_address.compose(_street).compose(_name))).modify(employee) { $0.capitalizedString }
// => operator syntax
(_company >>> _address >>> _street >>> _name).modify(employee) { $0.capitalizedString }Prism is like a "Lens began to be expressed fail"
Use prism:
let stringToInt: Prism<String, Int> = Prism(getOption: { Int($0) }, reverseGet: { String($0) })stringToInt.getOption("1") // .Some(1)
stringToInt.getOption("") // .None
stringToInt.reverseGet(1) // "1"
stringToInt.modify("1") { $0 + 100 } // .Some(101)
stringToInt.modify("") { $0 + 100 } // .None