Given the code below the method foo should compare operator-wise a given parameter bar with the lowerBound and upperBound all being of the same abstract type Bar.
trait Foo {
type Bar <: Ordered[Bar]
val lowerBound: Bar
val upperBound: Bar
def foo(bar: Bar) = bar >= lowerBound && bar <= upperBound
}
This way the trait Foo can be defined. The problems start with the below concrete class FooImpl.
class FooImpl extends Foo {
type Bar = Int
val lowerBound = 0
val upperBound = 5
}
I understand that scala.Int isn’t implementing what scala.runtime.RichInt does, effectively scala.math.Ordered[Int]. Defining type Bar as RichInt instead neither works as it does not conform to scala.math.Ordered[RichInt]. My third attempt to define type Bar as Ordered[Ord] where Ord is declared as type Ord and defining it in FooImpl as Int also did not work.
How would a possibly close solution look like?
There may be a more elegant solution, but you can achieve this by moving the restriction on the type to the method, rather than the type declaration:
Then your
FooImplworks as you have it:From the REPL:
The disadvantage here is that the trait can be extended with unordered types (although
foocan’t be called in that case):Alternatively, you can keep the requirement at the class level (and therefore stop anyone creating a
BrokenFoo) as follows, butFooImplhas to change slightly:This problem feels like view or context bounds should be applicable, but unfortunately it doesn’t seem like you can use them either in
typedeclarations or in generic type parameters on traits.