Reputation: 345
What I need is, let say, I have a List trait, and Value trait, and special lists store special Value types. I tried this, but line.value doesn't exist, and the reason is, it looks like prepend's type parameter is not the actual SingleValue class, but it is still a template. But why? thanks
sealed trait Value
case class SingleValue(value: Int) extends Value
case class DoubleValue(value1: Int, value2: Int) extends Value
trait List1 {
def prepend[B <: Value](value: B): Int
}
case class SingleList1 extends List1 {
def prepend[SingleValue](line: SingleValue): Int = {
line.value
}
}
Upvotes: 0
Views: 55
Reputation: 40500
SingleValue
in def prepend[SingleValue](line: SingleValue)
is a type parameter, not a concrete type.
Like when you wrote def prepend[B <: Value](value: B): Int
, you used B
as a variable def prepend[SingleValue]
has exactly the same meaning (except that variable name is different, but that's immaterial).
It is not very clear from your question what exactly you are trying to do here ... but, if I am guessing correctly, you want to parametrize the class, not the method:
trait List1[B <: Value] {
def prepend(b: B): Int
}
class SingleList extends List1[SingleValue] {
def prepend(sv: SingleValue) = sv.value
}
Update So, if you want your List1
to be covariant, as you mentioned in the comment, that won't work: if it did, then SingleList
would be a subclass of List1[Value]
, and therefore prepend
would have to work with any Value
, not just SingleValue
, and it doesn't know how.
What you could do in that case, is define the specialized prepend
method "on the side" and associate it with List1
via an implicit conversion:
trait Lis1[+B <: Value]
object List1Ops {
implicit class SVL[T <: SingleValue](val l: List1[T]) extends AnyVal {
def prepend(v: T) = v.value
}
}
This let's you do both things like:
val svl = new List1[SingleValue]{}
println(svl.prepend(new SingleValue))
and
val l: List1[Value] = new List1[SingleValue]{} // still covariant
Is that what you are after?
Upvotes: 2