The first error covariant type A occurs in contravariant position in type A of value param
means that if a generic type Foo
declares itself to be covariant over T
(i.e. Foo[+T]
), it means that its methods can only return T
and not require it. Otherwise type consistency will be violated. For instance you could pass in an instance of Sample[Dog]
where Sample[Animal]
is required, and then something could call doit(new Duck)
on it, even though Sample[Dog]#doit
can only handle instances of Dog
. However, return values behave the exact opposite way in this context (I'll let you figure out why).
However this
def doit[Int](param: Int)
means doit
has a type parameter called Int
, which has nothing to do with the Int
type (although it sure does seem like it does at first impression, which is why you should never use type parameter names that coincide with the names of other/built-in types). So the error you're getting is because Int
in that context means "any type", and using +
on any type will fall back to string concatenation as opposed to arithmetic addition.
instead you need (to correctly inherit from Sample[+A]
):
def doit[B >: Int](param: B)
however, that will still not allow you to do addition on param
because param
is now any supertype of Int
, not Int
itself or a subtype thereof.
So I do not see how you can "fix" this—the way variance works fundamentally simply doesn't allow for generic types to be covariant over method parameters. This has nothing to do with Scala really. But see e.g. http://blogs.atlassian.com/2013/01/covariance-and-contravariance-in-scala/ or http://docs.scala-lang.org/tutorials/tour/variances.html for more information on how variance works and why it has to work exactly like it does (in any language implementing correct variance rules).
I think a better way in general to get a really helpful answer on Stackoverflow is to also describe what you really need to achieve, not just the implementation you've been working on so far.