Search code examples
scalacontravariance

Making a Contravariant Object


I'm trying to create a class that's contravariant:

class ContraObj[-T] {
  var item: T = _                 // initialize `item` to "some" T value
  def replace(t: T) = (item = t) 
}

But the following compile-time error occurs:

[error] .../ContraObj.scala:4: contravariant type T occurs in covariant 
   position in type => T of method item
[error]   var item: T = _
[error]       ^

How can I resolve this error?


Solution

  • You need to think about what contravariance means. That is, what does it imply and what constraints will result because of it. Hence,

    trait Foo[-T]{
      def stuff(t: T): T
    }
    

    Now think about what this means in the following context:

    def action(that: Foo[Int]) = that.stuff(1)
    

    and if I pass it a Foo[Any]. Does this then mean that if I expect the following definition to hand me back an Int that it will suceed?

    def action(that: Foo[Int]): Int = that.stuff(1)
    

    It can't, can it? That's because what you've defined is a function and functions have as their signature Function[-T, +R] and you're trying to define it as Function[-T, -T].