This page is no longer maintained — Please continue to the home page at www.scala-lang.org

_5.A where val _5: Out.this.In

3 replies
Jesse Eichar
Joined: 2008-12-20,
User offline. Last seen 42 years 45 weeks ago.
I am trying to figure out why exec doesn't compile.  If I move type A into trait Out it compiles.  
trait Out {  trait In {    type A    def get() : A     def doit(a:A) : Int  }    def in : In    def exec : Any = in doit in.get}
The error message I get is:
console>:14: error: type mismatch; found   : Out.this.In#A required: _5.A where val _5: Out.this.In          def exec : Any = in.doit (in.get)   
Is there a way to make it compile without having to move the type A declaration into the outer class?
Jesse
Matthias
Joined: 2010-03-08,
User offline. Last seen 42 years 45 weeks ago.
Re: _5.A where val _5: Out.this.In
Probably this is not exactly what you meant, but you can do the following:
trait Out {   import Out._  ...} object Out {  trait In {    ...   }}

I have moved the In trait to the companion object. This, arguably, is not the outer class.
I use this style in Scala all the time. For me, it looks good. But it's a question of taste.

2010/4/26 Jesse Eichar <jeichar.w@gmail.com>
I am trying to figure out why exec doesn't compile.  If I move type A into trait Out it compiles.  
trait Out {  trait In {    type A    def get() : A     def doit(a:A) : Int  }    def in : In    def exec : Any = in doit in.get}
The error message I get is:
console>:14: error: type mismatch; found   : Out.this.In#A required: _5.A where val _5: Out.this.In          def exec : Any = in.doit (in.get)   
Is there a way to make it compile without having to move the type A declaration into the outer class?
Jesse

Mark Harrah
Joined: 2008-12-18,
User offline. Last seen 35 weeks 3 days ago.
Re: _5.A where val _5: Out.this.In

Hey Jesse,

On Monday 26 April 2010 10:21:56 am Jesse Eichar wrote:
> I am trying to figure out why exec doesn't compile. If I move type A into
> trait Out it compiles.
>
> trait Out {
> trait In {
> type A
> def get() : A
> def doit(a:A) : Int
> }
>
> def in : In
>
> def exec : Any = in doit in.get
> }
>
> The error message I get is:
>
> console>:14: error: type mismatch;
> found : Out.this.In#A
> required: _5.A where val _5: Out.this.In
> def exec : Any = in.doit (in.get)

The issue is that 'in' is not a stable reference. In 'exec', the calls to
'in' could return different instances. The unqualified A in 'get' and 'doit'
means A according to this instance of In, not A for any instance of In.
Expanding the A in those methods:

def get() : this.A
def doit(a: this.A) : Int

The body of 'exec':

in doit in.get

translates to something like:

val in1 = in
val in2 = in
val got: in2.A = in2.get
in1.doit(got)

The problem is that 'got' is of type in2.A but in1.doit expects an instance of
type in1.A. If you use the above expansion as the body of 'exec', the error
message is much clearer:

error: type mismatch;
found : in2.A
required: in1.A
in1.doit(got)

> Is there a way to make it compile without having to move the type A
> declaration into the outer class?

Yes, here are some solutions:

// widen the type to be A for any instance of In, not just this one
def doit(a: In#A): Int

// or, define Out.in to be a stable reference
val in : In

// or, create a stable reference in 'exec'
def exec : Any = {
val i = in
i doit i.get
}

-Mark

Joshua.Suereth
Joined: 2008-09-02,
User offline. Last seen 32 weeks 5 days ago.
Re: _5.A where val _5: Out.this.In
May be late responding here, but have you tried assigning in  to a Val first?  I believe since in is a method and could return different objects each time, the exec implementation is unsound.

Try -
def exec : Any = {  val tmp = in  tmp doit tmp.get
}

- Josh
On Apr 26, 2010, at 10:21 AM, Jesse Eichar <jeichar.w@gmail.com> wrote:

I am trying to figure out why exec doesn't compile.  If I move type A into trait Out it compiles.  
trait Out {  trait In {    type A    def get() : A     def doit(a:A) : Int  }    def in : In    def exec : Any = in doit in.get}
The error message I get is:
console>:14: error: type mismatch; found   : Out.this.In#A required: _5.A where val _5: Out.this.In          def exec : Any = in.doit (in.get)   
Is there a way to make it compile without having to move the type A declaration into the outer class?
Jesse

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland