- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
_5.A where val _5: Out.this.In
Mon, 2010-04-26, 15:29
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
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
Mon, 2010-04-26, 16:07
#2
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
Mon, 2010-04-26, 22:07
#3
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:
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
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>