Slide 1

Slide 1 text

SwiftͰ ߴΧΠϯυଟ૬ (Higher Kinded Types) 2018/06/21 potatotips #52 (iOS/Android։ൃTipsڞ༗ձ) Yasuhiro Inami / @inamiy

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

ߴΧΠϯυଟ૬ʢͷ༧උ஌ࣝʣ • ܕίϯετϥΫλ ʹ ʮܕʯΛҾ਺ʹऔΓɺʮܕʯΛฦ͢ • ྫɿ Optional = 1 + X ʹ͓͚Δ "Optional" ͸ɺ ʮܕ → ܕʯʹม׵͢Δʮܕؔ਺ʯ • ΧΠϯυ ʹ ʮܕͷܕʯ • ྫɿ Optional : *ɹʢܕʣ • ྫɿ Optional : * -> *ɹʢܕ → ܕʣ

Slide 4

Slide 4 text

ߴΧΠϯυଟ૬ • ߴΧΠϯυ ʹ ʮΧΠϯυʯΛҾ਺ʹऔΓɺʮΧΠϯυʯΛ ฦ͢ • ྫɿ Functor : (* -> *) -> *ɹʢܕؔ਺ → ܕʣ • Functor ͷΑ͏ͳॻ͖ํ͕Մೳ • ʮܕίϯετϥΫλʯΛҾ਺ʹऔΔʮܕʯΛ࡞Δ͜ͱ ͕Ͱ͖Δ ❗❗

Slide 5

Slide 5 text

ߴΧΠϯυଟ૬ͷྫ Haskell: class Functor f where fmap :: (a -> b) -> f a -> f b Scala (scalaz): trait Functor[F[_]] extends InvariantFunctor[F] { self => def map[A, B](fa: F[A])(f: A => B): F[B] ... }

Slide 6

Slide 6 text

Swift 4.2 ݱࡏɺ ߴΧΠϯυଟ૬͸ະαϙʔτ ʢSwift 5 Ͱ΋αϙʔτ༧ఆ͸͓ͦΒ͘ͳ͍1ʣ 1 WWDC 2018ͷSwiftϥϘʹͯԹ౓ײΛ֬ೝɻ·ͨɺGenerics Manifesto Ͱ΋ "Unlikely" ͷهड़ɻ

Slide 7

Slide 7 text

!

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

arrow-kt/arrow • https://github.com/arrow-kt/arrow • Functor, Applicative, Monad ͳͲͷ جຊతͳtypeclassΛαϙʔτ • ಺෦Ͱ KindedJ ʢJavaͰlightweight HKTʣΛ࢖༻ • Annotation processing ͱ generic interface ͕ڧྗ (Swiftʹ͸ͳ͍)

Slide 11

Slide 11 text

SwiftͰHKTΛ࣮ݱ͢Δʹ͸ʁ • SwiftͰHigher Kinded PolymorphismΛ࣮ݱ͢Δ - Qiita • Emulating HKT in Swift • ͲͷΞϓϩʔν΋ɺ Lightweight higher-kinded polymorphism ʢ࿦จʣ͕ݩʹͳ͍ͬͯΔ

Slide 12

Slide 12 text

Lightweight HKT • ʮܕίϯετϥΫλΛɺܕύϥϝʔλʹద༻͢ΔʯͨΊͷ޻ ෉ͱͯ͠ɺ ୅༻ͷܕʢλάʣΛ༻ҙ͢Δ • MyClass ͱॻ͚ͳ͍୅ΘΓʹ enum ForArray {} Λ༻ҙ͠ɺMyClass ͱॻ͘ • ͨͩ͠ɺ ForArray ࣗମ͸ܕม਺Λ࣋ͨͳ͍ͨΊɺ ܕద༻Λ දݱ͢ΔͨΊͷܕ struct Kind Λಋೖͯ͠ɺ Kind 㱻 Array ૬ޓม׵Մೳʹ͢Δ

Slide 13

Slide 13 text

/// `F` ʹ `A1` Λద༻ͯ͠ɺ `F` Λදݱʢ࣮ࡍͷܕ͸ `Any` Ͱফڈʣ public struct Kind { internal let _value: Any public init(_ value: Any) { self._value = value } } /// `Kind` 㱻 `Array` ͳͲͷ૬ޓม׵ϓϩτίϧ public protocol KindConvertible { associatedtype F associatedtype A1 var kind: Kind { get } init(kind: Kind) }

