qiita.comã® 12/21 ã§ãã
å æ¥ï©å ã®ï¨³å¼·æ㧠Tour of Scala ãè¦è¿ãã¦ããããpath ä¾ååãã¨äºãµæè¨ãè¦ã¦ãååããç¥ãããªã¨æã²è¿ãã¾ãããããã§
path ä¾ååã£ã¦ä½? ã©ããªãã®? 年齡ã¯? çµå©ãã¦ã? 調ã¹ã¦ã¿ã¾ãã!
type selection
path ä¾åå (path-dependent type) ã¯ãScala ã®å¯¦è£ï©éã«ããè«æNada Amin, Tiark Rompf, and Martin Odersky. 2014. Foundations of path-dependent types. SIGPLAN Not. 49, 10 (October 2014), 233–249.ã«ã¦èå¯ããã¦ãããåã®ä¸ã¤ã§ãããã®è«æã§ã¯ "type selection" ã¨äºãµåã§èå¯ããã¦ãã¾ãã
ãã®å½¢ã®è¨èãç®å°ãªã®ã§ãè®ãæã¯ãã®å½¢ãç®æãã¦ã¿ã¦ãã ãããã variable (è®æ¸) ã§ããåã§ãçµã¿åã¯ãã¦ã¨äºãµåã§ããè®æ¸ã«ä¾åããåãã¨äºãµè¨£ã§ pathãä¾åãåã¨å¼ã¶ã®ã§ãã (ä¾åå (dependent type) ã®ä¸ç¨®ã¨å¼ã¹ãäºã¯ç¡ãâ¦ã實éãpath ä¾ååã¨éè¯ã㦠Scala 3 ããå°å ¥ãããä¾åå½æ¸å (dependent function type) ã¯ä¾ååã®ä¸ç¨®ã§ã)ã
type selection ãã©ãå°å ¥ãããã®ãã¯ãè«ææ«å°¾ã®å¼ãéè³ãã¦ããã ãäºã¨ãã¦ãããã§ã¯ path ä¾ååã®ä½¿ã²ã©ãããçºãã¦ã¿ã¾ããã
path ä¾åå
path ä¾ååã¯ãclass ã trait ã®å §å´ã§å®ç¾©ãã class ã trait ã® instance ã®åã¨ãã¦ç»å ´ãã¾ãã
class A { class B { def f(b: B): Unit = {} } def newB: B = new B() } val a1 = new A() a1.newB.f(a1.newB) // OK val a2 = a1 a1.newB.f(a2.newB) // Found: Playground.a2.B // Required: Playground.a1.B a2.newB.f(a1.newB) // Found: Playground.a1.B // Required: Playground.a2.B
class A ã®å
§å´ã§å®ç¾©ãã class B ã® instance ã®åã¯ãclass B ã® instance ãçæããæã«ä½¿ã£ã class A ã® instance ã«ä¾åãã¾ããa1.newB
ã®å㯠a1.B
ã§ãããa2.newB
ã®å㯠a2.B
ã¨ãåå¥ããã¾ããè®æ¸ a1
ã¨è®æ¸ a2
ã¯ãval a2 = a1
ã§ããåãå¤ã§ãããpath ä¾ååã¯å¤ã§ã¯ãªãè®æ¸ã«ä¾åããã®ã§ãclass B ã® instance ã®åã¯åå¥ããã¾ã (nominality (ååçãªå) 㨠general refinements (總稱細å¥å (ãç´°å¥åãã¯å¤§æµã篩åãã¨è¯ããã¾ãã)) ã¨ãèæ
®ãã¦ã¨ã®äºã ã¨è«æã«ã¯ããã¾ã)ã
path ä¾ååã¯ãåå°å½± (type projection) ã«ããå A#B
ã« cast ã§ããcast ããã¨åãåã®å¤ã¨ãã¦æ±ã¸ã樣ã«ãªãã¾ã (A#B
ã¨ãã¦æ¯ãèã¯ãã㨠Java ã£ã½ããªãã¾ãã)ã
ä½ã«ä½¿ãµã®?
ãã¦ä½¿ã²ã©ããã§ãã
å¤ãã®è¨äºã«ã¯ãtree ã® appendChild å ãééã¸ãªã樣ã«ããä¾ãè¦ã¾ãããããããªçæ³ã£ã¦å¤ããã§ããã?
é¢ç½ãã£ãã®ã¯Path dependent types. Modeling algebraic structures has never… | by Marcin Rzeźnicki | VirtusLab | Mediumã®ä¾ã§ãã2 é²æ¸ã®æ¼ç®é«ç³»ã¨ 10 é²æ¸ã®æ¼ç®é«ç³»ãä½ã£ã¦ãããããã®ä¸ã§ã¯æ¼ç®ã§ãã¾ããã2 é²æ¸ã®æ¸ã¨ 10 é²æ¸ã®æ¸ãæ¼ç®ãããã¨ãã㨠compile error ã«ã§ãã¾ãã
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]
ä»ã«ã¯Dependent Types in Scala - Some Tips, Tricks and Techniquesã§ãã¾ãã§æ®éã®ä¾ååãã®æ¨£ã«ä½¿ãµåå¼·ã使ã²æ¹ãç´¹ä»ãã¦ãããé¢ç½ããã®ã§ããã
ä¾åå½æ¸å
éè¯ããä»æ¨£ã« Scala 3 ããå°å ¥ãããä¾åå½æ¸å (dependent function type) ã dependent method (dependent method 㯠Scala 2 ããå¨ãã¾ã) ãããã¾ãã
docs.scala-lang.org docs.scala-lang.org
å½æ¸ã method ã®å¼æ¸ã«ç»å ´ããè®æ¸ã«ä¾åããåããä»ã®å¼æ¸ãè¿ãå¤ã®åã¨ãã¦æ¸ãããã®ã§ãã
trait A { type B; val b: B } val f: (a: A) => a.B = (a: A) => a.b
å½æ¸ f
ã®åã (a: A) => a.B
ã¨ãªã£ã¦ãããa.B
ã¨äºãµ path ä¾ååãå«ã¾ãã¦ããã®ã (Scala ã§è¨ãµ) ä¾åå½æ¸åã§ãã
總稱åã¿ããã«ä½¿ãµã®ãå¤ããã§ãããã總稱åã§ã¯ã
case class Key[V](name: String) {} class DB { def set[V](k: Key[V], v: V): Unit = { println(k) println(v) } } val db = new DB val k1 = Key[String]("k1") val k2 = Key[Double]("k2") db.set(k1, "v1") db.set(k2, 42.0)
ã¨æ¸ãã¨ããã¯ãä¾åå½æ¸åã§ã¯ã
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 = { println(k) println(v) } } val db = new DB val k1 = key[String]("k1") val k2 = key[Double]("k2") db.set(k1, "v1") db.set(k2, 42.0)
ã¨ãªãã¾ãããset
method ã®å parameter ãæ¶ãã¦ããã¾ãã
ãããã§ããã?