Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

ܕ͕ͳ͍ͱ 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

Slide 4

Slide 4 text

ॻ͍ͯΑ͍ࣜΛ੍ݶ͢Δ ▶ ܕ෇͚نଇʹ߹கͨ͠΋ͷͷΈڐ͢ ▶ ྫ: ୯७ܕ෇ϥϜμܭࢉ (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)

Slide 5

Slide 5 text

ॻ͍ͯΑ͍ࣜΛ੍ݶ͢Δ ▶ ܕ෇͚نଇʹ߹கͨ͠΋ͷͷΈڐ͢ ▶ ྫ: ୯७ܕ෇ϥϜμܭࢉ (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)

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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’

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

ܕ͸͋Δछͷ࢓༷ ྫ (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 ͷΠϯελϯε͕ಘΒΕΔ

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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)

Slide 19

Slide 19 text

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)

Slide 20

Slide 20 text

ͳͥܕϑΝʔετ?

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

ܕͷදݱΛ޻෉͢Δ

Slide 28

Slide 28 text

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[???]

Slide 29

Slide 29 text

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]

Slide 30

Slide 30 text

εϚʔτίϯετϥΫλ ྫ: ϦετΛඇۭʹݶఆ͍ͨ͠ 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

Slide 31

Slide 31 text

ɹ ;Δ͍ ᝲ ɹܕ (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 ͱ͍͏ϥΠϒϥϦ

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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