Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I constrain a member of a parameter class to match the instance of an outer class?

Tags:

scala

The following code does not compile, because the compiler cannot prove that v.o.Inner and Outer.this.Inner are the same, in the implementation of visit(). I cannot see how to tell the compiler than v.o must be Outer.this such that its recognized at compiler time. Any ideas?

class Outer {
   class Inner {
      def visit(v:Visitor) = v.visitInner(this)
   }
}

class Visitor(val o:Outer) {
    def visitInner(i:o.Inner) = { println("foo") } 
}
like image 545
Simon K Avatar asked Mar 21 '23 23:03

Simon K


1 Answers

The compiler cannot prove that because that is false. For example:

val o1 = new Outer
val o2 = new Outer
val o2i = new o2.Inner
val v = new Visitor(o1)

o2i.visit(v)

Here the Outer of v is o1, but the Outer of this (o2i) is o2.

If what you are asking is how to enforce the types so that it becomes so, this might help:

class Outer {
   self => 
   class Inner {
      def visit(v:Visitor[self.type]) = v.visitInner(this)
   }
}

class Visitor[T <: Outer](val o:T) {
    def visitInner(i:o.Inner) = { println("foo") } 
}

However, type inference won't help you if you go this route. You'll have to be explicit about the type of any Visitor, like this:

val v = new Visitor[o1.type](o1)
like image 76
Daniel C. Sobral Avatar answered Apr 15 '23 12:04

Daniel C. Sobral