The reason why you can't define such a trait is that you are using covariant type parameters in a place where they are not allowed. The following traits compile fine in Scala 2.10:
trait Update1[-A, -B] {
def update(i: A, v: B) : Unit
}
trait MyFunction1[-A, +B] {
def apply(a:A): B
}
trait Mutable[-A, B] extends Update1[A,B] with MyFunction1[A,B]
Notice that in order to have a mutable trait you have to fix the B parameter, so it allows neither covariance nor contravariance. If you take a look at the mutable collections in the Scala API you can see that in fact this is how they are declared.
In addition, nothing prevents you to mix a trait in an object instead of in a class to make the compiler happy, if you know that class already implements the methods defined in the trait. For example, you can have the following:
class SingleStringCollection(v: String) extends MyFunction1[Int, String] {
private var someString: String = v
def apply(a: Int): String = someString
def update(i: Int, v: String): Unit = {
someString = v
}
override def toString = someString
}
val test1: Update1[Int, String] = new SingleStringCollection("hi") // this would fail
val test2: Update1[Int, String] = new SingleStringCollection("hi") with Update1[Int, String] // this would work
Or you could also use structural typing if you just want to require that your val or parameter implements a list of known methods:
type UpdatableStructuralType = {
def update(i: Int, v: String) : Unit
}
val test3: UpdatableStructuralType = new SingleStringCollection("hi") // this would work
test3(0) = "great" // And of course this would also work
So you have several alternatives if you want to accept parameters conforming to some trait or requiring some methods to be implemented.