Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Lens introduction

to4iki
February 18, 2018

Lens introduction

in `swift` implementation
see: https://github.com/to4iki/LensKit

to4iki

February 18, 2018
Tweet

More Decks by to4iki

Other Decks in Programming

Transcript

  1. getter • ΦϒδΣΫτS͔ΒAΛऔΓग़͢ • get: (S) -> A setter •

    ΦϒδΣΫτSͷ೚ҙͷ஋ΛAʹมߋ͢Δ • set: (S, A) -> S == set: (S) -> A -> S 9
  2. struct Lens<S, T> { private let _get: (S) -> T

    private let _set: (S, T) -> S init(get: @escaping (S) -> T, set: @escaping (S, T) -> S) func get(_ source: S) -> T func set(_ source: S, value: T) -> S } 12
  3. struct User { let name: String } let user =

    User(name: "hoge") let nameLens = Lens<User, String>( get: { $0.name }, set: { User(name: $1) } ) nameLens.get(user) // "hoge" nameLens.set("fuga") // User(name:"fuga)" 14
  4. ωετͨ͠σʔλͷ͋ΔҰ෦ ͚ͩΛมߋ͍ͨ͠ struct Street { let name: String } struct

    Address { let street: Street } struct Company { let address: Address } struct Employee { let company: Company } let employee = Employee(company: Company(address: Address(street: Street(name: "street")))) 16
  5. struct Lens<S, T> { ... func compose<U>(_ other: Lens<T, U>)

    -> Lens<S, U> { return Lens<S, U>( get: { (source: S) -> U in other.get(self.get((source))) }, set: { (source: S, value: U) -> S in self.set(source, value: other.set(self.get(source), value: value)) } ) } } 19
  6. (operator΋ఆٛ͠ͱ͘) /// Left-to-Right Composition infix operator >>> : MultiplicationPrecedence func

    >>> <S, T, U>(lhs: Lens<S, T>, rhs: Lens<T, U>) -> Lens<S, U> { return lhs.compose(rhs) } 20
  7. ! let nameLens = Lens<Street, String>(get: { $0.name }, set:

    { Street(name: $1) } ) let streetLens = Lens<Address, Street> ... let addressLens = Lens<Company, Address> ... let companyLens = Lens<Employee, Company> ... let lens: Lens<Employee, String> = companyLens >>> addressLens >>> streetLens >>> nameLens let employee = Employee(company: Company(address: Address(street: Street(name: "street")))) let updatedEmployee = lens.modify(employee) { $0.capitalized } // Employee(Company(Address(Street(name: "Street") 22
  8. Conclusion • Lens ͸ ͍͢͝getter/setter • ෆมߏ଄Λอͪͳ͕Β • ਂ͍ߏ଄Ͱ΋ •

    ஋ʹΞΫηεग़དྷΔ • Ϣʔεέʔε͸ਖ਼௚೉͍͠ • ςετ࣌ͷαϙʔτͱͯ͠࢖͏? 24