scala - Conducir un tipo singleton a través de un brickwall
types path-dependent-type (3)
Aquí hay una versión muy condensada:
case class Brickwall[A](otherSide: A)
trait Monoman { def me(m: this.type): Unit }
def test(m: Monoman): Unit = m.me(Brickwall(m).otherSide)
-> error: type mismatch;
found : Monoman
required: m.type
estúpido Brickwall no me deja pasar. alguna idea de cómo podría ser posible? ¿efectos secretos del túnel scala? esperando...
Por lo que sé, el compilador de Scala se niega a inferir los tipos que dependen de la ruta, por lo que una pequeña anotación tipo ayuda:
def test( m: Monoman ) { m.me( Brickwall[m.type]( m ).otherSide )}
Sí, los tipos de singleton nunca se deducen por el compilador de Scala.
Una posibilidad es agregar un método de fábrica al rasgo de Monoman:
trait Monoman {
def me( m: this.type ) : Unit
def createWall = Brickwall[this.type](this)
}
def test( m: Monoman ) { m.me(m.createWall.otherSide) }
Tal vez esa no sea una solución viable en su caso.
He aquí un intento con la idea de fábrica (ya había hecho esto antes y me rendí, pero bueno, intentémoslo de nuevo):
object Brickwall
case class Brickwall[A](brick: A)
trait Monoman {
var wall: Ref[this.type, Brickwall[String]]
def ref[V](v: V): Ref[this.type, V]
}
object Ref {
implicit def unwrap[Repr](r: Ref[_, Repr]): Repr = r.repr
implicit def wrap[A, Repr](repr: Repr): Ref[A, Repr] = new Impl[A, Repr](repr)
private class Impl[A, Repr](val repr: Repr) extends Ref[A, Repr]
}
trait Ref[A, Repr] { def repr: Repr }
def test(m: Monoman): Unit = {
val w0 = m.wall
val w1 = w0.copy(brick = "3.1415")
m.wall = w1 // doesn''t convert to Ref
}
entonces, mientras que el desenvolvimiento es transparente, el reenvío no parece funcionar, y sospecho que no es posible hacerlo funcionar, una vez más porque m.type
nunca se puede inferir.