Concerning the cyclic reference error: This has nothing to do with structural types, but happens for every F-bounded type refinement. To see that, just make Summable into a class instead of a type alias.
I have become more and more convinced that F-bounds are a pain in the neck (they also seriously mess up type inference and make subtype checking incomplete). Maybe we can eliminate them? I see only one way to do this: Replace F-bounds by higher-kinded types. Here's a sketch:
We now have:
def less[T <: Ordered[T]](x: T, y: T) = x < y
Instead of that we could maybe write:
def less[O[X = T] <: Ordered[X], T]
(x: O[T], y: O[T]) =
x < y
One thing that's tricky is that we should be able to complete the example as follows:
class Str extends Ordered[Str]
less[Str, Str](x, y)
That is the first parameter Str would need to match the signature
O[X] <: Ordered[X]
It doesn't of course, because it is not polymorphic. However, we have specified in the signature of `less' that the
O[X] <: Ordered[X]
relationship needs to hold only for X = T, and T is Str, so the types work out.
This is all very preliminary. It's driven by the motivation that using refinements instead of higher-kinded types we can eliminate the F-bound:
trait Ordered {
type Elem;
def < (x: Elem, y; Elem): Boolean
}
def less[T, O <: Ordered{ type Elem = T }]
(x: Ordered { type Elem = T },
y: Ordered { type Elem = T }) =
x < y
less[Str, Str](x, y)
Is this better than F-bounds? I am not sure yet. But it seems worth investigating. Another requirement for this is that we can do type inference for such higher-kinded types. Adriaan, do maybe you want to try you hand with this?
|