Driving a singleton type through a brick wall

Here is a very concise version:

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 

stupid brick wall doesn't let me pass. any ideas how this is possible? secret scala tunnel effects? hoping ...

+4
source share
3 answers

As far as I know, the Scala compiler refuses to output path-dependent types, so a small annotation allows:

 def test( m: Monoman ) { m.me( Brickwall[m.type]( m ).otherSide )} 
+6
source

Yes, singleton types are never inferred by the Scala compiler.

One possibility is to add a factory method to the Monoman trait:

 trait Monoman { def me( m: this.type ) : Unit def createWall = Brickwall[this.type](this) } def test( m: Monoman ) { m.me(m.createWall.otherSide) } 

Perhaps this is not a viable solution in your case.

+3
source

here is a try with the idea of ​​a factory (I did it before and gave up, but I will try it again well):

 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 } 

therefore, when the deployment is transparent, repacking does not work, and I suspect that it is impossible to make it work, again, because m.type never be output.

+1
source

Source: https://habr.com/ru/post/1347020/


All Articles