Slide 14

Slide 14 text

extension Array: KindConvertible { public typealias F = ForArray public typealias A1 = Element public var kind: Kind { // `Array` -> `Kind` ʹม׵ return Kind(self as Any) } public init(kind: Kind) { // ܕফڈͨ͠த਎Λμ΢ϯΩϟετͯ͠औΓग़͢ //ʢ`ForArray` ͱ 1:1ʹඥ෇͍͍ͯΔͷͰ҆શʣ self = kind._value as! Array } }

Slide 15

Slide 15 text

Kind Λ࢖ͬͯɺ Functor Λఆٛͯ͠ΈΔɻ public protocol Functor { associatedtype F associatedtype A1 // Note: `Kind` ͸ `Self` ͷ୅༻ func fmap(_ f: @escaping (A1) -> B) -> Kind } ͜͜Ͱɺ Kind 㱻 Array ͕૬ޓม׵͢Δͷ ͰɺArray ͷ୅ΘΓʹ Kind Λ Functor ʹద߹ͯ͠ΈΔɻ

Slide 16

Slide 16 text

extension Kind: Functor where F == ForArray { func fmap(_ f: (A1) -> B) -> Kind { // ͜͜Ͱ͸ `Array.map` Λͦͷ··࠶ར༻ɻ // ͨͩ͠ɺ`Kind.fmap`ʹมߋ͢Δʹ͸ɺ // `.value` Ͱ unwrap ͔ͭ // `.kind` (= `Kind.init()`) Ͱ re-wrap ͢Δඞཁ͋Γɻ return self.value.map(f).kind } } let result = [1, 2, 3].kind .fmap { "\($0)!" }.value result == ["1!", "2!", "3!"]

Slide 17

Slide 17 text

extension Kind: Functor where F == ForArray { /* ࣮૷1 */ } extension Kind: Functor where F == ForOptional { /* ࣮૷2 */ } extension Kind: Functor where F == ForTree { /* ࣮૷3 */ } // ERROR: Swift Conflicting conformance of // 'Kind' to protocol 'Functor'; // there cannot be more than one conformance, // even with different conditional bounds. ɹ ⚠ ͨͩ͠ɺҟͳΔ੍໿৚݅ʹର͢Δadhocͳ࣮૷௥Ճ͸Τϥʔ ʹͳΔͷͰ஫ҙʢGeneric protocolͳΒղܾͯ͘͠ΕΔʣ

Slide 19

Slide 19 text

ྫɿϞφυ let arr = [1, 2, 3].kind .bind { [$0 * 3, $0 * 5 ].kind }.value arr == [3, 5, 6, 10, 9, 15] let list = List.cons(1, .cons(2, .cons(3, .nil))).kind .bind { List.cons($0 * 3, .cons($0 * 5, .nil)).kind } .value list == List.cons(3, .cons(5, .cons(6, .cons(10, .cons(9, .cons(15, .nil)))))) ܕ͕ҟͳ͍ͬͯͯ΋ɺฦΓ஋͸લճͷίϯςφܕΛҡ࣋

Slide 20

Slide 20 text

ྫɿࣗવม׵ // `Array` ͔Β `List` ΁ͷࣗવม׵ let list = [1, 2, 3].kind .naturalTransform { List($0.value).kind } .value list == List.cons(1, .cons(2, .cons(3, .nil)))

Slide 21

Slide 21 text

HigherKindSwift https://github.com/inamiy/HigherKindSwift

Slide 22

Slide 22 text

Future TODO (?) • Monad Transformer • Free / Cofree • Yoneda / Coyoneda • Adjunction • Lan / Ran (Kan Extension) • iOSDC 2018 CfP ʮݍ࿦ͱSwift΁ͷԠ༻ʯ

Slide 23

Slide 23 text

·ͱΊ • ܕίϯετϥΫλɺΧΠϯυɺߴΧΠϯυ • Lightweight HKT • Arrow (Kotlin) ྑͦ͞͏ • Swiftʹཉ͍͠ػೳ (HKTҎલ) • Generic protocol (e.g. protocol Functor) • Parameterized extensions (e.g. where T: Optional)

Slide 24

Slide 24 text

Thanks! Yasuhiro Inami @inamiy