Slide 1

Slide 1 text

4XJGUͰ-FOT ؔ੢ϞόΠϧΞϓϦݚڀձ !NBUVZVKJ

Slide 2

Slide 2 text

@matuyuji safx-dev.blogspot.jp

Slide 3

Slide 3 text

-FOT

Slide 4

Slide 4 text

-FOT struct Lens { let get: Whole -> Part let set: (Whole, Part) -> Whole } ෆมͳߏ଄ମ΁ͷࢀরɾมߋΛ؆୯ʹ͢Δ΋ͷ

Slide 5

Slide 5 text

struct Lens { let get: Whole -> Part let set: (Whole, Part) -> Whole } let p = Person(name: “Yamamoto", address: Address(city: "Osaka")) struct Person { let name: String let address: Address } struct Address { let city: String } let name = Lens( get: { $0.name }, set: { Person(name: $1, address: $0.address) } ) name.get(p) // => “Yamamoto” name.set(p, “Nakayama") // => Person(Nakayama, Osaka)

Slide 6

Slide 6 text

let p = Person(name: “Yamamoto", address: Address(city: "Osaka")) let name = Lens( get: { $0.name }, set: { Person(name: $1, address: $0.address) } ) let address = Lens( get: { $0.address }, set: { Person(name: $0.name, address: $1) } ) let city = Lens
( get: { $0.city }, set: { Address(city: $1) } ) let composed = address.compose(city) composed.get(p) // "Osaka" composed.set(p, "Tokyo") // Person(Yamamoto, Tokyo)

Slide 7

Slide 7 text

$PNQPTF func compose(other: Lens) -> Lens { return Lens( get: { other.get(self.get($0)) }, set: { obj, newValue in return self.set(obj, other.set(self.get(obj), newValue)) } ) } struct Lens { let get: Whole -> Part let set: (Whole, Part) -> Whole }

Slide 8

Slide 8 text

8IZVTF-FOT

Slide 9

Slide 9 text

let newValue = SomeStruct(issuesUrl: oldValue.issuesUrl, hasWiki: oldValue.hasWiki, forksUrl: oldValue.forksUrl, mirrorUrl: oldValue.mirrorUrl, subscriptionUrl: oldValue.subscriptionUrl, sshUrl: oldValue.sshUrl, collaboratorsUrl: oldValue.collaboratorsUrl, updatedAt: oldValue.updatedAt, pullsUrl: oldValue.pullsUrl, fullName: newName, issueCommentUrl: oldValue.issueCommentUrl, statusesUrl: oldValue.statusesUrl, id: oldValue.id, keysUrl: oldValue.keysUrl, size: oldValue.size, tagsUrl: oldValue.tagsUrl, issueEventsUrl: oldValue.issueEventsUrl, downloadsUrl: oldValue.downloadsUrl, assigneesUrl: oldValue.assigneesUrl, contentsUrl: oldValue.contentsUrl, hasPages: oldValue.hasPages, gitRefsUrl: oldValue.gitRefsUrl, score: oldValue.score, cloneUrl: oldValue.cloneUrl, watchersCount: oldValue.watchersCount, gitTagsUrl: oldValue.gitTagsUrl, milestonesUrl: oldValue.milestonesUrl, stargazersCount: oldValue.stargazersCount, homepage: oldValue.homepage, branchesUrl: oldValue.branchesUrl, fork: oldValue.fork, commitsUrl: oldValue.commitsUrl, releasesUrl: oldValue.releasesUrl, description: oldValue.description, hasDownloads: oldValue.hasDownloads, labelsUrl: oldValue.labelsUrl, eventsUrl: oldValue.eventsUrl, contributorsUrl: oldValue.contributorsUrl, htmlUrl: oldValue.htmlUrl, forks: oldValue.forks, compareUrl: oldValue.compareUrl, treesUrl: oldValue.treesUrl, watchers: oldValue.watchers, svnUrl: oldValue.svnUrl, forksCount: oldValue.forksCount, mergesUrl: oldValue.mergesUrl, hasIssues: oldValue.hasIssues, blobsUrl: oldValue.blobsUrl, languagesUrl: oldValue.languagesUrl, notificationsUrl: oldValue.notificationsUrl, hooksUrl: oldValue.hooksUrl, openIssuesCount: oldValue.openIssuesCount, commentsUrl: oldValue.commentsUrl, name: oldValue.name, language: oldValue.languagesUrl, url: oldValue.url, createdAt: oldValue.createdAt, archiveUrl: oldValue.archiveUrl, pushedAt: oldValue.pushedAt, defaultBranch: oldValue.defaultBranch, teamsUrl: oldValue.teamsUrl, openIssues: oldValue.openIssues, gitCommitsUrl: oldValue.gitCommitsUrl, subscribersUrl: oldValue.subscribersUrl, stargazersUrl: oldValue.stargazersUrl, gitUrl: oldValue.gitUrl)

Slide 10

Slide 10 text

let newValue = fullName.set(oldValue, newName)

Slide 11

Slide 11 text

4XJGU*%- -FOTZ

Slide 12

Slide 12 text

let name = Lens( get: { $0.name }, set: { Person(name: $1, address: $0.address) } ) let address = Lens( get: { $0.address }, set: { Person(name: $0.name, address: $1) } ) let city = Lens
( get: { $0.city }, set: { Address(city: $1) } )

Slide 13

Slide 13 text

TBGYTXJGUJEM w $VTUPN4USJOH$POWFSUJCMF w +40/FODPEFEFDPEF w .FNCFSXJTFJOJUJBMJ[FS w &RVBUBCMF w "1*,JU)FMQFS w -FOT ؔ੢Ϟό #4

Slide 14

Slide 14 text

struct Person: Lensy { let name: String let address: Address } struct Address: Lensy { let city: String } swift_idl public struct Person { public let name: String public let address: Address public struct Lenses { public static let name = Lens( g: { $0.name }, s: { (this, newValue) in Person(name: newValue, address: this.address) } ) public static let address = Lens( g: { $0.address }, s: { (this, newValue) in Person(name: this.name, address: newValue) } ) } public static var $: PersonLensHelper { return PersonLensHelper(lens: createIdentityLens()) } } public struct PersonLensHelper: LensHelperType { public typealias Part = Person public let lens: Lens public init(lens: Lens) { self.init(lens: lens) } public var name: LensHelper { return LensHelper(parent: self, lens: Person.Lenses.name) } public var address: AddressLensHelper { return AddressLensHelper(parent: self, lens: Person.Lenses.address) } } public struct Address { public let city: String public struct Lenses { public static let city = Lens
( g: { $0.city }, s: { (this, newValue) in Address(city: newValue) } ) } public static var $: AddressLensHelper
{ return AddressLensHelper
(lens: createIdentityLens()) } } public struct AddressLensHelper: LensHelperType { public typealias Part = Address public let lens: Lens public init(lens: Lens) { self.init(lens: lens) } public var city: LensHelper { return LensHelper(parent: self, lens: Address.Lenses.city) } }

Slide 15

Slide 15 text

-FOT)FMQFS Array subscription & Result Code completion

Slide 16

Slide 16 text

TBGY-FOTZ protocol LensType { typealias Whole typealias Part var get: Whole -> LensResult { get } var set: (Whole, Part) -> LensResult { get } } enum LensResult { case OK(Element) case Error(LensErrorType) }