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

nel

to4iki
December 09, 2018

 nel

to4iki

December 09, 2018
Tweet

More Decks by to4iki

Other Decks in Programming

Transcript

  1. "ͶΔ" ͸͍͍ͧ
    2018.12.9
    #shinjukult
    @to4iki
    1

    View Slide

  2. Me
    • @to4iki
    • 
    • AbemaTV
    • builderscon
    2

    View Slide

  3. ಥવͰ͕͢ɺ
    ഑ྻૢ࡞ʹؔͯ͠ɺ
    3

    View Slide

  4. e.g. 1
    if xs.isEmpty {
    // fallback processing.
    } else {
    // anything.
    }
    4

    View Slide

  5. e.g. 1
    guard !xs.isEmpty else {
    fatalError("unrechable.")
    }
    // anything
    5

    View Slide

  6. e.g. 2
    /// GraphQL type’s fields
    enum UserField: String {
    case id, name, email
    }
    /// build up a query
    func query(_ fields: Set) -> String {
    return (["{\n"] + fields.map { " \($0.rawValue)\n" } + ["}\n"])
    .joined()
    }
    6

    View Slide

  7. e.g. 2
    !
    request success
    query([.id, .name])
    // {
    // name
    // id
    // }
    !
    request runtime-error
    query([])
    // {
    // }
    7

    View Slide

  8. !
    • ֓೦ϨϕϧͰ Nil or Cons(ଘࡏ͢Δ͔) Λҙࣝ͢Δඞཁ͕͋Δ
    • ܕ҆શͰ͸ͳ͍
    !
    8

    View Slide

  9. ۭ഑ྻͱ͍͏ɺ
    ಉ͡഑ྻͳΜ͚ͩͲ
    ͦͷঢ়ଶ(ཁૉ͕༗Δ͔ແ͍͔)Λ
    ҙࣝ͠ͳ͍ͱ͍͚ͳ͍
    9

    View Slide

  10. ۭͱ͍͏ঢ়ଶ͕ى͜Γ͑ͳ͍
    ഑ྻ͕͋Ε͹Α͍ͷͰ͸
    10

    View Slide

  11. Nel(ͶΔ)
    11

    View Slide

  12. Non Empty List
    12

    View Slide

  13. NonEmptyList2
    /// a data type which represents a non empty list of A.
    /// single element (head) and optional structure (tail).
    struct NonEmptyArray {
    let head(T)
    let tail: [T]
    }
    2 Swift͸ඪ४ܕͰList͕ଘࡏ͠ͳ͍ͷͰɺArrayΛࣄྫʹͯ͠ѻ͏
    13

    View Slide

  14. !
    // [1, 2, 3]
    NonEmptyArray(head: 1, tail: [2, 3])
    14

    View Slide

  15. other solution
    enum NonEmptyArray {
    case single(T)
    indirect case cons(T, NonEmptyArray)
    }
    // [1, 2, 3]
    NonEmptyArray.cons(1, .cons(2, .single(3)))
    15

    View Slide

  16. ۭͷঢ়ଶΛදݱͰ͖Δͷ͸Array
    ͚ͩͰ͸ͳ͍ΑͶ
    16

    View Slide

  17. NonEmpty
    struct NonEmpty {
    var head: C.Element
    var tail: C
    init(_ head: C.Element, _ tail: C) {
    self.head = head
    self.tail = tail
    }
    }
    17

    View Slide

  18. typealias NonEmptyArray
    = NonEmpty>
    typealias NonEmptySet
    = NonEmpty> where T: Hashable
    typealias NonEmptyDictionary =
    NonEmpty> where K: Hashable
    // etc...
    18

    View Slide

  19. NonEmpty
    Λඪ४ͷίϨΫγϣϯૢ࡞ʹ͚͍ۙͮͯ͘
    19

    View Slide

  20. (ུ)
    20

    View Slide

  21. !
    overload non-nil property
    extension NonEmpty {
    /// overload non-nil
    var first: C.Element {
    return self.head
    }
    }
    extension NonEmpty where C: BidirectionalCollection {
    /// overload non-nil
    var last: C.Element {
    return self.tail.last ?? self.head
    }
    }
    21

    View Slide

  22. Array
    let xs = [1, 2, 3]
    xs.first.map { $0 + 1 } ?? 0
    xs.last! + 1 // unsafe
    !
    NonEmptyArray
    let xs = NonEmptyArray(1, 2, 3)
    xs.first + 1
    xs.last + 1
    22

    View Slide

  23. Demo
    23

    View Slide

  24. Other lang
    • Haskel: Data.List.NonEmpty
    • https://hackage.haskell.org/package/semigroups-0.16.0.1/docs/Data-List-
    NonEmpty.html
    • Elm: List.Nonempty
    • https://package.elm-lang.org/packages/mgold/elm-nonempty-list/3.1.0/List-
    Nonempty
    • scalaz / cats
    • functional java
    • etc...
    24

    View Slide

  25. Advanced
    25

    View Slide

  26. Validation(Nel)
    • Monad
    • Applicative Functor
    • https://typelevel.org/cats/datatypes/validated.html
    /// `Result` with success-value, `nel` as the failure type.
    enum Validated {
    case valid(Value)
    case invalid(NonEmptyArray)
    }
    26

    View Slide

  27. Kotlin: arrow.Validated
    • https://arrow-kt.io/docs/datatypes/validated/
    @higherkind sealed class Validated : ValidatedOf {
    data class Valid(val a: A) : Validated()
    data class Invalid(val e: E) : Validated()
    }
    27

    View Slide

  28. e.g
    let validatedPassword: Validated ...
    switch validatedPassword {
    case .valid(let value):
    print(value)
    case .invalid(let errors):
    // e.g. preset `errors.first` messages
    }
    28

    View Slide

  29. Conclusion
    • Ϧετ͸ ۭ or ۭͰ͸ͳ͍ͷ 2छྨͷঢ়ଶ͕ଘࡏ͢Δ
    • NonEmpty ʹΑΓɺܕϨϕϧͰ ۭͰ͸ͳ͍
    ঢ়ଶΛ୲อ͢Δ͜ͱ͕Ͱ͖Δ
    • ڊਓͷݞ(ଟݴޠͰͷ࣮૷ྫ)ʹ৐͍ͬͯ͜͏
    29

    View Slide

  30. SeeAlso
    • https://www.pointfree.co/episodes/ep20-nonempty
    • http://eed3si9n.com/learning-scalaz/ja/Validation.html
    • http://xuwei-k.github.io/scalaz-docs/validation.html
    30

    View Slide

  31. Thanks
    31

    View Slide