$30 off During Our Annual Pro Sale. View Details »

計算ファースト vs. 型ファースト / Computation First vs. Type First

INA Lintaro
November 28, 2019

計算ファースト vs. 型ファースト / Computation First vs. Type First

詳しい説明はこちらにあります:
https://tarao.hatenablog.com/entry/type-first

INA Lintaro

November 28, 2019
Tweet

More Decks by INA Lintaro

Other Decks in Programming

Transcript

  1. ܭࢉϑΝʔετ vs. ܕϑΝʔετ
    ϓϩάϥϜ͞Μ:ʮసੜͨ͠Βূ໌ͩͬͨ݅ʯ
    ҏಸ ྛଠ࿠
    id:tarao @oarat
    2019-11-28
    ࣾ಺ٕज़ษڧձ
    (վగ൛)

    View Slide

  2. ܭࢉϑΝʔετͰߟ͑Δܕ

    View Slide

  3. ܕ͕ͳ͍ͱ
    let apply2 = (f, n) => f(f(n))
    apply2(1, 3)
    Uncaught TypeError: f is not a function
    let omega = (x) => x(x)
    omega(omega)
    Uncaught RangeError: Maximum call stack size ex-
    ceeded

    View Slide

  4. ॻ͍ͯΑ͍ࣜΛ੍ݶ͢Δ
    ▶ ܕ෇͚نଇʹ߹கͨ͠΋ͷͷΈڐ͢
    ▶ ྫ: ୯७ܕ෇ϥϜμܭࢉ (STLC) [Church 1940]
    x : T ∈ Γ
    Γ ⊢ x : T (Var)
    Γ, x : ⌊S⌋ ⊢ m : T
    Γ ⊢ ((x:S) => m) : ⌊S⌋ → T (Abs)
    Γ ⊢ m : S → T Γ ⊢ n : S
    Γ ⊢ m(n) : T (App)
    ⌊(x:S) => T⌋ = ⌊S⌋ → ⌊T⌋
    (otherwise) ⌊T⌋ = T
    ڐ͞ΕΔྫ: (f: (a:A) => A) => (n: A) => f(f(n))
    f : A → A ∈ {f : A → A, n : A}
    f : A → A, n : A ⊢ f : A → A
    f : A → A ∈ {f : A → A, n : A}
    f : A → A, n : A ⊢ f : A → A
    n : A ∈ {f : A → A, n : A}
    f : A → A, n : A ⊢ n : A
    f : A → A, n : A ⊢ f(n) : A
    (App)
    f : A → A, n : A ⊢ f(f(n)) : A
    (App)
    f : A → A ⊢ ((n: A) => f(f(n))) : A → A
    (Abs)
    ⊢ ((f: (a:A) => A) => (n: A) => f(f(n))) : (A → A) → A → A
    (Abs)

    View Slide

  5. ॻ͍ͯΑ͍ࣜΛ੍ݶ͢Δ
    ▶ ܕ෇͚نଇʹ߹கͨ͠΋ͷͷΈڐ͢
    ▶ ྫ: ୯७ܕ෇ϥϜμܭࢉ (STLC) [Church 1940]
    x : T ∈ Γ
    Γ ⊢ x : T (Var)
    Γ, x : ⌊S⌋ ⊢ m : T
    Γ ⊢ ((x:S) => m) : ⌊S⌋ → T (Abs)
    Γ ⊢ m : S → T Γ ⊢ n : S
    Γ ⊢ m(n) : T (App)
    ⌊(x:S) => T⌋ = ⌊S⌋ → ⌊T⌋
    (otherwise) ⌊T⌋ = T
    ڐ͞Εͳ͍ྫ: (x: (a:A) => B) => x(x)
    x : A → B ∈ {x : A → B}
    x : A → B ⊢ x : A → B (Var)
    x : A ̸∈ {x : A → B}
    x : A → B ⊢ x : A (Var)
    x : A → B ⊢ x(x) : B (App)
    ⊢ ((x: (a:A) => B) => x(x)) : (A → B) → B (Abs)

    View Slide

  6. ॻ͍ͯΑ͍ࣜΛ੍ݶ͢Δ
    let apply2 =
    (f: (a: A) => A, n: A) => f(f(n))
    apply2(1, 3)
    Argument of type ’1’ is not assignable to parame-
    ter of type ’(a: 3) => 3’
    apply2((n) => n*n, 3) // OK
    let omega = (x: (a: A) => B) => x(x)
    Argument of type ’(a: A) => B’ is not assignable to pa-
    rameter of type ’A’

    View Slide

  7. STLCͷੑ࣭
    ܕͷ͍ͭͨࣜ͸
    ▶ ࣮ߦͨ݁͠Ռͷ஋΋ಉ͡ܕʹͳΔ
    ▶ ࠷ऴ݁Ռ͚ͩͰͳ࣮͘ߦ్த΋ಉ༷
    ▶ ओ෦؆໿ఆཧ (subject reduction) ͱݴ͏
    ▶ ࣮ߦͨ͠Βඞͣఀࢭ͢Δ
    (ඞͣ݁Ռͷ஋͕ಘΒΕΔ)
    ▶ ධՁઓུʹΑΒͳ͍
    ▶ ڧਖ਼نԽੑ (strong normalization) ͱݴ͏

    View Slide

  8. STLCͷݶք
    ▶ νϡʔϦϯά׬શͰ͸ͳ͍
    (࠶ؼؔ਺͸ॻ͚ͳ͍)
    ▶ Ұݟ͢Δͱ໰୊ͳ͍ͷʹॻ͚ͳ͍͕ࣜ͋Δ
    ܕͳ͠
    let apply2 = (f, n) => f(f(n))
    apply2((n) => [n], 3)
    => [[3]]
    ܕ͖ͭ
    let apply2 =
    (f: (a: A) => A, n: A) => f(f(n))
    apply2((n) => [n], 3)
    Type ’number[]’ is not assignable to type ’number’

    View Slide

  9. (ऄ଍)
    ͦ΋ͦ΋ܕͱ͸
    ܕͱ͸
    ▶ σʔλͷϝϞϦϨΠΞ΢τͷҧ͍Ͱ͸ͳ͍
    ▶ ΋ͷͷू·ΓΛ۠ผ͍ͨ֓͠೦Ͱ෼͚ͨ΋ͷ
    ܕͷىݯ [Kamareddine et al. 2002]
    ▶ ݹ͘͸ϢʔΫϦου
    ▶ ʮ఺ʯͱʮઢʯΛ۠ผ͍ͯͨ͠
    ▶ Theory of types [Russell 1908]
    ▶ ϥοηϧͷύϥυοΫεͷճආͷͨΊ
    ▶ ୯७ܕ෇ϥϜμܭࢉ [Church 1940]

    View Slide

  10. (ऄ଍)
    ͳͥSTLC͸࠶ؼͳ͠?
    ▶ ౰࣌·ͩίϯϐϡʔλ͸ͳ͔ͬͨ
    ▶ ΋ͱ΋ͱ͸໋୊ؔ਺ (࿦ཧࣜΛͱΔؔ਺) Λ૝ఆ
    ▶ ϥοηϧͷύϥυοΫεͷճආ
    ▶ Λ΋ͬͱఆࣜԽͨ͠΋ͷ
    ▶ ७ਮʹ࿦ཧ্ֶͷٞ࿦ͩͬͨ

    View Slide

  11. ͜͜·Ͱͷ·ͱΊ
    ▶ ܕ͕ͳ͍ͱΊͪΌͪ͘ΌʹͳΔ
    ▶ ܕͰʮඞͣ͏·͘ಈ͘ʯ΋ͷʹ੍ݶ
    ▶ ੍ݶ͗ͯ͢͠ෆศʹݟ͑Δ?

    View Slide

  12. ܕϑΝʔετͰߟ͑Δܭࢉ

    View Slide

  13. ܕ͸͋Δछͷ࢓༷
    ྫ (Scala)
    BookmarkRepository.find: BookmarkId => Option[BookmarkEntity]
    // - ϒοΫϚʔΫ ID ͕͋ΔͳΒ,
    // - ϒοΫϚʔΫͷΤϯςΟςΟ͕͋Ε͹ಘΒΕΔ
    Seq.sortBy: Seq[A] => (A => B) => Ordering[B] => Seq[A]
    // - A ͷྻ͕͋Γ,
    // - A Λ B ʹม׵Ͱ͖,
    // - B ͷॱং͕نఆ͞Ε͍ͯΕ͹,
    // - (B ͰιʔτࡁΈͷ)A ͷྻ͕ಘΒΕΔ
    Either.fold: Either[A, B] => (A => C) => (B => C) => C
    // - A ·ͨ͸ B ͲͪΒ͔ͷΠϯελϯε͕͋Γ,
    // - A ͔Β C ΁ͷม׵ͱ, B ͔Β C ΁ͷม׵͕͋Ε͹,
    // - ৗʹ C ͷΠϯελϯε͕ಘΒΕΔ

    View Slide

  14. ܕ͸͋Δछͷ࢓༷
    ܕͷಡΈํ
    ▶ ܕA͸ʮAͷΠϯελϯε͕͋ΔʯΛදͯͦ͠͏
    ▶ =>͸ʮͳΒ͹ʯΛදͯͦ͠͏

    View Slide

  15. ܕ͸͋Δछͷ࢓༷
    ܕͷಡΈํ
    ▶ ܕA͸ʮAͷΠϯελϯε͕͋ΔʯΛදͯͦ͠͏
    ▶ =>͸ʮͳΒ͹ʯΛදͯͦ͠͏ → ࣮ࡍͦ͏

    View Slide

  16. ܕ͸͋Δछͷ࢓༷
    ܕͷಡΈํ
    ▶ ܕA͸ʮAͷΠϯελϯε͕͋ΔʯΛදͯͦ͠͏
    ▶ =>͸ʮͳΒ͹ʯΛදͯͦ͠͏ → ࣮ࡍͦ͏
    ܕ͸࿦ཧࣜ, ࣮૷͸ূ໌
    ▶ ܕ = ࢓༷ (࿦ཧࣜͰද໋ͨ͠୊)
    ▶ ܕͷ͍ͭͨࣜ = ࢓༷͕ຬͨͤΔ͜ͱͷূ໌
    ▶ ࣜʹܕ͕ͭ͘ ⇔ ࢓༷Λຬ࣮ͨ͢૷͕ଘࡏ͢Δ

    View Slide

  17. ܕ͸͋Δछͷ࢓༷
    ܕͷಡΈํ
    ▶ ܕA͸ʮAͷΠϯελϯε͕͋ΔʯΛදͯͦ͠͏
    ▶ =>͸ʮͳΒ͹ʯΛදͯͦ͠͏ → ࣮ࡍͦ͏
    ܕ͸࿦ཧࣜ, ࣮૷͸ূ໌
    ▶ ܕ = ࢓༷ (࿦ཧࣜͰද໋ͨ͠୊)
    ▶ ܕͷ͍ͭͨࣜ = ࢓༷͕ຬͨͤΔ͜ͱͷূ໌
    ▶ ࣜʹܕ͕ͭ͘ ⇔ ࢓༷Λຬ࣮ͨ͢૷͕ଘࡏ͢Δ
    Curry-HowardಉܕରԠ

    View Slide

  18. Curry-HowardಉܕରԠ
    STLC + ௚ੵܕ (λϓϧ) + ௚࿨ܕͷܕ෇͚نଇ
    Γ, x : φ ⊢ x : φ (Ax)
    Γ ⊢ m : ⊥
    Γ ⊢ m : φ (⊥E)
    Γ, x : ⌊φ⌋ ⊢ m : ψ
    Γ ⊢ ((x:φ) => m) : ⌊φ⌋ → ψ (→I)
    Γ ⊢ m : φ → ψ Γ ⊢ n : φ
    Γ ⊢ m(n) : ψ (→E)
    Γ ⊢ m : φ Γ ⊢ n : ψ
    Γ ⊢ [m, n] : φ ∧ ψ (∧I)
    Γ ⊢ m : φ ∧ ψ
    Γ ⊢ m[0] : φ (∧E)
    Γ ⊢ m : φ ∧ ψ
    Γ ⊢ m[1] : ψ
    Γ ⊢ m : φ kind distinct in φ, ψ
    Γ ⊢ m : φ ∨ ψ (∨I)
    Γ ⊢ m : ψ kind distinct in φ, ψ
    Γ ⊢ m : φ ∨ ψ
    Γ ⊢ m : φ ∨ ψ Γ ⊢ n1 : φ → ϑ Γ ⊢ n2 : ψ → ϑ kind : Ki in φ, ψ
    Γ ⊢ switch (m.kind) { case Ki: return ni(m); ... } : ϑ (∨E)

    View Slide

  19. Curry-HowardಉܕରԠ
    ௚؍ओ໋ٛ୊࿦ཧ (Gentzen ͷ NJ)
    Γ, x : φ ⊢ x : φ (Ax)
    Γ ⊢ m : ⊥
    Γ ⊢ m : φ (⊥E)
    Γ, x : ⌊φ⌋ ⊢ m : ψ
    Γ ⊢ ((x:φ) => m) : ⌊φ⌋ → ψ (→I)
    Γ ⊢ m : φ → ψ Γ ⊢ n : φ
    Γ ⊢ m(n) : ψ (→E)
    Γ ⊢ m : φ Γ ⊢ n : ψ
    Γ ⊢ [m, n] : φ ∧ ψ (∧I)
    Γ ⊢ m : φ ∧ ψ
    Γ ⊢ m[0] : φ (∧E)
    Γ ⊢ m : φ ∧ ψ
    Γ ⊢ m[1] : ψ
    Γ ⊢ m : φ kind distinct in φ, ψ
    Γ ⊢ m : φ ∨ ψ (∨I)
    Γ ⊢ m : ψ kind distinct in φ, ψ
    Γ ⊢ m : φ ∨ ψ
    Γ ⊢ m : φ ∨ ψ Γ ⊢ n1 : φ → ϑ Γ ⊢ n2 : ψ → ϑ kind : Ki in φ, ψ
    Γ ⊢ switch (m.kind) { case Ki: return ni(m); ... } : ϑ (∨E)

    View Slide

  20. ͳͥܕϑΝʔετ?

    View Slide

  21. ͳͥܕϑΝʔετ?
    ԿΛূ໌͍͔ܾͨ͠Ίͣʹ
    ূ໌Λॻ͘Ϡπ͸͍ͳ͍

    View Slide

  22. ͳͥܕϑΝʔετ?
    ԿΛূ໌͍͔ܾͨ͠Ίͣʹ
    ূ໌Λॻ͘Ϡπ͸͍ͳ͍
    ▶ ҋӢʹίʔυΛॻ͘લʹ࢓༷Λߟ͑·͠ΐ͏
    ▶ ܕ͕ͳͯ͘΋ TDD Ͱ͸ͦ͏͠·͢ΑͶ

    View Slide

  23. (ऄ଍)
    ຊ౰ʹ໋୊͕ઌ?
    ࣮ࡍʹূ໌Λॻ͍͍ͯΔͱ͖͸
    ▶ ิ୊Λॻ͘ͱ͖͸ޙ͔Β໋୊Λม͑Δ͜ͱ΋
    ▶ ͍͟࢖͏ͱ͖ʹ࢖͍উखͷѱ͞ʹؾͮ͘
    ▶ ͏·͘ূ໌Ͱ͖ͳ͍ͷͰϓϥϯ B ʹม͑Δ
    ▶ ͱ͸͍͍͖͑ͳΓূ໌Λॻ͘͜ͱ͸ͳͦ͞͏
    ϓϩάϥϜΛॻ͘ͱ͖Ͳ͏ͨ͠ΒΑ͍?
    ▶ ϓϥΠϕʔτϝιου౳͸޷͖ʹͨ͠ΒΑ͍
    ▶ ʮͳʹ͕੒Γཱͭ͸͔ͣ?ʯ͸৺͕͚͍ͨ

    View Slide

  24. ܕ͸ʮ͋Δछʯͷ࢓༷
    ܕͷදݱྗ͕ߴ͍ͱخ͍͠
    ▶ ࢓༷ͷදݱྗ͸ܕͷදݱྗʹґଘ
    ܕͷදݱྗ͕ߴ͗͢ΔͱࠔΔ
    ▶ ΍Γ͗͢Δͱܕݕ͕ܾࠪఆෆೳʹͳΔ
    ▶ ܕਪ࿦͕׬શͰ͸ͳ͘ͳΓ͕ͪ
    ▶ ϓϩάϥϜͰ͸ͳ͘೉͍͠ূ໌Λॻ͘͜ͱʹ
    ▶ Coq ͳͲ
    ▶ ূ໌Λॻ͍͔ͯͦ͜ΒϓϩάϥϜΛநग़

    View Slide

  25. දݱྗͷߴ͍ܕ
    ࿦ཧମܥ ܭࢉମܥ΍ݴޠ
    ݹయ࿦ཧ STLC + ܧଓ
    ೋ֊௚؍ओ໋ٛ୊࿦ཧ System F
    ࣌૬࿦ཧ MetaOCaml
    ઢܗ࿦ཧ (ΞϑΟϯ࿦ཧ) Rust

    View Slide

  26. ͜͜·Ͱͷ·ͱΊ
    ▶ ࣜʹܕ͕ͭ͘ = ࢓༷Λຬ࣮ͨ͢૷͕Ͱ͖ͨ
    ▶ ܕ = ࢓༷
    ▶ ࣮૷ = ࢓༷ͷ࣮ݱΛূ໌
    ▶ ;ͭ͏࢓༷͔Βઌʹߟ͑Δ
    ▶ ܕͷදݱྗΛߴΊΔͱࡉ͔͍࢓༷ΛදݱͰ͖Δ
    ▶ දݱྗͷߴ͍࿦ཧମܥ΋͋Δ (Ή͔͍ͣ͠)
    ▶ ଞʹ΋޻෉ͷ͔ͨ͠͸͋Δ (͜ͷ͋ͱ঺հ)

    View Slide

  27. ܕͷදݱΛ޻෉͢Δ

    View Slide

  28. Scalaͷimplicit

    val l1: List[(Int, String)] =
    List(1 -> "foo", 2 -> "bar")
    val m1 = l1.toMap // m1: Map[Int, String]
    val l2: List[Int] = List(1, 2, 3)
    val m2 = l2.toMap // ίϯύΠϧΤϥʔ
    Ͳ͏΍ͬͯఆٛ͢Δ??
    class List[A] {
    def toMap: Map[???]

    View Slide

  29. Scalaͷimplicit

    val l1: List[(Int, String)] =
    List(1 -> "foo", 2 -> "bar")
    val m1 = l1.toMap // m1: Map[Int, String]
    val l2: List[Int] = List(1, 2, 3)
    val m2 = l2.toMap // ίϯύΠϧΤϥʔ
    Ͳ͏΍ͬͯఆٛ͢Δ??
    class List[A] {
    def toMap[K, V](implicit
    ev: A <:< (K, V) // ௥Ճͷূ໌Λཁٻ
    ): Map[K, V]

    View Slide

  30. εϚʔτίϯετϥΫλ
    ྫ: ϦετΛඇۭʹݶఆ͍ͨ͠
    val l1 = List(1, 2, 3)
    l1.head // => 1
    val l2 = List()
    l2.head // ࣮ߦ࣌Τϥʔ
    class Nel[A] private (val v: List[A])
    object Nel {
    def apply[A](v: A*): Option[Nel[A]] =
    if (v.nonEmpty) Some(new Nel(v))
    else None
    }
    val nel1 = Nel(1, 2, 3)
    nel1.map(_.v.head) // => Some(1)
    val nel2 = Nel()
    nel2.map(_.v.head) // => None

    View Slide

  31. ɹ
    ;Δ͍

    ɹܕ (refinement type)
    ྫ: ϦετͷඇۭੑΛอ͍ͪͨ
    val Some(nel1) = Nel(1, 2, 3)
    nel1.v.map(n => n * n) // => List(1, 4, 9): List[Int]
    val Some(nel2) = RefinedNel(1, 2, 3)
    nel2.map(n => n * n) // => List(1, 4, 9): RefinedNel[Int]
    nel2.flatMap(n => List()) // => List(): List[Int]
    ▶ ަࠩܕ (intersection type) Ͱ࣮ݱ [Pfenning et al. 1991]
    ▶ Haskell ΍ Scala Ͱ͸ Refined ͱ͍͏ϥΠϒϥϦ

    View Slide

  32. ߴΧΠϯυܕ

    trait Hoge[F[_]]
    ▶ ܕίϯετϥΫλΛҾ਺ʹऔΕΔ
    ▶ ͋Δͱݍ࿦తͳ֓೦Λૉ௚ʹදݱͰ͖Δ
    ▶ αϙʔτͯ͠Δݴޠ͸ଟ͘͸ͳ͍
    ▶ Haskell, Scala, C++, Rust ͋ͨΓ?
    ▶ ࢖ͬͯ͏Ε͍͠ྫ͸άά͍ͬͯͩ͘͞

    View Slide

  33. ·ͱΊ
    ▶ ܕΛ͚ͭͯʮ͏·͘ಈ͘ʯ΋ͷʹ੍ݶ͢Δ
    ▶ ٯʹ࢓༷͔Βઌʹߟ͑Δ
    ▶ ࢓༷Λ͏·͘දݱ͢ΔͨΊʹςΫχοΫΛຏ͘

    View Slide