nel

3925ee6eaa41031bac799de0f4f528ec?s=47 to4iki
December 09, 2018

 nel

3925ee6eaa41031bac799de0f4f528ec?s=128

to4iki

December 09, 2018
Tweet

Transcript

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

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

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

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

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

    5
  6. e.g. 2 /// GraphQL type’s fields enum UserField: String {

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

    name // id // } ! request runtime-error query([]) // { // } 7
  8. ! • ֓೦ϨϕϧͰ Nil or Cons(ଘࡏ͢Δ͔) Λҙࣝ͢Δඞཁ͕͋Δ • ܕ҆શͰ͸ͳ͍ !

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

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

  11. Nel(ͶΔ) 11

  12. Non Empty List 12

  13. NonEmptyList2 /// a data type which represents a non empty

    list of A. /// single element (head) and optional structure (tail). struct NonEmptyArray<T> { let head(T) let tail: [T] } 2 Swift͸ඪ४ܕͰList͕ଘࡏ͠ͳ͍ͷͰɺArrayΛࣄྫʹͯ͠ѻ͏ 13
  14. ! // [1, 2, 3] NonEmptyArray(head: 1, tail: [2, 3])

    14
  15. other solution enum NonEmptyArray<T> { case single(T) indirect case cons(T,

    NonEmptyArray<T>) } // [1, 2, 3] NonEmptyArray.cons(1, .cons(2, .single(3))) 15
  16. ۭͷঢ়ଶΛදݱͰ͖Δͷ͸Array ͚ͩͰ͸ͳ͍ΑͶ 16

  17. NonEmpty<C: Collection> struct NonEmpty<C: Collection> { var head: C.Element var

    tail: C init(_ head: C.Element, _ tail: C) { self.head = head self.tail = tail } } 17
  18. typealias NonEmptyArray<T> = NonEmpty<Array<T>> typealias NonEmptySet<T> = NonEmpty<Set<T>> where T:

    Hashable typealias NonEmptyDictionary<K, V> = NonEmpty<Dictionary<K, V>> where K: Hashable // etc... 18
  19. NonEmpty<C: Collection> Λඪ४ͷίϨΫγϣϯૢ࡞ʹ͚͍ۙͮͯ͘ 19

  20. (ུ) 20

  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
  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
  23. Demo 23

  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
  25. Advanced 25

  26. Validation(Nel) • Monad • Applicative Functor • https://typelevel.org/cats/datatypes/validated.html /// `Result`

    with success-value, `nel` as the failure type. enum Validated<Value, E: Swift.Error> { case valid(Value) case invalid(NonEmptyArray<E>) } 26
  27. Kotlin: arrow.Validated • https://arrow-kt.io/docs/datatypes/validated/ @higherkind sealed class Validated<out E, out

    A> : ValidatedOf<E, A> { data class Valid<out A>(val a: A) : Validated<Nothing, A>() data class Invalid<out E>(val e: E) : Validated<E, Nothing>() } 27
  28. e.g let validatedPassword: Validated<String, PasswordInputError> ... switch validatedPassword { case

    .valid(let value): print(value) case .invalid(let errors): // e.g. preset `errors.first` messages } 28
  29. Conclusion • Ϧετ͸ ۭ or ۭͰ͸ͳ͍ͷ 2छྨͷঢ়ଶ͕ଘࡏ͢Δ • NonEmpty<C: Collection>

    ʹΑΓɺܕϨϕϧͰ ۭͰ͸ͳ͍ ঢ়ଶΛ୲อ͢Δ͜ͱ͕Ͱ͖Δ • ڊਓͷݞ(ଟݴޠͰͷ࣮૷ྫ)ʹ৐͍ͬͯ͜͏ 29
  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

  31. Thanks 31