🏷 Tagged

3925ee6eaa41031bac799de0f4f528ec?s=47 to4iki
April 19, 2018

🏷 Tagged

potatotips #50
2018/04/19
https://potatotips.connpass.com/event/82476/

`Tagged`を使ったId型作成の話
https://github.com/pointfreeco/swift-tagged

3925ee6eaa41031bac799de0f4f528ec?s=128

to4iki

April 19, 2018
Tweet

Transcript

  1. ! Tagged potatotips #50 2018/04/19 @to4iki 1

  2. Me • Takezawa Toshiki • @to4iki • iOS Engineer •

    builderscon • ! ☕ ♨ 2
  3. IdΛܕԽ͍ͨ͠ (user.id ͱ subscription.idΛ۠ผ) 3

  4. ex. 1 struct User: Decodable { typealias Id = String

    let id: Id let subscriptionId: Subscription.Id } struct Subscription: Decodable { typealias Id = String let id: Id } 4
  5. ! not type-safety // typealias User.Id = String func fetchUser(with

    id: User.Id) -> User? fetchUser(with: user.id) // OK fetchUser(with: user.subscriptionId) // OK fetchUser(with: "123") // OK 5
  6. ! type-safety struct User: Decodable { struct Id: Decodable {

    let value: String } ... } func fetchUser(with id: User.Id) -> User? fetchUser(with: user.id) // OK fetchUser(with: user.subscriptionId) // Compile Error fetchUser(with: "123") // Compile Error 6
  7. ex. 2 { "id": "abc", "subscriptionId": "123" } // decode

    to `User` let decoder = JSONDecoder() let user = try! decoder.decode(User.self, from: Data(json.utf8)) 7
  8. ! DecodingError.typeMismatch at User.Id Fatal error: 'try!' expression unexpectedly raised

    an error: Swift.DecodingError.typeMismatch(Swift.Dictionary<Swift.Strin g, Any>, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "id", intValue: nil)], debugDescription: ... 8
  9. ! DecodableΛ໌ࣔతʹ࣮૷͢Δ struct User: Decodable { struct Id: Decodable {

    let value: String init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() self.value = try container.decode(String.self) } } ... } 9
  10. ΋ͬͱεϚʔτʹղܾͰ͖ͳ͍͔ͳ 10

  11. SE-0143: Conditional Conformance1 /// Swift4 /// Returns `true` if these

    arrays contain the same elements. public func ==<Element>(lhs: [Element], rhs: [Element]) -> Bool where Element : Equatable /// Swift4.1 extension Array: Equatable where Element: Equatable { static func ==(lhs: Array<Element>, rhs: Array<Element>) -> Bool } [1,2,3] == [1,2,3] // ok 1 https://github.com/apple/swift-evolution/blob/master/proposals/0143-conditional-conformances.md https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md 11
  12. Conditional2 Array<Element>ʹ͓͍ͯɺElement͕Equatableͳ৔߹ʹݶΓ Conformance Array<Element>΋Equatableద߹͢Δ 2 આ໌্ͷҰྫͰ͢ 12

  13. Tagged<Tag, RawValue> https://github.com/pointfreeco/swift-tagged 13

  14. use Tagged struct User: Decodable, Equatable... { typealias Id =

    Tagged<User, String> let id: Id let subscriptionId: Subscription.Id } struct Subscription: Decodable, Equatable... { typealias Id = Tagged<Subscription, String> let id: Id } 14
  15. use Tagged "Decodable" let decoder = JSONDecoder() let user =

    try! decoder.decode(User.self, from: Data(json.utf8)) "Equatable" user1 == user2 // OK 15
  16. https://github.com/pointfreeco/swift-tagged/blob/master/Sources/Tagged/Tagged.swift public struct Tagged<Tag, RawValue> { public var rawValue: RawValue

    public init(rawValue: RawValue) { self.rawValue = rawValue } } extension Tagged: RawRepresentable { } 16
  17. https://github.com/pointfreeco/swift-tagged/blob/master/Sources/Tagged/Tagged.swift extension Tagged: Comparable where RawValue: Comparable { extension Tagged:

    Decodable where RawValue: Decodable { extension Tagged: Encodable where RawValue: Encodable { extension Tagged: Hashable where RawValue: Hashable { extension Tagged: Numeric where RawValue: Numeric { extension Tagged: ExpressibleByStringLiteral where RawValue: ExpressibleByStringLiteral { ... 17
  18. Conclusion • Swift 4.1 Conditional Conformance ʹΑΓܕͷදݱྗ͕๛ ͔ʹͳͬͨ • Tagged

    Λ࢖͏͜ͱͰϓϦϛςΟϒ3ͳܕΛ؆୯ʹܕԽ͢Δ͜ ͱ͕Ͱ͖Δ 3 ೚ҙͷܕͰߏΘͳ͍͕ຊεϥΠυͷྫʹԊͬͯ͜ͷΑ͏ʹදݱ͍ͯ͠Δ 18
  19. SeeAlso • Swift 4.1ͷConditional ConformanceͱδΣωϦΫεͷະདྷ • https://twitter.com/koher/status/985127876507860993 • Conditional Conformance

    in the Standard Library • https://swift.org/blog/conditional-conformance/ 19
  20. Thanks 20