- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
type checking problem
Sun, 2009-10-11, 22:59
in Scala-2.7.4 & current 2.80 snapshots I get the following:
scala> object Test {
|
| trait ZZ {
| trait C1[T]{}
|
| trait CF1[T, CT <: C1[T]]{}
|
| trait A[T] {
| type R <: C1[T]
| type FR <: CF1[T, R]
| def fr : FR
| }
|
| def f1[Y, AY <: A[Y]](y: Y, ay: AY) : AY#R
| = f2[Y, AY#R](y, ay.fr : AY#FR)
|
| def f2[O, CO <: C1[O]](f: O, fr : CF1[O, CO]) : CO
| }
| }
<console>:21: error: type mismatch;
found : AY#FR
required: ZZ.this.CF1[Y,AY#R]
= f2[Y, AY#R](y, ay.fr : AY#FR)
^
but I think AY#FR <: CF1[Y,AY#R] so why is this an error?
thanks
Daniel
scala> object Test {
|
| trait ZZ {
| trait C1[T]{}
|
| trait CF1[T, CT <: C1[T]]{}
|
| trait A[T] {
| type R <: C1[T]
| type FR <: CF1[T, R]
| def fr : FR
| }
|
| def f1[Y, AY <: A[Y]](y: Y, ay: AY) : AY#R
| = f2[Y, AY#R](y, ay.fr : AY#FR)
|
| def f2[O, CO <: C1[O]](f: O, fr : CF1[O, CO]) : CO
| }
| }
<console>:21: error: type mismatch;
found : AY#FR
required: ZZ.this.CF1[Y,AY#R]
= f2[Y, AY#R](y, ay.fr : AY#FR)
^
but I think AY#FR <: CF1[Y,AY#R] so why is this an error?
thanks
Daniel
Mon, 2009-10-12, 07:17
#2
Re: type checking problem
I figured out my problem.
What I was actually after is:
object Test {
trait ZZ {
type C[O]
type CF[O, CO <: C[O]]
trait A[O, CO <: C[O]] {
type CFO <: CF[O, CO]
def cfo : CFO
}
def f1[O, CO <: C[O]](o: O, ao: A[O, CO]) : CO
= f2[O, CO](o, ao.cfo)
def f2[O, CO <: C[O]](o: O, cfo : CF[O, CO]) : CO
}
Though, I suspect the benefit of these contortions is not apparent without the context :)
cheers
Daniel
On Mon, Oct 12, 2009 at 3:46 AM, Daniel Mahler <dmahler@gmail.com> wrote:
What I was actually after is:
object Test {
trait ZZ {
type C[O]
type CF[O, CO <: C[O]]
trait A[O, CO <: C[O]] {
type CFO <: CF[O, CO]
def cfo : CFO
}
def f1[O, CO <: C[O]](o: O, ao: A[O, CO]) : CO
= f2[O, CO](o, ao.cfo)
def f2[O, CO <: C[O]](o: O, cfo : CF[O, CO]) : CO
}
Though, I suspect the benefit of these contortions is not apparent without the context :)
cheers
Daniel
On Mon, Oct 12, 2009 at 3:46 AM, Daniel Mahler <dmahler@gmail.com> wrote:
On Sun, Oct 11, 2009 at 11:58 PM, Daniel Mahler <dmahler@gmail.com> wrote:
in Scala-2.7.4 & current 2.80 snapshots I get the following:
scala> object Test {
|
| trait ZZ {
| trait C1[T]{}
|
| trait CF1[T, CT <: C1[T]]{}
|
| trait A[T] {
| type R <: C1[T]
| type FR <: CF1[T, R]
| def fr : FR
| }
|
| def f1[Y, AY <: A[Y]](y: Y, ay: AY) : AY#R
| = f2[Y, AY#R](y, ay.fr : AY#FR)
|
| def f2[O, CO <: C1[O]](f: O, fr : CF1[O, CO]) : CO
| }
| }
<console>:21: error: type mismatch;
found : AY#FR
required: ZZ.this.CF1[Y,AY#R]
= f2[Y, AY#R](y, ay.fr : AY#FR)
^
but I think AY#FR <: CF1[Y,AY#R] so why is this an error?
thanks
Daniel
I have found that I this code will compile if I make CF1 covariant in CT.
object Test {
trait ZZ {
type C1[T]
type CF1[T, +CT <: C1[T]]
trait A[T] {
type R <: C1[T]
type FR <: CF1[T, R]
def fr : FR
}
def f1[Y, AY <: A[Y]](y: Y, ay: AY) : AY#R
= f2[Y, AY#R](y, ay.fr)
def f2[O, CO <: C1[O]](f: O, fr : CF1[O, CO]) : CO
}
}
Unfortunately in my intended application CF1 is not covariant in CT
and I am havingtrouble figuring out what is forcing the covariance requirement.
Is there some other minor change that would make the above work?
The f2, C1 & CF1 reperesent fixed third party library interfaces;
though C1 & CF1 could be covariant in T.
I am trying to package up the fr, FR & R components
and provide a cleaner interface to f2 via f1
and ultimately make the ay parameter implicit
(the reason for trying to package things together in the first place)
If I remove the covariance and look at the -explaintypes output
there is one line that puzzles me:
experimental/users/mahler/java/porn/Tests.scala:19: error: type mismatch;
found : ay.FR
required: ZZ.this.CF1[Y,AY#R]
= f2[Y, AY#R](y, ay.fr)
^
ay.FR < ZZ.this.CF1[Y,AY#R]?
ay.FR < Nothing?
<notype> < Nothing?
false
ZZ.this.CF1[Y,ay.R] < Nothing?
<notype> < Nothing?
false
Any < Nothing?
<notype> < Nothing?
false
false
false
false
ZZ.this.CF1[Y,ay.R] < ZZ.this.CF1[Y,AY#R]?
AY#R < ay.R?
*** Why does the ordering flip in the previous step?
AY < ay.type?
ZZ.this.A[Y] < ay.type?
false
false
AY#R < Nothing?
<notype> < Nothing?
false
ZZ.this.C1[Y] < Nothing?
<notype> < Nothing?
false
Any < Nothing?
<notype> < Nothing?
false
false
false
false
ZZ.this.C1[Y] < ay.R?
ZZ.this.C1[Y] < Nothing?
<notype> < Nothing?
false
Any < Nothing?
<notype> < Nothing?
false
false
false
Any < ay.R?
Any < Nothing?
<notype> < Nothing?
false
false
false
false
false
ZZ.this.CF1[Y,ay.R] < Nothing?
<notype> < Nothing?
false
Any < Nothing?
<notype> < Nothing?
false
false
false
Any < ZZ.this.CF1[Y,AY#R]?
Any < Nothing?
<notype> < Nothing?
false
false
false
false
false
[[syntax trees at end of typer]]// Scala source: Tests.scala
package <empty> {
final object Test extends java.lang.Object with ScalaObject {
def this(): object Test = {
Test.super.this();
()
};
abstract trait ZZ extends java.lang.Object with ScalaObject {
def /*ZZ*/$init$(): Unit = {
()
};
type C1[T >: Nothing <: Any]>: Nothing <: Any;
type CF1[T >: Nothing <: Any, CT >: Nothing <: ZZ.this.C1[T]]>: Nothing <: Any;
abstract trait A[T >: Nothing <: Any] extends scala.AnyRef {
type R>: Nothing <: ZZ.this.C1[T];
type FR>: Nothing <: ZZ.this.CF1[T,A.this.R];
def fr: A.this.FR
};
def f1[Y >: Nothing <: Any, AY >: Nothing <: ZZ.this.A[Y]](y: Y, ay: AY): AY#R = ZZ.this.f2[Y, AY#R](y, ay.<error: method fr>);
def f2[O >: Nothing <: Any, CO >: Nothing <: ZZ.this.C1[O]](f: O, fr: ZZ.this.CF1[O,CO]): CO
}
}
}
Thanks
Daniel
On Sun, Oct 11, 2009 at 11:58 PM, Daniel Mahler <dmahler@gmail.com> wrote:
I have found that I this code will compile if I make CF1 covariant in CT.
object Test {
trait ZZ {
type C1[T]
type CF1[T, +CT <: C1[T]]
trait A[T] {
type R <: C1[T]
type FR <: CF1[T, R]
def fr : FR
}
def f1[Y, AY <: A[Y]](y: Y, ay: AY) : AY#R
= f2[Y, AY#R](y, ay.fr)
def f2[O, CO <: C1[O]](f: O, fr : CF1[O, CO]) : CO
}
}
Unfortunately in my intended application CF1 is not covariant in CT
and I am havingtrouble figuring out what is forcing the covariance requirement.
Is there some other minor change that would make the above work?
The f2, C1 & CF1 reperesent fixed third party library interfaces;
though C1 & CF1 could be covariant in T.
I am trying to package up the fr, FR & R components
and provide a cleaner interface to f2 via f1
and ultimately make the ay parameter implicit
(the reason for trying to package things together in the first place)
If I remove the covariance and look at the -explaintypes output
there is one line that puzzles me:
experimental/users/mahler/java/porn/Tests.scala:19: error: type mismatch;
found : ay.FR
required: ZZ.this.CF1[Y,AY#R]
= f2[Y, AY#R](y, ay.fr)
^
ay.FR < ZZ.this.CF1[Y,AY#R]?
ay.FR < Nothing?
<notype> < Nothing?
false
ZZ.this.CF1[Y,ay.R] < Nothing?
<notype> < Nothing?
false
Any < Nothing?
<notype> < Nothing?
false
false
false
false
ZZ.this.CF1[Y,ay.R] < ZZ.this.CF1[Y,AY#R]?
AY#R < ay.R?
*** Why does the ordering flip in the previous step?
AY < ay.type?
ZZ.this.A[Y] < ay.type?
false
false
AY#R < Nothing?
<notype> < Nothing?
false
ZZ.this.C1[Y] < Nothing?
<notype> < Nothing?
false
Any < Nothing?
<notype> < Nothing?
false
false
false
false
ZZ.this.C1[Y] < ay.R?
ZZ.this.C1[Y] < Nothing?
<notype> < Nothing?
false
Any < Nothing?
<notype> < Nothing?
false
false
false
Any < ay.R?
Any < Nothing?
<notype> < Nothing?
false
false
false
false
false
ZZ.this.CF1[Y,ay.R] < Nothing?
<notype> < Nothing?
false
Any < Nothing?
<notype> < Nothing?
false
false
false
Any < ZZ.this.CF1[Y,AY#R]?
Any < Nothing?
<notype> < Nothing?
false
false
false
false
false
[[syntax trees at end of typer]]// Scala source: Tests.scala
package <empty> {
final object Test extends java.lang.Object with ScalaObject {
def this(): object Test = {
Test.super.this();
()
};
abstract trait ZZ extends java.lang.Object with ScalaObject {
def /*ZZ*/$init$(): Unit = {
()
};
type C1[T >: Nothing <: Any]>: Nothing <: Any;
type CF1[T >: Nothing <: Any, CT >: Nothing <: ZZ.this.C1[T]]>: Nothing <: Any;
abstract trait A[T >: Nothing <: Any] extends scala.AnyRef {
type R>: Nothing <: ZZ.this.C1[T];
type FR>: Nothing <: ZZ.this.CF1[T,A.this.R];
def fr: A.this.FR
};
def f1[Y >: Nothing <: Any, AY >: Nothing <: ZZ.this.A[Y]](y: Y, ay: AY): AY#R = ZZ.this.f2[Y, AY#R](y, ay.<error: method fr>);
def f2[O >: Nothing <: Any, CO >: Nothing <: ZZ.this.C1[O]](f: O, fr: ZZ.this.CF1[O,CO]): CO
}
}
}
Thanks
Daniel