Suppose I have two classes, Input
and Output
, which are designed to be connected to each other. Output
produces values of some type, and Input
consumes them.
class Input[T] {
var output: Option[Output[_ <: T]] = None
}
class Output[T] {
var input: Option[Input[_ >: T]] = None
}
It's okay if an Input
and Output
pair don't operate on the same kind of value as long as the Input
type parameter is a supertype of the Output
type parameter. Note that the type parameter in both classes is invariant; in the real versions it is used in both co- and contravariant positions.
I have a connect
method elsewhere which sets up a link between an Input
/Output
pair:
def connect[T](output: Output[T], input: Input[_ >: T]) = {
output.input = Some(input)
input.output = Some(output)
}
If I call this method as below, I get a type error:
val out = new Output[String]
val in = new Input[AnyRef]
connect(out, in)
The error is:
test.scala:17: error: type mismatch;
found : Output[String]
required: Output[AnyRef]
connect(out, in)
^
I can resolve this by writing out the type parameter (in this case, I would write connect[String]
, but I think the compiler should be able to figure this out for me. How can I change the connect
method so that the type parameter is inferred automatically?
Edit: For now, I've made connect
a method of Output
so it gets the type parameter automatically. This also has the added benefit that I can use the infix notation out connect in
, but the design feels a little awkward.
I am still interested in why the compiler exhibits this behavior. I feel like it should be able to infer the type parameter. Is this actually working as specified?