༗ݶΦʔτϚτϯ • ༗ݶΦʔτϚτϯ • ભҠؔͷΈ (s, a) -> s • Mealy Machine • ભҠؔ (s, a) -> s • ग़ྗؔ (s, a) -> b • Moore Machine • ભҠؔ (s, a) -> s • ग़ྗؔ s -> b ঢ়ଶΛཧ͍ͨ࣌͠ʹ׆༻͖͢
Binary Gap A binary gap within a positive integer N is any maximal sequence of consecutive zeros that is surrounded by ones at both ends in the binary representation of N. Ex: 9 = 1001 → 2
A binary gap within a positive integer N is any maximal sequence of consecutive zeros that is surrounded by ones at both ends in the binary representation of N. Ex: 9 = 1001 → 2 Started Zero One Binary Gap
Visual Format Language class func constraints(withVisualFormat format: String, options opts: NSLayoutFormatOptions = [], metrics: [String : Any]?, views: [String : Any]) -> [NSLayoutConstraint] "H:|-15-[iconImageView(30)]-[appNameLabel]-[skipButton]-15-|" Direction Start Line Number Label [ ] ( ) End
εςʔτͱΠϕϯτΛఆٛ enum RegistrationState { case root case registerRoot case profileRegister case startWithMercari case emailLogin case atteLogin case home } enum RegistrationEvent: Hashable { case showRegisterRoot(loginMode: RootViewController.LoginMode?) case registerWithFacebook(profile: FacebookProfile?) case startWithMercari(resource: MercariIdResource?, tokenPair: TokenPair?, showsCloseButton: Bool) case loginWithEmail(showsCancelButton: Bool) case loginWithAtte(resource: MercariIdResource?, tokenPair: TokenPair?) case loginAndShowHome(tokenPair: TokenPair?, userId: Int64, hasMercariItem: Bool) }
ભҠؔ (aka Reducer) • ༗ݶΦʔτϚτϯ • ભҠؔͷΈ (s, a) -> s • Mealy Machine • ભҠؔ (s, a) -> s • ग़ྗؔ (s, a) -> b • Moore Machine • ભҠؔ (s, a) -> s • ग़ྗؔ s -> b
ঢ়ଶ͖ͷܭࢉʢStateful Computationʣ ঢ়ଶ͖ͷܭࢉͱɺ͋Δঢ়ଶΛऔͬͯɺߋ৽͞Εͨঢ়ଶͱҰॹʹܭࢉ݁ՌΛ ฦؔ͢ͱͯ͠දݱͰ͖Δɿ s -> (s, a) class State { private let run: (S) -> (S, A) init(f: @escaping (S) -> (S, A)) { self.run = f } func run(s: S) -> (S, A) { return self.run(s) } }
εςʔτϞφυ ঢ়ଶ͖ͷܭࢉͱɺ͋Δঢ়ଶΛऔͬͯɺߋ৽͞Εͨঢ়ଶͱҰॹʹܭࢉ݁ՌΛ ฦؔ͢ͱͯ͠දݱͰ͖Δɿ s -> (s, a) extension State { func map(g: @escaping (A) -> B) -> State { return State { s in let (s1, val) = self.run(s: s) return (s1, g(val)) } } func flatMap(g: @escaping (A) -> State) -> State { return State { s in let (s1, val) = self.run(s: s) return g(val).run(s: s1) } } }
MonadicAutomaton class MonadicAutomaton { typealias T = (A) -> State private var f : T init(f: @escaping T) { self.f = f } func transition(from: S, by: A) -> (S, B) { return f(by).run(s: from) } } ɹભҠؔ A -> State[S, B] A:ΠϯϓοτܕɺB: Ξτϓοτܕ A = ΠϕϯτenumɺB = UIViewController
εςʔτͱΠϕϯτΛఆٛ enum RState { case any case root case registerRoot case profileRegister case startWithMercari case emailLogin case atteLogin case home } enum REvent { case showRegisterRoot case registerWithFacebook(profile: FacebookProfile) case startWithMercari(resource: MercariIdResource, token: String) case loginWithEmail case loginWithAtte(resource: MercariIdResource, token: String) case loginAndShowHome(token: String, userId: Int64) } OptionalͰͳ͍ʂʂ
ભҠάϥϑΛఆٛ let transitionFunc: (REvent) -> State = { event in switch event { case .registerWithFacebook(let profile): let vc = ProfileRegisterViewController.make(withDependency: .init(facebookProfile: profile)) return State { s in let s1: RState = s == .registerRoot ? .profileRegister : .any return (s1, vc) //... } } let registrationMachine = MonadicAutomaton(f : transitionFunc) A S B A S B