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

path 依存型って何?

path 依存型って何?

Scala の path 依存型って何? 調べてみました!

さっちゃん

November 24, 2023
Tweet

More Decks by さっちゃん

Other Decks in Programming

Transcript

  1. path 依存型って何?

    View full-size slide

  2. .。oO(さっちゃんですよヾ(〃l _ l)ノ゙☆)

    View full-size slide

  3. .。oO(さっちゃんですよヾ(〃l _ l)ノ゙☆)
    好きな技術 : Erlang VM、Clojure
    開發環境 : zsh、Nix、asdf、Emacs (Evil)、Vivaldi
    https://ja.mackerel.io を作ってゐます

    View full-size slide

  4. 今讀んでゐる本

    View full-size slide

  5. Scala の path 依存型って何?
    調べてみました!

    View full-size slide

  6. class A {
    class B {
    def f(b: B): Unit = {}
    }
    def newB: B = new B()
    }
    val a1 = new A()
    val a2 = a1
    val b1 = a1.newB
    val b2 = a2.newB
    b1.f(b1)
    b1.f(b2)
    ?

    View full-size slide

  7. class A {
    class B {
    def f(b: B): Unit = {}
    }
    def newB: B = new B()
    }
    val a1 = new A()
    val a2 = a1
    val b1 = a1.newB
    val b2 = a2.newB
    b1.f(b1) // OK
    b1.f(b2)
    // Found: Playground.a2.B
    // Required: Playground.a1.B

    View full-size slide

  8. type selection x.L

    變數

    に依存
    した型
    type selection は名前的 (nominal)

    View full-size slide

  9. type selection x.L
    subtyping of types

    View full-size slide

  10. type selection x.L
    well-formed types

    View full-size slide

  11. type selection x.L
    explanation

    View full-size slide

  12. trait A {
    type B
    def f(b: B): Unit = {}
    }
    trait Ba
    trait Aa extends A {
    type B = Ba
    }
    val aa = new Aa {}
    aa.f(new Ba {}) // OK
    val aaa: A = aa
    aaa.f(new Ba {})
    // Found: Object with Playground.Ba {...}
    // Required: Playground.aaa.B

    View full-size slide

  13. path 依存型の使ひ所

    View full-size slide

  14. 異なる變數から生成された値を受け附けない
    class Store {
    class Item {}
    def getItem: Item = new Item
    def save(item: Item): Unit = {}
    }
    val store1 = new Store
    val item1 = store1.getItem
    val store2 = new Store
    val item2 = store2.getItem
    store1.save(item1) // OK
    store1.save(item2)
    // Found: (Playground.item2 : Playground.store2.Item)
    // Required: Playground.store1.Item

    View full-size slide

  15. 値を parameter として持つ型
    case class Z(modulus: Int) {
    sealed class Modulus {
    val value = modulus
    }
    object Modulus {
    implicit val mod: Modulus = new Modulus()
    }
    }
    class IntMod[N <: Z#Modulus] private (val value: Long) extends AnyVal {
    def +(x: IntMod[N])(implicit m: N): IntMod[N] = value + x
    }
    object IntMod {
    import scala.language.implicitConversions
    implicit def longAsIntModN[N <: Z#Modulus](i: Long)(implicit
    modulus: N
    ): IntMod[N] =
    new IntMod[N](i % modulus.value)
    implicit def intModN2Long(a: IntMod[_]): Long = a.value
    }
    val z1 = Z(2)
    val z2 = Z(10)
    val i1z1 = 1: IntMod[z1.Modulus]
    val i2z1 = 3: IntMod[z1.Modulus]
    val i1z2 = 1: IntMod[z2.Modulus]
    val i2z2 = 3: IntMod[z2.Modulus]
    println(i1z1 + i2z1) // 0: IntMod[z1.Modulus]
    println(i1z2 + i2z2) // 4: IntMod[z2.Modulus]
    println(i1z1 + i2z2)
    // Found: (Playground.i2z2 : Playground.IntMod[Playground.z2.Modulus])
    // Required: Playground.IntMod[Playground.z1.Modulus]

    View full-size slide

  16. 實行時に確定する値に依存する型
    trait time_t_proto {
    type time_t
    }
    trait time_t_impl[U] extends time_t_proto {
    type time_t = U
    }
    case class Ptr[U](time: U) extends time_t_impl[U]
    trait Platform extends time_t_proto
    object PlatformI386 extends Platform with time_t_impl[Int]
    object PlatformX64 extends Platform with time_t_impl[Long]
    val arch = "x86_64"
    val platform: Platform =
    if arch == "i386" then PlatformI386
    else if arch == "x86_64" then PlatformX64
    else ???
    def f(timer: Ptr[platform.time_t]): platform.time_t = timer.time
    val t = Ptr(42L.asInstanceOf[platform.time_t]) // C から渡される
    f(t) // 42: platform.time_t

    View full-size slide

  17. dependent method と
    依存函數型 (dependent function type)

    View full-size slide

  18. dependent method
    method の引數變數に依存した型
    trait V
    trait A {
    type B = V
    def newB = new B {}
    }
    def f(a: A): a.B = a.newB
    f(new A {}) // : V

    View full-size slide

  19. 依存函數型 (dependent function type)
    引數變數に依存した函數型
    trait A { type B; val b: B }
    val f: (a: A) => a.B = (a: A) => a.b

    View full-size slide

  20. dependent method や依存函數型の使ひ所

    View full-size slide

  21. 總稱型 (generics)
    abstract class Key(name: String) { type Value }
    def key[V](name: String) = new Key(name) {
    override type Value = V }
    class DB {
    def set(k: Key, v: k.Value): Unit = {}
    }
    val db = new DB
    val k1 = key[String]("k1")
    val k2 = key[Double]("k2")
    db.set(k1, "v1")
    db.set(k2, 42.0)
    case class Key[V](name: String) {}
    class DB {
    def set[V](k: Key[V], v: V): Unit = {}
    }
    val db = new DB
    val k1 = Key[String]("k1")
    val k2 = Key[Double]("k2")
    db.set(k1, "v1")
    db.set(k2, 42.0)

    View full-size slide

  22. 條件分岐
    object ApplyEither {
    def apply[T, F, G](t: T, f: F, g: G)(implicit ea: EApply[T, F, G]): ea.Out =
    ea(t, f, g)
    }
    trait EApply[T, F, G] {
    type Out
    def apply(t: T, f: F, g: G): Out
    }
    object EApply {
    def apply[T, F, G](implicit ea: EApply[T, F, G]) = ea
    implicit def applyF[T, R, G]: EApply[T, T => R, G] =
    new EApply[T, T => R, G] {
    type Out = R
    def apply(t: T, f: T => R, g: G) = f(t)
    }
    implicit def applyG[T, R, F]: EApply[T, F, T => R] =
    new EApply[T, F, T => R] {
    type Out = R
    def apply(t: T, f: F, g: T => R) = g(t)
    }
    }
    ApplyEither(1, { (x: Int) => 42 }, { (x: Double) => "no" }) // 42: EApply[Int, Function1[Int, Int], Function1[Double, String]].Out
    ApplyEither(2.0, { (x: Int) => 42 }, { (x: Double) => "no" }) // "no": EApply[Int, Function1[Int, Int], Function1[Double, String]].Out

    View full-size slide

  23. いかがでしたか?

    View full-size slide

  24. 參考文獻
    真理について〈2〉 (ヤスパース選集 ) | カール ヤスパース, Jaspers,Karl, 靖昌, 小林 |本 | 通販 | Amazon
    https://www.amazon.co.jp/dp/4650001323/
    内部クラス | Scala Documentation https://docs.scala-lang.org/ja/tour/inner-classes.html
    Nada Amin, Tiark Rompf, and Martin Odersky. 2014. Foundations of path-dependent types. SIGPLAN Not. 49, 10 (October 2014),
    233–249. https://doi.org/10.1145/2714064.2660216
    Path dependent types. Modeling algebraic structures has never… | by Marcin Rzeźnicki | VirtusLab | Medium
    https://medium.com/virtuslab/path-dependent-types-9f2d7927c1fa
    A quick explanation of Path Dependent Types - DEV Community
    https://dev.to/markehammons/a-quick-explanation-of-path-dependent-types-4pki
    Dependent Function Types | Scala 3 — Book | Scala Documentation
    https://docs.scala-lang.org/scala3/book/types-dependent-function.html
    Dependent Types in Scala - Some Tips, Tricks and Techniques
    https://wheaties.github.io/Presentations/Scala-Dep-Types/dependent-types.html

    View full-size slide